stimfit-0.16.7/0000775000175000017500000000000014764352500007035 5stimfit-0.16.7/README0000664000175000017500000000000014750345043007622 stimfit-0.16.7/setup.py.in0000664000175000017500000002073614750344764011114 import distutils from distutils.core import setup, Extension import sys import os import subprocess import shlex from numpy.distutils import system_info import numpy as np numpy_config_keys = [ 'atlas_blas_info', 'atlas_blas_threads_info', 'atlas_info', 'atlas_threads_info', 'blas_mkl_info', 'blas_opt_info', 'get_info', 'lapack_mkl_info', 'lapack_opt_info', 'mkl_info', 'openblas_info', 'openblas_lapack_info' ] np_define_macros = [] np_extra_compile_args = [] np_extra_link_args = [] np_libraries = [] if not 'linux' in sys.platform: for key in numpy_config_keys: try: np_libraries += np.__config__.get_info(key)['libraries'] except: pass try: np_define_macros += np.__config__.get_info(key)['define_macros'] except: pass try: np_extra_compile_args += np.__config__.get_info(key)[ 'extra_compile_args'] except: pass try: np_extra_link_args += np.__config__.get_info(key)['extra_link_args'] except: pass hdf5_extra_compile_args = [] hdf5_extra_link_args = [] if 'linux' in sys.platform: cmd = shlex.split('pkg-config --cflags hdf5') p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.wait() pkg_config_out = p.stdout.read().decode("utf-8")[:-1] pkg_config_err = p.stderr.read().decode("utf-8")[:-1] if "No package" in pkg_config_err: hdf5_extra_compile_args = ["-I/usr/include/hdf5/serial"] else: hdf5_extra_compile_args = [pkg_config_out] cmd = shlex.split('pkg-config --libs hdf5') p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.wait() pkg_config_out = p.stdout.read().decode("utf-8")[:-1] pkg_config_err = p.stderr.read().decode("utf-8")[:-1] if "No package" in pkg_config_err: hdf5_extra_link_args = [ "-L/usr/lib/x86_64-linux-gnu/", "-L/usr/lib/x86_64-linux-gnu/hdf5/serial"] else: hdf5_extra_link_args = [pkg_config_out] if os.name == "nt": biosig_define_macros = [('WITH_BIOSIG2', None)] biosig_libraries = ['libbiosig2'] biosig_lite_sources = [] else: biosig_define_macros = [('WITH_BIOSIG2', None), ('WITH_BIOSIGLITE', None), ('WITHOUT_NETWORK', None)] biosig_libraries = ['iconv'] biosig_lite_sources = [ 'src/libbiosiglite/../biosig/biosig4c++/t210/sopen_abf_read.c', 'src/libbiosiglite/../biosig/biosig4c++/t210/sopen_alpha_read.c', 'src/libbiosiglite/../biosig/biosig4c++/t210/sopen_axg_read.c', 'src/libbiosiglite/../biosig/biosig4c++/t210/sopen_cfs_read.c', 'src/libbiosiglite/../biosig/biosig4c++/t210/sopen_heka_read.c', 'src/libbiosiglite/../biosig/biosig4c++/t210/sopen_igor.c', 'src/libbiosiglite/../biosig/biosig4c++/t210/sopen_scp_read.c', 'src/libbiosiglite/../biosig/biosig4c++/t210/scp-decode.cpp', 'src/libbiosiglite/../biosig/biosig4c++/t220/crc4scp.c', 'src/libbiosiglite/../biosig/biosig4c++/t220/sopen_scp_write.c', 'src/libbiosiglite/../biosig/biosig4c++/test0/sandbox.c', 'src/libbiosiglite/../biosig/biosig4c++/biosig.c', 'src/libbiosiglite/../biosig/biosig4c++/biosig2.c', 'src/libbiosiglite/../biosig/biosig4c++/biosig-network.c', 'src/libbiosiglite/../biosig/biosig4c++/gdftime.c', 'src/libbiosiglite/../biosig/biosig4c++/mdc_ecg_codes.c', 'src/libbiosiglite/../biosig/biosig4c++/physicalunits.c' ] fftw3_libraries = ['fftw3'] if 'libraries' in system_info.get_info('fftw3').keys(): fftw3_libraries = system_info.get_info('fftw3')['libraries'] if os.name == "nt": win_define_macros = [("_WINDOWS", None), ("__STF__", None), ("STFIODLL", None), ("_WIN64", None), ("_WINDLL", None), ("H5_USE_16_API", None), ("_HDF5USEDLL_", None), ("_CRT_SECURE_NO_WARNINGS", None), ("UNICODE", None), ("_UNICODE", None)] win_compile_args = ["/EHsc"] home_dir = os.path.expanduser("~") win_include_dirs = [ os.path.join(home_dir, 'boost'), os.path.join(home_dir, 'biosig', 'include'), os.path.join(home_dir, 'hdf5', 'include'), os.path.join(home_dir, 'fftw'), ] win_library_dirs = [ os.path.join(home_dir, 'hdf5', 'lib'), os.path.join(home_dir, 'biosig', 'lib'), os.path.join(home_dir, 'stimfit', 'dist', 'windows', 'libs'), os.path.join(home_dir, 'fftw'), ] fftw3_libraries = ['libfftw3-3'] np_libraries = ['BLAS', 'clapack', 'libf2c'] win_libraries = ['user32'] win_link_args = ["/SUBSYSTEM:WINDOWS", "/LARGEADDRESSAWARE", "/OPT:REF", "/OPT:ICF", "/DYNAMICBASE", "/NXCOMPAT", "/MACHINE:X64", "/NODEFAULTLIB:\"libc.lib\"", "/NODEFAULTLIB:\"libcmt.lib\""] win_data_files = [( distutils.sysconfig.get_python_lib(), [ os.path.join(home_dir, 'biosig', 'lib', 'libbiosig2.dll'), os.path.join(home_dir, 'fftw', 'libfftw3-3.dll'), ] )] else: win_define_macros = [] win_include_dirs = [] win_compile_args = [] win_library_dirs = [] win_libraries = [] win_link_args = [] win_data_files = [] stfio_module = Extension( '_stfio', swig_opts=['-c++'], library_dirs=win_library_dirs, libraries=['hdf5', 'hdf5_hl'] + fftw3_libraries + np_libraries + biosig_libraries + win_libraries, define_macros=np_define_macros + biosig_define_macros + win_define_macros, extra_compile_args=np_extra_compile_args + hdf5_extra_compile_args + win_compile_args, extra_link_args=np_extra_link_args + hdf5_extra_link_args + win_link_args, include_dirs=win_include_dirs, sources=[ 'src/libstfio/abf/abflib.cpp', 'src/libstfio/abf/axon/AxAbfFio32/Oldheadr.cpp', 'src/libstfio/abf/axon/AxAbfFio32/abferror.cpp', 'src/libstfio/abf/axon/AxAbfFio32/abffiles.cpp', 'src/libstfio/abf/axon/AxAbfFio32/abfheadr.cpp', 'src/libstfio/abf/axon/AxAbfFio32/abfhwave.cpp', 'src/libstfio/abf/axon/AxAbfFio32/abfutil.cpp', 'src/libstfio/abf/axon/AxAbfFio32/csynch.cpp', 'src/libstfio/abf/axon/AxAbfFio32/filedesc.cpp', 'src/libstfio/abf/axon/AxAbfFio32/msbincvt.cpp', 'src/libstfio/abf/axon/AxAtfFio32/axatffio32.cpp', 'src/libstfio/abf/axon/AxAtfFio32/fileio2.cpp', 'src/libstfio/abf/axon/Common/FileIO.cpp', 'src/libstfio/abf/axon/Common/FileReadCache.cpp', 'src/libstfio/abf/axon/Common/unix.cpp', 'src/libstfio/abf/axon2/ProtocolReaderABF2.cpp', 'src/libstfio/abf/axon2/SimpleStringCache.cpp', 'src/libstfio/abf/axon2/abf2headr.cpp', 'src/libstfio/atf/atflib.cpp', 'src/libstfio/axg/AxoGraph_ReadWrite.cpp', 'src/libstfio/axg/axglib.cpp', 'src/libstfio/axg/byteswap.cpp', 'src/libstfio/axg/fileUtils.cpp', 'src/libstfio/axg/stringUtils.cpp', 'src/libstfio/biosig/biosiglib.cpp', 'src/libstfio/cfs/cfs.c', 'src/libstfio/cfs/cfslib.cpp', 'src/libstfio/channel.cpp', 'src/libstfio/hdf5/hdf5lib.cpp', 'src/libstfio/igor/CrossPlatformFileIO.c', 'src/libstfio/igor/WriteWave.c', 'src/libstfio/igor/igorlib.cpp', 'src/libstfio/intan/common.cpp', 'src/libstfio/intan/intanlib.cpp', 'src/libstfio/intan/streams.cpp', 'src/libstfio/recording.cpp', 'src/libstfio/section.cpp', 'src/libstfio/stfio.cpp', 'src/libstfnum/fit.cpp', 'src/libstfnum/funclib.cpp', 'src/libstfnum/levmar/Axb.c', 'src/libstfnum/levmar/lm.c', 'src/libstfnum/levmar/lmbc.c', 'src/libstfnum/levmar/misc.c', 'src/libstfnum/measure.cpp', 'src/libstfnum/stfnum.cpp', 'src/pystfio/pystfio.cxx', 'src/pystfio/pystfio.i', ] + biosig_lite_sources) setup(name='stfio', version='@PACKAGE_VERSION@', description='stfio module', include_dirs=system_info.default_include_dirs + [ np.get_include()], scripts=[], package_dir={'stfio': 'src/pystfio'}, packages=['stfio'], data_files=win_data_files, ext_modules=[stfio_module]) stimfit-0.16.7/Makefile.static.in0000664000175000017500000002074414755262551012325 ######################################################################## # Makefile for static compilation Stimfit # no automake, or libtool, are needed. # # No global installation (sudo make install) is needed, but # stimfit can be started immediately after compilation. # # This is most useful for debugging, when several instances of stimfit # should be available. # # Usage: # cd ~/src/stimfit/ # change into stimfit's root directory # ./autogen.sh # ./configure --with-biosig --disable-python --with-pslope # make -f Makefile.static # build stimfit(-lite) i.e. w/o python support # make -f Makefile.static install # install stimfit into bindir # # WXCONF=/usr/bin/wx-config make -f Makefile.static # # build built with non-default WX # # PREFIX=/usr/local make -f Makefile.static # # ./stimfit # start stimfit # # win32 built # CROSS=i686-pc-mingw32- make -f Makefile.static # WXCONF=i686-pc-mingw32-wx-config make -f Makefile.static # win64 built # CROSS=x86_64-static-mingw32- make -f Makefile.static # WXCONF=x86_64-static-mingw32-wx-config make -f Makefile.static # # The use of WXCONF is deprecated, and might be removed in future # Limitations: # - PYTHON shell, matplotlib (print) are not supported # # Copyright (C) 2012,2013,2014,2015,2021,2025 Alois Schloegl # This is part of the stimfit project http://stimfit.org # ######################################################################## ifeq (,$(WXCONF)) # default wx-config WXCONF = $(CROSS)wx-config else ifneq (,$(findstring mingw,$(WXCONF))) # for backwords compatibility to older MXE scripts CROSS = $(subst wx-config,,$(WXCONF)) endif endif DEFINES += -DWITH_BIOSIG DEFINES += -DWITH_PSLOPE #DEFINES += -DTEST_MINIMAL #DEFINES += -DPYTHON -DWITH_PYTHON WXVERSION = $(basename $(shell $(WXCONF) --version)) PY_VERSION := $(shell py3versions -i | sed 's/python//g') ############################################################## ### SOURCES ############################################################## vpath %.cpp ./src/stimfit:./src/stimfit/gui:./src/stimfit/gui/dlgs:./src/stimfit/gui/usrdlg:./src/libstfnum:./src/libstfio/:./src/libstfio/cfs/:./src/libstfio/atf/:./src/libstfio/abf/:./src/libstfio/abf/axon2:./src/libstfio/abf/axon/Common:./src/libstfio/abf/axon/AxAbfFio32:./src/libstfio/abf/axon/AxAtfFio32/:./src/libstfio/biosig/:./src/libstfio/hdf5/:./src/libstfio/heka/:./src/libstfio/igor:./src/libstfio/ascii/:./src/libstfio/axg/ vpath %.c ./src/libstfnum/levmar/:./src/libstfio/igor/:./src/libstfio/cfs/ vpath %.cpp ./src/libstfnum/:./src/libstfnum/levmar/:./src/stimfit/gui/:./src/stimfit/gui/dlgs/:./src/libstfio/:./src/libstfio/biosig/:./src/libstfio/igor/:./src/libstfio/cfs/ SOURCES = ./src/stimfit/stf.cpp \ ./src/libstfnum/stfnum.cpp \ ./src/libstfnum/funclib.cpp \ ./src/libstfnum/measure.cpp \ ./src/libstfnum/fit.cpp \ ./src/libstfnum/levmar/lm.c \ ./src/libstfnum/levmar/Axb.c \ ./src/libstfnum/levmar/misc.c \ ./src/libstfnum/levmar/lmbc.c \ ./src/libstfnum/levmar/lmlec.c \ ./src/stimfit/gui/doc.cpp \ ./src/stimfit/gui/zoom.cpp \ ./src/stimfit/gui/childframe.cpp \ ./src/stimfit/gui/app.cpp \ ./src/stimfit/gui/parentframe.cpp \ ./src/stimfit/gui/dlgs/convertdlg.cpp \ ./src/stimfit/gui/dlgs/cursorsdlg.cpp \ ./src/stimfit/gui/dlgs/eventdlg.cpp \ ./src/stimfit/gui/dlgs/smalldlgs.cpp \ ./src/stimfit/gui/dlgs/fitseldlg.cpp \ ./src/stimfit/gui/copygrid.cpp \ ./src/stimfit/gui/usrdlg/usrdlg.cpp \ ./src/stimfit/gui/graph.cpp \ ./src/stimfit/gui/unopt.cpp \ ./src/stimfit/gui/view.cpp \ ./src/stimfit/gui/table.cpp \ ./src/stimfit/gui/printout.cpp \ ./src/stimfit/gui/main.cpp \ ./src/libstfio/igor/igorlib.cpp \ ./src/libstfio/cfs/cfslib.cpp \ ./src/libstfio/section.cpp \ ./src/libstfio/recording.cpp \ ./src/libstfio/hdf5/hdf5lib.cpp \ ./src/libstfio/intan/intanlib.cpp \ ./src/libstfio/intan/common.cpp \ ./src/libstfio/intan/streams.cpp \ ./src/libstfio/channel.cpp \ ./src/libstfio/stfio.cpp \ ./src/libstfio/igor/WriteWave.c \ ./src/libstfio/igor/CrossPlatformFileIO.c \ ./src/libstfio/biosig/biosiglib.cpp \ ./src/libstfio/cfs/cfs.c SOURCES_OPTIONAL = \ ./src/libstfio/heka/hekalib.cpp \ SOURCES_ABF = ./src/libstfio/atf/atflib.cpp \ ./src/libstfio/abf/abflib.cpp \ ./src/libstfio/abf/axon2/ProtocolReaderABF2.cpp \ ./src/libstfio/abf/axon2/abf2headr.cpp \ ./src/libstfio/abf/axon2/SimpleStringCache.cpp \ ./src/libstfio/abf/axon/Common/FileReadCache.cpp \ ./src/libstfio/abf/axon/Common/unix.cpp \ ./src/libstfio/abf/axon/Common/FileIO.cpp \ ./src/libstfio/abf/axon/AxAtfFio32/axatffio32.cpp \ ./src/libstfio/abf/axon/AxAtfFio32/fileio2.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abferror.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfheadr.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/filedesc.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/msbincvt.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfutil.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abffiles.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/Oldheadr.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfhwave.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/csynch.cpp EXCLUDED = ./src/libstfio/ascii/asciilib.cpp \ ./src/libstfio/abf/axon/AxAtfFio32/fileio2.cpp \ ./src/libstfnum/levmar/lmbc_core.c \ ./src/libstfnum/levmar/lmlec_core.c \ ./src/libstfnum/levmar/misc_core.c \ ./src/libstfnum/levmar/lm_core.c \ ./src/libstfnum/levmar/Axb_core.c \ ./src/stimfit/gui/dclatex.cpp \ TESTSRC = ./src/test/section.cpp \ ./src/test/recording.cpp \ ./src/test/measure.cpp \ ./src/test/channel.cpp \ ./src/test/gtest/src/gtest.cc \ ./src/test/gtest/src/gtest-port.cc \ ./src/test/gtest/src/gtest-test-part.cc \ ./src/test/gtest/src/gtest-typed-test.cc \ ./src/test/gtest/src/gtest.cc \ ./src/test/gtest/src/gtest-printers.cc \ ./src/test/gtest/src/gtest-death-test.cc \ ./src/test/gtest/src/gtest-all.cc \ ./src/test/gtest/src/gtest_main.cc \ ./src/test/gtest/src/gtest-filepath.cc SOURCES_AXG = ./src/libstfio/axg/axglib.cpp \ ./src/libstfio/axg/AxoGraph_ReadWrite.cpp \ ./src/libstfio/axg/fileUtils.cpp \ ./src/libstfio/axg/stringUtils.cpp \ ./src/libstfio/axg/byteswap.cpp \ # needed because of exportATF SOURCES += $(SOURCES_ABF) SOURCES += $(SOURCES_AXG) ifeq (,$(findstring mingw, $(WXCONF))) TARGET = stimfit OBJEXT = o else ### MINGW ### TARGET = stimfit.exe OBJEXT = obj endif ifeq (,$(findstring TEST_MINIMAL, $(DEFINES))) SOURCES += $(SOURCES_OPTIONAL) endif ifneq (,$(findstring WITH_PYTHON, $(DEFINES))) SOURCES += $(SOURCES_PYSTFIO) CFLAGS += $(shell python$(PY_VERSION)-config --cflags) DEFINES += -I$(shell python$(PY_VERSION)-config --prefix)/lib/pymodules/python$(PY_VERSION)/numpy/core/include LDFLAGS += $(shell python$(PY_VERSION)-config --ldflags) LIBS += $(shell python$(PY_VERSION)-config --libs) endif CC ?= $(shell $(WXCONF) --cc) CXX ?= $(shell $(WXCONF) --cxx) LD = $(shell $(WXCONF) --ld) CFLAGS += $(DEFINES) $(shell $(WXCONF) --cflags) -fstack-protector -O2 -I./ CPPFLAGS += $(DEFINES) $(shell $(WXCONF) --cppflags) -std=c++17 -fstack-protector -O2 -I./ LIBS += $(shell $(WXCONF) --libs net,adv,aui,core,base) SWIG = @SWIG@ SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ prefix ?= $(PREFIX) exec_prefix = ${prefix} datarootdir = ${prefix}/share datadir = ${datarootdir} libdir = ${exec_prefix}/lib includedir = ${prefix}/include bindir = ${exec_prefix}/bin mandir = ${datarootdir}/man PKGCONF ?= $(CROSS)pkg-config HDF5_CFLAGS = @HDF5_CFLAGS@ CPPFLAGS += $(HDF5_CFLAGS) LIBHDF5_LDFLAGS = @LIBHDF5_LDFLAGS@ LIBS += $(LIBHDF5_LDFLAGS) LIBLAPACK_LDFLAGS = @LIBLAPACK_LDFLAGS@ LIBS += $(LIBLAPACK_LDFLAGS) CXXFLAGS += $(CFLAGS) $(CPPFLAGS) ## BIOSIG related stuff ## LIBS += $(shell $(PKGCONF) --libs libbiosig) LIBS += -lfftw3 ifeq (mingw,$(findstring mingw, $(WXCONF))) LIBS += -lgfortran -lquadmath endif PYTHON_DEST_DIR = ${prefix}${PYTHON_TARGET_DIR} ############################################################## ### BUILT ############################################################## OBJECTS = $(addsuffix .$(OBJEXT), $(basename $(SOURCES))) $(TARGET): $(OBJECTS) $(LD) "$@" $(OBJECTS) $(LDFLAGS) $(LIBS) %.c: %.h %.cpp: %.h %.$(OBJEXT): %.c $(CC) -o "$@" $(CFLAGS) -c "$<" %.$(OBJEXT): %.cc $(CC) -o "$@" $(CFLAGS) -c "$<" %.$(OBJEXT): %.cpp $(CXX) -o "$@" $(CPPFLAGS) -c "$<" %.$(OBJEXT): %.cxx $(CXX) -o "$@" $(CXXFLAGS) -c "$<" clean: find src -name "*.$(OBJEXT)" -exec rm {} \; rm -f stimfit install: $(TARGET) install $(TARGET) $(bindir) uninstall: rm $(bindir)/stimfit stimfit-0.16.7/missing0000755000175000017500000001533614764352410010362 #! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: stimfit-0.16.7/install-sh0000755000175000017500000003577614764352410011001 #!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: stimfit-0.16.7/stfconf.h.in0000664000175000017500000000333514764352410011201 /* stfconf.h.in. Generated from configure.ac by autoheader. */ /* 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_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_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 where 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 all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION stimfit-0.16.7/configure0000775000175000017500000242223714764352407010706 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for stimfit 0.16.7. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 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="as_nop=: if test \${ZSH_VERSION+y} && (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 \$as_nop 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 \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || 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 -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 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi 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'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$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_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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=`printf "%s\n" "$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 || printf "%s\n" 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_nop 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_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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 || printf "%s\n" 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" || { printf "%s\n" "$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 } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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='stimfit' PACKAGE_TARNAME='stimfit' PACKAGE_VERSION='0.16.7' PACKAGE_STRING='stimfit 0.16.7' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/stimfit/gui/main.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS GT_LDFLAGS GT_LIBS GT_CXXFLAGS GT_CPPFLAGS OPT_CXXFLAGS LIBHDF5_LDFLAGS HDF5_LIBS HDF5_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG MACSETFILE POSTLINK_COMMAND SETFILE REZ WX_CXXFLAGS WX_CPPFLAGS WX_LIBS LIBLAPACK_LDFLAGS LIBBIOSIG_LDFLAGS WITH_BIOSIGLITE_FALSE WITH_BIOSIGLITE_TRUE WITH_BIOSIG_FALSE WITH_BIOSIG_TRUE STFIO_PYTHON_LIBNAME STF_PYTHON_LIBNAME LIBSTF_LDFLAGS LIBWXPYTHON_INCLUDES LIBNUMPY_INCLUDES LIBPYTHON_INCLUDES LIBPYTHON_LDFLAGS SWIG_PYTHON_CPPFLAGS SWIG_PYTHON_OPT SWIG_LIB SWIG PYTHON_EXTRA_LDFLAGS PYTHON_EXTRA_LIBS PYTHON_WXPYTHON_INCLUDE PYTHON_NUMPY_INCLUDE PYTHON_DIST_PKG PYTHON_PRE_DIST_PKG PYTHON_SITE_PKG PY_AC_VERSION PYTHON_LDFLAGS PYTHON_CPPFLAGS PYTHON PYTHON_VERSION BUILD_PYTHON_FALSE BUILD_PYTHON_TRUE ISDARWIN_FALSE ISDARWIN_TRUE BUILD_DEBIAN_FALSE BUILD_DEBIAN_TRUE BUILD_MODULE_FALSE BUILD_MODULE_TRUE CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX CPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP FILECMD LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V CSCOPE ETAGS CTAGS 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_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir 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 am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock enable_module enable_debian enable_python enable_ipython with_pslope with_biosig with_biosiglite with_lapack_lib enable_aui with_wx_config with_hdf5_prefix enable_debug ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH CPP CXX CXXFLAGS CCC CXXCPP PYTHON_VERSION PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR HDF5_CFLAGS HDF5_LIBS' # 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' runstatedir='${localstatedir}/run' 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 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=`printf "%s\n" "$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=`printf "%s\n" "$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 ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -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=`printf "%s\n" "$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=`printf "%s\n" "$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. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$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" ;; *) printf "%s\n" "$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 runstatedir 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 || printf "%s\n" 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 stimfit 0.16.7 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] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --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/stimfit] --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] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of stimfit 0.16.7:";; 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-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --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-module build a standalone python module; implies --enable-python --enable-debian special build for pbuilder --enable-python enable python console (default="yes") --enable-ipython enable ipython as the default shell (experimental); implies --enable-python --enable-aui enable AUI for the doc/view architecture (experimental) --enable-debug build stimfit in debug mode Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-pslope include slope measure cursors --without-biosig disable support for biosig --with-biosiglite use builtin biosig library --with-lapack-lib=LAPACKLIB Provide full path to custom lapack library --with-wx-config=FILE Use the given path to wx-config when determining wxWidgets configuration; defaults to "wx-config" --with-hdf5-prefix=HDF5_PREFIX Provide full path to hdf5 prefix 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 LT_SYS_LIBRARY_PATH User-defined run-time library search path. CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor PYTHON_VERSION The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name. PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path HDF5_CFLAGS C compiler flags for HDF5, overriding pkg-config HDF5_LIBS linker flags for HDF5, overriding pkg-config 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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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 configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. 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 printf "%s\n" "$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 stimfit configure 0.16.7 generated by GNU Autoconf 2.71 Copyright (C) 2021 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 conftest.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop 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 $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop 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. */ #include #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 (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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 conftest.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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_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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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.beam 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\"" printf "%s\n" "$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 printf "%s\n" "$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_nop printf "%s\n" "$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 ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac 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 stimfit $as_me 0.16.7, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "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=`printf "%s\n" "$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=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## 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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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 printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$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 printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*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 do not provoke an error unfortunately, instead are silently treated as an "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 is necessary to write \x00 == 0 to get something that is 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 **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " # Auxiliary files required by this configure script. ac_aux_files="config.guess config.sub ltmain.sh compile missing install-sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$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. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" 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,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-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 am__api_version='1.16' # 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. 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+y}; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$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' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "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=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 ('*'coreutils) '* | \ 'BusyBox '* | \ '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+y}; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} 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} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$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='stimfit' VERSION='0.16.7' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # 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 -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope 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 # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$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='\' 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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}clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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="clang" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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. printf "%s\n" "$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 -version; 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\"" printf "%s\n" "$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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$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+y} && 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 $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$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 (void) { 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$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 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$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_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; 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 ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _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 conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 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 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$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 DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} 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 depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$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 enable_dlopen=yes case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$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 # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "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*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$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+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "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 yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop 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 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$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 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=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_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 # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) 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 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop 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; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # 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 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; 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" && \ test undefined != "$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`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$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 cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; 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}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$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 FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_FILECMD="file" printf "%s\n" "$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_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop 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 # that 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='$FILECMD -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. if ( 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 # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' 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* | midnightbsd*) 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=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD 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 glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) 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=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; 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 ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi 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 if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$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 DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_DLLTOOL="dlltool" printf "%s\n" "$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_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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$ac_prog" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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="$ac_prog" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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=: # 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 bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # 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 ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; 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 if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # 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"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$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"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/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, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,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 lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # 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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && 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 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #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. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$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_globsym_save_LIBS=$LIBS lt_globsym_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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_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 yes = "$pipe_works"; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || 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 what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. 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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD 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* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. 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=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop 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 cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) 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 if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$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 MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_MANIFEST_TOOL="mt" printf "%s\n" "$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_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop 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 there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop 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 $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 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 -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $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*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; 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 no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi 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 : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi # Set options enable_win32_dll=no # Check whether --enable-shared was given. if test ${enable_shared+y} 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 $as_nop enable_shared=yes fi # Check whether --enable-static was given. if test ${enable_static+y} 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 $as_nop enable_static=yes fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} 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 $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h 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 set != "${COLLECT_NAMES+set}"; 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 and # ICC, which need '.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 func_cc_basename $compiler cc_basename=$func_cc_basename_result # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop 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" ## exclude from sc_useless_quotes_in_assignment # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; 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= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; 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' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; 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 ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; 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 ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; 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' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; 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 | 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' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' 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' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' 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\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # 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\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; 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* | sunf77* | sunf90* | sunf95*) 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 that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop 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" ## exclude from sc_useless_quotes_in_assignment # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; 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\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "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_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++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=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 yes = "$with_gnu_ld"; 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 yes = "$lt_use_gnu_ld_interface"; 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 | $SED -e 's/([^)]\+)\s\+//' 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 ia64 != "$host_cpu"; 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/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' 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, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; 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 ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; 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) tmp_diet=no if test linux-dietlibc = "$host_os"; 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 no = "$tmp_diet" 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' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-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 yes = "$supports_anon_versioning"; 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 tcc*) hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; 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='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; 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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) 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 $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $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 $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $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 cannot *** 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 $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $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 no = "$ld_shlibs"; 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 yes = "$GCC" && 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 ia64 = "$host_cpu"; 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 GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. 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) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | 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 # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; 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,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; 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 yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; 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 yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' 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,yes = "$with_aix_soname,$aix_use_runtimelinking"; 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 set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_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 "$lt_cv_aix_libpath_"; then lt_cv_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.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ 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 -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; 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 set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_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 "$lt_cv_aix_libpath_"; then lt_cv_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.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ 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 yes = "$with_gnu_ld"; 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 archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' 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++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # 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 $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper 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' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; 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*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_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 \$rpath/\$soname \$verstring $_lt_dar_single_mod$_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* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$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 "x$output_objdir/$soname" = "x$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 yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $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 no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$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 yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $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 -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) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; 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 no = "$with_gnu_ld"; 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 yes = "$GCC"; then archive_cmds='$CC -shared $pic_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' # 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. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_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 $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no 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 ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) 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* | bitrig*) 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__`"; 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 archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; 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 yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_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 yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $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 $pic_flag $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 yes = "$GCC"; 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 sequent = "$host_vendor"; 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 yes = "$GCC"; 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 CANNOT 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 yes = "$GCC"; 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 sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && 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 yes,yes = "$GCC,$enable_shared"; 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $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=$? printf "%s\n" "$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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; 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` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac 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" elif test -n "$lt_multi_os_dir"; then 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 # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; 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 # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # 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' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # 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' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac 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%'\''`; $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 # correct to gnu/linux during the next big refactor 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,$cc_basename in yes,*) # gcc 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 dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # 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' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # 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 # correct to gnu/linux during the next big refactor 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* | midnightbsd*) # 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$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' 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 # correct to gnu/linux during the next big refactor 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=no 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 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; 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 # correct to gnu/linux during the next big refactor 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 yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor 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 ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # 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 dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor 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 test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop 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\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam \ 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 # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) 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' ;; netbsdelf*-gnu) 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=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_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 # correct to gnu/linux during the next big refactor 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* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi 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 shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 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' ;; 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 # correct to gnu/linux during the next big refactor 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 yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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=sco 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 yes = "$with_gnu_ld"; 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 # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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 ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # 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 no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$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_nop lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) 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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $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. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$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 $as_nop 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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $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. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$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_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $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. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$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 no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; 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 $LINENO "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 -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; 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 $LINENO "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 -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$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= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && 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 yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$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 ac_config_commands="$ac_config_commands libtool" # Only expand once: 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "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 test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" 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. # 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. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$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. # 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. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" 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 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 clang++ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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 clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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" printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "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:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$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. printf "%s\n" "$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\"" printf "%s\n" "$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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop 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 (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; 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_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 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= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CXX_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 printf "%s\n" "$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 func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /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. # 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. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 printf "%s\n" "$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. # 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. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # 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 $as_nop # 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_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$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_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 yes != "$_lt_caught_CXX_error"; 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_CFLAGS=$CFLAGS 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++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "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 yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop 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 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$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 yes = "$with_gnu_ld"; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "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 ia64 = "$host_cpu"; 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 # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive 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 if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; 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,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; 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 yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; 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 yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' 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,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`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.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX 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 -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; 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 set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`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 "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`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.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX 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 yes = "$with_gnu_ld"; 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 archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' 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*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # 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_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _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, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; 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 ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; 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*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_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 \$rpath/\$soname \$verstring $_lt_dar_single_mod$_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 yes != "$lt_cv_apple_cc_single_mod"; then 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 \$rpath/\$soname \$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 ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes file_list_spec_CXX='@' ;; 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* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; 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 "x$output_objdir/$soname" = "x$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 yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; 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 -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 yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $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 yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -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 $pic_flag -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 | 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 yes = "$supports_anon_versioning"; 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 ;; openbsd* | bitrig*) 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__`"; 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 yes,no = "$GXX,$with_gnu_ld"; 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 $pic_flag -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* | sunCC*) # 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 yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $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 $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -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 $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 $wl-h $wl$soname -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 CANNOT 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*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && 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 _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$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 $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev 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 prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$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 no = "$pre_test_object_deps_done"; 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 CFLAGS=$_lt_libdeps_save_CFLAGS # 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= ;; 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= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; 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 ia64 = "$host_cpu"; 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' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; 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 ia64 = "$host_cpu"; 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 ;; 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). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; 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* | midnightbsd*) # 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 ia64 != "$host_cpu"; 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 | 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* | netbsdelf*-gnu) ;; *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* | sunCC*) # 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 that 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if test ${lt_cv_prog_compiler_pic_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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" ## exclude from sc_useless_quotes_in_assignment # 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; 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\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "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' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' 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 GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. 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) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && 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 yes,yes = "$GCC,$enable_shared"; 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. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc_CXX+y} then : printf %s "(cached) " >&6 else $as_nop $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=$? printf "%s\n" "$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=$? printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "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 # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; 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 # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # 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' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # 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' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac 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%'\''`; $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 # correct to gnu/linux during the next big refactor 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,$cc_basename in yes,*) # gcc 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 dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # 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' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # 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 # correct to gnu/linux during the next big refactor 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* | midnightbsd*) # 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$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' 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 # correct to gnu/linux during the next big refactor 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=no 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 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; 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 # correct to gnu/linux during the next big refactor 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 yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor 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 ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # 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 dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor 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 test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop 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\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; 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.beam \ 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 # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) 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' ;; netbsdelf*-gnu) 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=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_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 # correct to gnu/linux during the next big refactor 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* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi 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 shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 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' ;; 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 # correct to gnu/linux during the next big refactor 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 yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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=sco 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 yes = "$with_gnu_ld"; 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 # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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 ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "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 yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # 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 no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 printf "%s\n" "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS 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 yes != "$_lt_caught_CXX_error" 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 # BUILDDATE=`date` # Build a standalone python module # Check whether --enable-module was given. if test ${enable_module+y} then : enableval=$enable_module; fi if test "$enable_module" = "yes"; then BUILD_MODULE_TRUE= BUILD_MODULE_FALSE='#' else BUILD_MODULE_TRUE='#' BUILD_MODULE_FALSE= fi # pbuilder debian package build # Check whether --enable-debian was given. if test ${enable_debian+y} then : enableval=$enable_debian; fi if test "$enable_debian" = "yes"; then BUILD_DEBIAN_TRUE= BUILD_DEBIAN_FALSE='#' else BUILD_DEBIAN_TRUE='#' BUILD_DEBIAN_FALSE= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for kernel" >&5 printf %s "checking for kernel... " >&6; } case `uname` in Darwin) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: darwin" >&5 printf "%s\n" "darwin" >&6; } CXXFLAGS="${CXXFLAGS} -fPIC" CFLAGS="${CFLAGS} -fPIC" STFKERNEL="darwin" ;; *) # treat everything else (kfreebsd, hurd) as linux { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: linux or similar" >&5 printf "%s\n" "linux or similar" >&6; } CXXFLAGS="-fPIC" CFLAGS="-fPIC" STFKERNEL="linux" ;; esac if test $STFKERNEL = "darwin"; then ISDARWIN_TRUE= ISDARWIN_FALSE='#' else ISDARWIN_TRUE='#' ISDARWIN_FALSE= fi # https://stackoverflow.com/questions/11909347/autotools-check-for-c11 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ standard (boost is not required with c++17 and later) " >&5 printf %s "checking for C++ standard (boost is not required with c++17 and later) ... " >&6; } DIALECT="-std=gnu++17" echo 'int main() {return 0;}' > ./log.cpp && $CXX $DIALECT ./log.cpp || DIALECT="-std=c++17" $CXX $DIALECT ./log.cpp || $DIALECT="no" if test $DIALECT = no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: c++17 not supported - boost is required" >&5 printf "%s\n" "c++17 not supported - boost is required" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DIALECT" >&5 printf "%s\n" "$DIALECT" >&6; } CXXFLAGS="${CXXFLAGS} ${DIALECT}" fi # Checks for python libraries. # Check whether --enable-python was given. if test ${enable_python+y} then : enableval=$enable_python; else $as_nop enable_python="yes" fi if test "$enable_python" = "yes"; then BUILD_PYTHON_TRUE= BUILD_PYTHON_FALSE='#' else BUILD_PYTHON_TRUE='#' BUILD_PYTHON_FALSE= fi if (test "$enable_python" = "yes") || (test "$enable_module" = "yes"); then # # Allow the use of a (user set) custom python version # # Extract the first word of "python[$PYTHON_VERSION]", so it can be a program name with args. set dummy python$PYTHON_VERSION; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PYTHON+y} then : printf %s "(cached) " >&6 else $as_nop case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 printf "%s\n" "$PYTHON" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$PYTHON"; then as_fn_error $? "Cannot find python$PYTHON_VERSION in your system path" "$LINENO" 5 PYTHON_VERSION="" fi # # Check for a version of Python >= 2.1.0 # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a version of Python >= '2.1.0'" >&5 printf %s "checking for a version of Python >= '2.1.0'... " >&6; } ac_supports_python_ver=`$PYTHON -c "import sys, string; \ ver = sys.version.split()[0]; \ print(ver >= '2.1.0')"` if test "$ac_supports_python_ver" != "True"; then if test -z "$PYTHON_NOVERSIONCHECK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? " This version of the AC_PYTHON_DEVEL macro doesn't work properly with versions of Python before 2.1.0. You may need to re-run configure, setting the variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG, PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. Moreover, to disable this check, set PYTHON_NOVERSIONCHECK to something else than an empty string. See \`config.log' for more details" "$LINENO" 5; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: skip at user request" >&5 printf "%s\n" "skip at user request" >&6; } fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi # # if the macro parameter ``version'' is set, honour it # if test -n ""; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a version of Python " >&5 printf %s "checking for a version of Python ... " >&6; } ac_supports_python_ver=`$PYTHON -c "import sys, string; \ ver = sys.version.split()[0]; \ sys.stdout.write(ver + '' + '\n')"` if test "$ac_supports_python_ver" = "True"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "this package requires Python . If you have it installed, but it isn't the default Python interpreter in your system path, please pass the PYTHON_VERSION variable to configure. See \`\`configure --help'' for reference. " "$LINENO" 5 PYTHON_VERSION="" fi fi # # Check if you have distutils, else fail # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5 printf %s "checking for the distutils Python package... " >&6; } ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` if test $? -eq 0; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "cannot import Python module \"distutils\". Please check your Python installation. The error was: $ac_distutils_result" "$LINENO" 5 PYTHON_VERSION="" fi # # Check for Python include path # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python include path" >&5 printf %s "checking for Python include path... " >&6; } if test -z "$PYTHON_CPPFLAGS"; then python_path=`$PYTHON -c "import distutils.sysconfig, sys; \ sys.stdout.write(distutils.sysconfig.get_python_inc() + '\n');"` if test -n "${python_path}"; then python_path="-I$python_path" fi PYTHON_CPPFLAGS=$python_path fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CPPFLAGS" >&5 printf "%s\n" "$PYTHON_CPPFLAGS" >&6; } # # Check for Python library path # # # Check for Python library path # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python library path" >&5 printf %s "checking for Python library path... " >&6; } if test -z "$PYTHON_LDFLAGS"; then # (makes two attempts to ensure we've got a version number # from the interpreter) py_version=`$PYTHON -c \ "import sys; from distutils.sysconfig import * if get_config_vars('LDVERSION')[0] is None: sys.stdout.write(' '.join(get_config_vars('VERSION'))+'\n') else: sys.stdout.write(' '.join(get_config_vars('LDVERSION'))+'\n')"` if test "$py_version" == "None"; then if test -n "$PYTHON_VERSION"; then py_version=$PYTHON_VERSION else py_version=`$PYTHON -c "import sys; \ sys.stdout.write(sys.version[:3] + '\n')"` fi fi PY_AC_VERSION=$py_version PYTHON_LDFLAGS=`$PYTHON -c "import sys; from distutils.sysconfig import *; \ sys.stdout.write('-L' + get_config_vars()['LIBDIR'] + \ ' -lpython' + '\n');"`$py_version fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LDFLAGS" >&5 printf "%s\n" "$PYTHON_LDFLAGS" >&6; } # # Check for prefixed site packages # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for prefixed Python site-packages path" >&5 printf %s "checking for prefixed Python site-packages path... " >&6; } if test -z "$PYTHON_SITE_PKG"; then PYTHON_SITE_PKG=`$PYTHON -c \ "import sys, distutils.sysconfig; \ acprefix = \"${prefix}\" if acprefix is \"NONE\": acprefix=\"/usr/local/\" sys.stdout.write(distutils.sysconfig.get_python_lib(0,1,prefix=acprefix)+'\n');"` PYTHON_SITE_PKG="${PYTHON_SITE_PKG}/dist-packages" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_SITE_PKG" >&5 printf "%s\n" "$PYTHON_SITE_PKG" >&6; } # # Check for prefixed dist packages # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for prefixed Python dist-packages path" >&5 printf %s "checking for prefixed Python dist-packages path... " >&6; } if test -z "$PYTHON_PRE_DIST_PKG"; then PYTHON_PRE_DIST_PKG=`$PYTHON -c \ "import sys, distutils.sysconfig; \ acprefix = \"${prefix}\" if acprefix is \"NONE\": acprefix=\"/usr/local/\" sys.stdout.write(distutils.sysconfig.get_python_lib(0,0,prefix=acprefix)+'\n');"` PYTHON_PRE_DIST_PKG=${PYTHON_PRE_DIST_PKG} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_PRE_DIST_PKG" >&5 printf "%s\n" "$PYTHON_PRE_DIST_PKG" >&6; } # # Check for unprefixed dist packages path # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unprefixed Python dist-packages path" >&5 printf %s "checking for unprefixed Python dist-packages path... " >&6; } if test -z "$PYTHON_DIST_PKG"; then PYTHON_DIST_PKG=`$PYTHON -c \ "import sys, distutils.sysconfig; \ sys.stdout.write(distutils.sysconfig.get_python_lib(0,0)+'\n');"` PYTHON_DIST_PKG=${PYTHON_DIST_PKG} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_DIST_PKG" >&5 printf "%s\n" "$PYTHON_DIST_PKG" >&6; } # # Check if you have numpy, else fail # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for numpy" >&5 printf %s "checking for numpy... " >&6; } ac_numpy_result=`$PYTHON -c "import numpy" 2>&1` if test -z "$ac_numpy_result"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "cannot import Python module \"numpy\". Please check your numpy installation. The error was: $ac_numpy_result" "$LINENO" 5 PYTHON_VERSION="" fi # # Check for numpy headers # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for numpy include path" >&5 printf %s "checking for numpy include path... " >&6; } if test -z "$PYTHON_NUMPY_INCLUDE"; then PYTHON_NUMPY_INCLUDE=-I`$PYTHON -c "import sys, numpy; \ sys.stdout.write(numpy.get_include() + '\n');"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_NUMPY_INCLUDE" >&5 printf "%s\n" "$PYTHON_NUMPY_INCLUDE" >&6; } # # Check if you have wxPython, else fail # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wxPython" >&5 printf %s "checking for wxPython... " >&6; } ac_wxpython_result=`$PYTHON -c "import wx" 2>&1` if test -z "$ac_wxpython_result"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } as_fn_error $? "cannot import Python module \"wxpython\". Please check your wxpython installation. The error was: $ac_wxpython_result" "$LINENO" 5 PYTHON_VERSION="" fi # # Check for wxpython headers # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wxpython include path" >&5 printf %s "checking for wxpython include path... " >&6; } if test -z "$PYTHON_WXPYTHON_INCLUDE"; then PYTHON_WXPYTHON_INCLUDE=-I`$PYTHON -c "import os, sys, wx; \ sys.stdout.write(os.path.join(os.path.dirname(wx.__spec__.origin), 'include') + '\n');"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_WXPYTHON_INCLUDE" >&5 printf "%s\n" "$PYTHON_WXPYTHON_INCLUDE" >&6; } # # libraries which must be linked in when embedding # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking python extra libraries" >&5 printf %s "checking python extra libraries... " >&6; } if test -z "$PYTHON_EXTRA_LIBS"; then PYTHON_EXTRA_LIBS=`$PYTHON -c "import sys, distutils.sysconfig; \ conf = distutils.sysconfig.get_config_var; \ sys.stdout.write(conf('LOCALMODLIBS') + ' ' + conf('LIBS') + ' ' + '\n')"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LIBS" >&5 printf "%s\n" "$PYTHON_EXTRA_LIBS" >&6; } # # linking flags needed when embedding # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking python extra linking flags" >&5 printf %s "checking python extra linking flags... " >&6; } if test -z "$PYTHON_EXTRA_LDFLAGS"; then PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import sys, distutils.sysconfig; \ conf = distutils.sysconfig.get_config_var; \ sys.stdout.write(conf('LINKFORSHARED')+'\n')"` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_EXTRA_LDFLAGS" >&5 printf "%s\n" "$PYTHON_EXTRA_LDFLAGS" >&6; } # # final check to see if everything compiles alright # { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking consistency of all components of python development environment" >&5 printf %s "checking consistency of all components of python development environment... " >&6; } 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 # save current global flags LIBS="$ac_save_LIBS $PYTHON_LDFLAGS -lm" CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { Py_Initialize(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : pythonexists=yes else $as_nop pythonexists=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $pythonexists" >&5 printf "%s\n" "$pythonexists" >&6; } if test ! "$pythonexists" = "yes"; then as_fn_error $? " Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LDFLAGS environment variable. Example: ./configure LDFLAGS=\"-L/usr/non-standard-path/python/lib\" ============================================================================ ERROR! You probably have to install the development version of the Python package for your distribution. The exact name of this package varies among them. ============================================================================ " "$LINENO" 5 PYTHON_VERSION="" 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 # turn back to default flags CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" # # all done! # # Extract the first word of "swig", so it can be a program name with args. set dummy swig; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SWIG+y} then : printf %s "(cached) " >&6 else $as_nop case $SWIG in [\\/]* | ?:[\\/]*) ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SWIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SWIG=$ac_cv_path_SWIG if test -n "$SWIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5 printf "%s\n" "$SWIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$SWIG" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5 printf "%s\n" "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;} SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false' elif test -n "1.3.17" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5 printf %s "checking for SWIG version... " >&6; } swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5 printf "%s\n" "$swig_version" >&6; } if test -n "$swig_version" ; then # Calculate the required version number components required=1.3.17 required_major=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_major" ; then required_major=0 fi required=`echo $required | sed 's/[0-9]*[^0-9]//'` required_minor=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_minor" ; then required_minor=0 fi required=`echo $required | sed 's/[0-9]*[^0-9]//'` required_patch=`echo $required | sed 's/[^0-9].*//'` if test -z "$required_patch" ; then required_patch=0 fi # Calculate the available version number components available=$swig_version available_major=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_major" ; then available_major=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_minor=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_minor" ; then available_minor=0 fi available=`echo $available | sed 's/[0-9]*[^0-9]//'` available_patch=`echo $available | sed 's/[^0-9].*//'` if test -z "$available_patch" ; then available_patch=0 fi if test $available_major -ne $required_major \ -o $available_minor -ne $required_minor \ -o $available_patch -lt $required_patch ; then if test $available_major -lt $required_major ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 1.3.17 is required. You have $swig_version. You should look at http://www.swig.org" >&5 printf "%s\n" "$as_me: WARNING: SWIG version >= 1.3.17 is required. You have $swig_version. You should look at http://www.swig.org" >&2;} SWIG='echo "Error: SWIG version >= 1.3.17 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: SWIG executable is '$SWIG'" >&5 printf "%s\n" "$as_me: SWIG executable is '$SWIG'" >&6;} SWIG_LIB=`$SWIG -swiglib` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: SWIG library directory is '$SWIG_LIB'" >&5 printf "%s\n" "$as_me: SWIG library directory is '$SWIG_LIB'" >&6;} fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5 printf "%s\n" "$as_me: WARNING: cannot determine SWIG version" >&2;} SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false' fi fi SWIG="$SWIG -c++" test "x" != "xno" || swig_shadow=" -noproxy" SWIG_PYTHON_OPT=-python$swig_shadow SWIG_PYTHON_CPPFLAGS=$PYTHON_CPPFLAGS CXXFLAGS="${CXXFLAGS}" CFLAGS="${CFLAGS}" LIBPYTHON_LDFLAGS=$PYTHON_LDFLAGS LIBPYTHON_INCLUDES=$PYTHON_CPPFLAGS LIBNUMPY_INCLUDES=$PYTHON_NUMPY_INCLUDE LIBWXPYTHON_INCLUDES=$PYTHON_WXPYTHON_INCLUDE else LIBPYTHON_LDFLAGS= LIBPYTHON_INCLUDES= LIBNUMPY_INCLUDES= LIBWXPYTHON_INCLUDES= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for kernel" >&5 printf %s "checking for kernel... " >&6; } case ${STFKERNEL} in darwin) LIBSTF_LDFLAGS="-avoid-version" if test "$enable_module" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DMODULE_ONLY" else CPPFLAGS="${CPPFLAGS}" fi STF_PYTHON_LIBNAME="libpystf.dylib" STFIO_PYTHON_LIBNAME="libpystfio.dylib" ARCH_FLAGS="" CFLAGS="${CFLAGS} ${ARCH_FLAGS}" CXXFLAGS="${CXXFLAGS} ${ARCH_FLAGS}" LDFLAGS="${LDFLAGS} ${ARCH_FLAGS}" OBJCFLAGS="${OBJCFLAGS} ${ARCH_FLAGS}" OBJCXXFLAGS="${OBJCXXFLAGS} ${ARCH_FLAGS}" ;; *) if test "$enable_module" = "yes" ; then LIBSTF_LDFLAGS="-avoid-version" CPPFLAGS="${CPPFLAGS} -DMODULE_ONLY" else if test "$enable_debian" = "yes" ; then LIBSTF_LDFLAGS="-Wl,-rpath,/usr/lib/stimfit -avoid-version" else LIBSTF_LDFLAGS="-Wl,-rpath,${prefix}/lib/stimfit -avoid-version" fi CPPFLAGS="${CPPFLAGS}" fi if test "$enable_debian" = "yes" ; then CPPFLAGS="${CPPFLAGS} `dpkg-buildflags --get CPPFLAGS`" CFLAGS="${CFLAGS} `dpkg-buildflags --get CFLAGS`" CXXFLAGS="${CXXFLAGS} `dpkg-buildflags --get CXXFLAGS`" LDFLAGS="${LDFLAGS} `dpkg-buildflags --get LDFLAGS`" fi STF_PYTHON_LIBNAME="libpystf.so" STFIO_PYTHON_LIBNAME="libpystfio.so" ;; esac # Checks for python libraries. if test "$enable_python" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DWITH_PYTHON" fi # Check whether --enable-ipython was given. if test ${enable_ipython+y} then : enableval=$enable_ipython; fi if test "$enable_ipython" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DIPYTHON" fi # Build the exotic Stimfit flavour with Slope cursors # Check whether --with-pslope was given. if test ${with_pslope+y} then : withval=$with_pslope; fi if test "$with_pslope" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DWITH_PSLOPE" fi # by default build WITH_BIOSIG # Check whether --with-biosig was given. if test ${with_biosig+y} then : withval=$with_biosig; else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sread in -lbiosig" >&5 printf %s "checking for sread in -lbiosig... " >&6; } if test ${ac_cv_lib_biosig_sread+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lbiosig $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. */ char sread (); int main (void) { return sread (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_biosig_sread=yes else $as_nop ac_cv_lib_biosig_sread=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_biosig_sread" >&5 printf "%s\n" "$ac_cv_lib_biosig_sread" >&6; } if test "x$ac_cv_lib_biosig_sread" = xyes then : with_biosig="yes" else $as_nop with_biosig="no" fi fi if test "x$with_biosig" = "xyes"; then WITH_BIOSIG_TRUE= WITH_BIOSIG_FALSE='#' else WITH_BIOSIG_TRUE='#' WITH_BIOSIG_FALSE= fi # Check whether --with-biosiglite was given. if test ${with_biosiglite+y} then : withval=$with_biosiglite; fi if test "x$with_biosiglite" = "xyes"; then WITH_BIOSIGLITE_TRUE= WITH_BIOSIGLITE_FALSE='#' else WITH_BIOSIGLITE_TRUE='#' WITH_BIOSIGLITE_FALSE= fi if test "x$with_biosiglite" = xyes ; then CPPFLAGS="${CPPFLAGS} -DWITH_BIOSIG -DWITH_BIOSIGLITE" LIBBIOSIG_LDFLAGS="" # LIBBIOSIG_LDFLAGS="-lcholmod" elif test "x$with_biosig" != xno ; then CPPFLAGS="${CPPFLAGS} -DWITH_BIOSIG" LIBBIOSIG_LDFLAGS="-lbiosig" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Stimfit recommends using --with-biosig or --with-biosiglite" >&5 printf "%s\n" "$as_me: WARNING: Stimfit recommends using --with-biosig or --with-biosiglite" >&2;} fi # Check whether --with-lapack-lib was given. if test ${with_lapack_lib+y} then : withval=$with_lapack_lib; if test "$withval" != "yes" -a "$withval" != ""; then LAPACKLIB=$withval LIBLAPACK_LDFLAGS="$LAPACKLIB" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fftw_malloc in -lfftw3" >&5 printf %s "checking for fftw_malloc in -lfftw3... " >&6; } if test ${ac_cv_lib_fftw3_fftw_malloc+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lfftw3 $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. */ char fftw_malloc (); int main (void) { return fftw_malloc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_fftw3_fftw_malloc=yes else $as_nop ac_cv_lib_fftw3_fftw_malloc=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw3_fftw_malloc" >&5 printf "%s\n" "$ac_cv_lib_fftw3_fftw_malloc" >&6; } if test "x$ac_cv_lib_fftw3_fftw_malloc" = xyes then : HAVE_FFTW3="yes" fi if test "${HAVE_FFTW3}" != "yes" ; then as_fn_error $? "Couldn't find fftw3." "$LINENO" 5 fi if test "$LAPACKLIB" = ""; then if test "$STFKERNEL" = "darwin" ; then # System LAPACK # LIBLAPACK_LDFLAGS="/usr/lib/liblapack.dylib -framework Accelerate" LIBLAPACK_LDFLAGS="-framework Accelerate" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK -DHAVE_LAPACK_SUFFIX" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgemm_ in -lopenblas" >&5 printf %s "checking for dgemm_ in -lopenblas... " >&6; } if test ${ac_cv_lib_openblas_dgemm_+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lopenblas -lgomp -lpthread -lm $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. */ char dgemm_ (); int main (void) { return dgemm_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_openblas_dgemm_=yes else $as_nop ac_cv_lib_openblas_dgemm_=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openblas_dgemm_" >&5 printf "%s\n" "$ac_cv_lib_openblas_dgemm_" >&6; } if test "x$ac_cv_lib_openblas_dgemm_" = xyes then : HAVE_OPENBLAS="yes" fi if test "${HAVE_OPENBLAS}" != "yes" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgemm_ in -llapack" >&5 printf %s "checking for dgemm_ in -llapack... " >&6; } if test ${ac_cv_lib_lapack_dgemm_+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-llapack $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. */ char dgemm_ (); int main (void) { return dgemm_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_lapack_dgemm_=yes else $as_nop ac_cv_lib_lapack_dgemm_=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lapack_dgemm_" >&5 printf "%s\n" "$ac_cv_lib_lapack_dgemm_" >&6; } if test "x$ac_cv_lib_lapack_dgemm_" = xyes then : HAVE_LAPACKX="yes" fi if test "${HAVE_LAPACKX}" != "yes" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgemm_ in -llapack3" >&5 printf %s "checking for dgemm_ in -llapack3... " >&6; } if test ${ac_cv_lib_lapack3_dgemm_+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-llapack3 $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. */ char dgemm_ (); int main (void) { return dgemm_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_lapack3_dgemm_=yes else $as_nop ac_cv_lib_lapack3_dgemm_=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lapack3_dgemm_" >&5 printf "%s\n" "$ac_cv_lib_lapack3_dgemm_" >&6; } if test "x$ac_cv_lib_lapack3_dgemm_" = xyes then : HAVE_LAPACK3="yes" fi if test "${HAVE_LAPACK3}" != "yes" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgemm_ in -llapack-3" >&5 printf %s "checking for dgemm_ in -llapack-3... " >&6; } if test ${ac_cv_lib_lapack_3_dgemm_+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-llapack-3 $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. */ char dgemm_ (); int main (void) { return dgemm_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_lapack_3_dgemm_=yes else $as_nop ac_cv_lib_lapack_3_dgemm_=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lapack_3_dgemm_" >&5 printf "%s\n" "$ac_cv_lib_lapack_3_dgemm_" >&6; } if test "x$ac_cv_lib_lapack_3_dgemm_" = xyes then : HAVE_LAPACK_3="yes" fi if test "${HAVE_LAPACK_3}" != "yes" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dgemm_ in -lblas" >&5 printf %s "checking for dgemm_ in -lblas... " >&6; } if test ${ac_cv_lib_blas_dgemm_+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lblas $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. */ char dgemm_ (); int main (void) { return dgemm_ (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_blas_dgemm_=yes else $as_nop ac_cv_lib_blas_dgemm_=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blas_dgemm_" >&5 printf "%s\n" "$ac_cv_lib_blas_dgemm_" >&6; } if test "x$ac_cv_lib_blas_dgemm_" = xyes then : HAVE_ATLAS="yes" fi LIBLAPACK_LDFLAGS="-llapack -lblas" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " else LIBLAPACK_LDFLAGS="-llapack-3" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " fi else LIBLAPACK_LDFLAGS=-llapack3 CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " fi else LIBLAPACK_LDFLAGS="-llapack -lblas" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " fi else LIBLAPACK_LDFLAGS="-lopenblas" CPPFLAGS="${CPPFLAGS} -DWITH_OPENBLAS -DHAVE_LAPACK" fi fi fi # stuff not required for standalone module if test "$enable_module" != "yes"; then # Optionally enables aui for doc/view architecture # Check whether --enable-aui was given. if test ${enable_aui+y} then : enableval=$enable_aui; fi if test "$enable_aui" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DWITH_AUIDOCVIEW" fi WXCONFIG=wx-config # Check whether --with-wx-config was given. if test ${with_wx_config+y} then : withval=$with_wx_config; if test "$withval" != "yes" -a "$withval" != ""; then WXCONFIG=$withval fi fi wxversion=0 # Call WXTEST func { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking wxWidgets version" >&5 printf %s "checking wxWidgets version... " >&6; } if wxversion=`$WXCONFIG --version`; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $wxversion" >&5 printf "%s\n" "$wxversion" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5 printf "%s\n" "not found" >&6; } as_fn_error $? "wxWidgets is required. Try --with-wx-config." "$LINENO" 5 fi # Verify minimus requires { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wxWidgets libraries" >&5 printf %s "checking for wxWidgets libraries... " >&6; } vers=`echo $wxversion | $AWK 'BEGIN { FS = "."; } { printf "% d", ($1 * 1000 + $2) * 1000 + $3;}'` if test -n "$vers" && test "$vers" -ge 2008000; then WX_CPPFLAGS="`$WXCONFIG --cppflags`" WX_CXXFLAGS="`$WXCONFIG --cxxflags`" if test "$STFKERNEL" = "darwin" ; then if test "${PY_AC_VERSION:0:1}" -ge 3; then WX_LIBS="`$WXCONFIG --libs all`" else WX_LIBS="`$WXCONFIG --libs propgrid,aui,adv,core,net,base`" fi else WX_LIBS="`$WXCONFIG --libs base,core,adv,aui,net`" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WX_LIBS" >&5 printf "%s\n" "$WX_LIBS" >&6; } else as_fn_error $? "wxWidgets 2.8.0 or newer is required" "$LINENO" 5 fi # CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" # CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS" dnl included in cppflags POSTLINK_COMMAND="@true" MACSETFILE="@true" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wxWidgets platform" >&5 printf %s "checking for wxWidgets platform... " >&6; } WX_BASENAME="`$WXCONFIG --basename`" case $WX_BASENAME in *wx_osx*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WX_BASENAME" >&5 printf "%s\n" "$WX_BASENAME" >&6; } # Extract the first word of "Rez", so it can be a program name with args. set dummy Rez; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_REZ+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$REZ"; then ac_cv_prog_REZ="$REZ" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_REZ="Rez" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_REZ" && ac_cv_prog_REZ="/Developer/Tools/Rez" fi fi REZ=$ac_cv_prog_REZ if test -n "$REZ"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $REZ" >&5 printf "%s\n" "$REZ" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi POSTLINK_COMMAND="\$(REZ) -d __DARWIN__ -t APPL -o" # Extract the first word of "SetFile", so it can be a program name with args. set dummy SetFile; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_SETFILE+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$SETFILE"; then ac_cv_prog_SETFILE="$SETFILE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_SETFILE="SetFile" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_SETFILE" && ac_cv_prog_SETFILE="/Developer/Tools/SetFile" fi fi SETFILE=$ac_cv_prog_SETFILE if test -n "$SETFILE"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SETFILE" >&5 printf "%s\n" "$SETFILE" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi MACSETFILE="\$(SETFILE)" ;; *wx_mac*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WX_BASENAME" >&5 printf "%s\n" "$WX_BASENAME" >&6; } # Extract the first word of "Rez", so it can be a program name with args. set dummy Rez; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_REZ+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$REZ"; then ac_cv_prog_REZ="$REZ" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_REZ="Rez" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_REZ" && ac_cv_prog_REZ="/Developer/Tools/Rez" fi fi REZ=$ac_cv_prog_REZ if test -n "$REZ"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $REZ" >&5 printf "%s\n" "$REZ" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi POSTLINK_COMMAND="\$(REZ) -d __DARWIN__ -t APPL -o" # Extract the first word of "SetFile", so it can be a program name with args. set dummy SetFile; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_SETFILE+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$SETFILE"; then ac_cv_prog_SETFILE="$SETFILE" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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_SETFILE="SetFile" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_SETFILE" && ac_cv_prog_SETFILE="/Developer/Tools/SetFile" fi fi SETFILE=$ac_cv_prog_SETFILE if test -n "$SETFILE"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SETFILE" >&5 printf "%s\n" "$SETFILE" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi MACSETFILE="\$(SETFILE)" ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: other" >&5 printf "%s\n" "other" >&6; } ;; esac fi # Checks for hdf5 libraries. # Check whether --with-hdf5-prefix was given. if test ${with_hdf5_prefix+y} then : withval=$with_hdf5_prefix; if test "$withval" != "yes" -a "$withval" != ""; then HDF5_PREFIX=${withval} LDFLAGS="${LDFLAGS} -L${HDF5_PREFIX}/lib" CPPFLAGS="${CPPFLAGS} -I${HDF5_PREFIX}/include" fi fi if test "${HDF5PREFIX}" = ""; then if test "$STFKERNEL" = "linux" ; then if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hdf5" >&5 printf %s "checking for hdf5... " >&6; } if test -n "$HDF5_CFLAGS"; then pkg_cv_HDF5_CFLAGS="$HDF5_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"hdf5\""; } >&5 ($PKG_CONFIG --exists --print-errors "hdf5") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_HDF5_CFLAGS=`$PKG_CONFIG --cflags "hdf5" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$HDF5_LIBS"; then pkg_cv_HDF5_LIBS="$HDF5_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"hdf5\""; } >&5 ($PKG_CONFIG --exists --print-errors "hdf5") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_HDF5_LIBS=`$PKG_CONFIG --libs "hdf5" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then HDF5_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "hdf5" 2>&1` else HDF5_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "hdf5" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$HDF5_PKG_ERRORS" >&5 HDF5_CFLAGS="" HDF5_LIBS="" elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } HDF5_CFLAGS="" HDF5_LIBS="" else HDF5_CFLAGS=$pkg_cv_HDF5_CFLAGS HDF5_LIBS=$pkg_cv_HDF5_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } CPPFLAGS="${CPPFLAGS} ${HDF5_CFLAGS} -DH5_USE_16_API" LIBHDF5_LDFLAGS="${HDF5_LIBS} -lhdf5_hl" LDFLAGS="${LDFLAGS} ${LIBHDF5_LDFLAGS}" fi fi fi ac_fn_c_check_header_compile "$LINENO" "hdf5.h" "ac_cv_header_hdf5_h" "$ac_includes_default" if test "x$ac_cv_header_hdf5_h" = xyes then : else $as_nop as_fn_error $? "Couldn't find hdf5 header" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for H5Fopen in -lhdf5" >&5 printf %s "checking for H5Fopen in -lhdf5... " >&6; } if test ${ac_cv_lib_hdf5_H5Fopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lhdf5 $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. */ char H5Fopen (); int main (void) { return H5Fopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_hdf5_H5Fopen=yes else $as_nop ac_cv_lib_hdf5_H5Fopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hdf5_H5Fopen" >&5 printf "%s\n" "$ac_cv_lib_hdf5_H5Fopen" >&6; } if test "x$ac_cv_lib_hdf5_H5Fopen" = xyes then : HAVE_HDF5="yes" fi if test "${HDF5_CFLAGS}" = ""; then CPPFLAGS="${CPPFLAGS} -DH5_USE_16_API" LIBHDF5_LDFLAGS="-lhdf5 -lhdf5_hl" fi # Check whether --enable-debug was given. if test ${enable_debug+y} then : enableval=$enable_debug; fi if test "$enable_debug" = "yes" ; then CPPFLAGS="${CPPFLAGS} -D_STFDEBUG " OPT_CXXFLAGS="-O0 -g3" CFLAGS="${CFLAGS} -O0 -g3" else OPT_CXXFLAGS="-O2 -g" CFLAGS="${CFLAGS} -O2 -g" fi # gtest GT_CPPFLAGS="" GT_CXXFLAGS="" GT_LIBS="-lpthread" GT_LDFLAGS="" # end gtest # CPPFLAGS="${CPPFLAGS} -DSTFDATE='\"${BUILDDATE}\"'" CXXFLAGS="${CXXFLAGS} -Wall" ac_config_headers="$ac_config_headers stfconf.h" ac_config_files="$ac_config_files Makefile src/Makefile src/libstfio/Makefile src/libstfnum/Makefile src/libbiosiglite/Makefile src/pystfio/Makefile src/stimfit/Makefile src/stimfit/py/Makefile dist/macosx/stimfit.plist dist/macosx/macports/insert_checksums.sh dist/macosx/scripts/mkimage.sh dist/macosx/package.pmdoc/index.xml dist/debian/mkdeb.sh dist/debian/mkquick.sh setup.py dist/conda/py-stfio-debug/meta.yaml dist/conda/py-stfio/meta.yaml doc/Doxyfile doc/sphinx/conf.py Makefile.static" 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_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$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+y} || &/ 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$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=`printf "%s\n" "$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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi 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 -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 "${BUILD_MODULE_TRUE}" && test -z "${BUILD_MODULE_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_DEBIAN_TRUE}" && test -z "${BUILD_DEBIAN_FALSE}"; then as_fn_error $? "conditional \"BUILD_DEBIAN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ISDARWIN_TRUE}" && test -z "${ISDARWIN_FALSE}"; then as_fn_error $? "conditional \"ISDARWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_PYTHON_TRUE}" && test -z "${BUILD_PYTHON_FALSE}"; then as_fn_error $? "conditional \"BUILD_PYTHON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_BIOSIG_TRUE}" && test -z "${WITH_BIOSIG_FALSE}"; then as_fn_error $? "conditional \"WITH_BIOSIG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_BIOSIGLITE_TRUE}" && test -z "${WITH_BIOSIGLITE_FALSE}"; then as_fn_error $? "conditional \"WITH_BIOSIGLITE\" 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" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$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 as_nop=: if test ${ZSH_VERSION+y} && (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 $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; 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 # 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 case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac 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 printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # 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 printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$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_nop 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_nop 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 || printf "%s\n" 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 # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. 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 # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' 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=`printf "%s\n" "$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 || printf "%s\n" 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 stimfit $as_me 0.16.7, which was generated by GNU Autoconf 2.71. 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 ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ stimfit config.status 0.16.7 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 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 ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$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=`printf "%s\n" "$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 ) printf "%s\n" "$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 \printf "%s\n" "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 printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # 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"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $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"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $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"`' FILECMD='`$ECHO "$FILECMD" | $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"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $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_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $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"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $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_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $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"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $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_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"`' 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"`' postlink_cmds='`$ECHO "$postlink_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"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $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_pic_CXX='`$ECHO "$lt_prog_compiler_pic_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_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_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"`' 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"`' postlink_cmds_CXX='`$ECHO "$postlink_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 \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ 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_separator \ 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_pic_CXX \ lt_prog_compiler_wl_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_separator_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\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) 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 \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ 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 \ postlink_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\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that 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' 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 "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "stfconf.h") CONFIG_HEADERS="$CONFIG_HEADERS stfconf.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/libstfio/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstfio/Makefile" ;; "src/libstfnum/Makefile") CONFIG_FILES="$CONFIG_FILES src/libstfnum/Makefile" ;; "src/libbiosiglite/Makefile") CONFIG_FILES="$CONFIG_FILES src/libbiosiglite/Makefile" ;; "src/pystfio/Makefile") CONFIG_FILES="$CONFIG_FILES src/pystfio/Makefile" ;; "src/stimfit/Makefile") CONFIG_FILES="$CONFIG_FILES src/stimfit/Makefile" ;; "src/stimfit/py/Makefile") CONFIG_FILES="$CONFIG_FILES src/stimfit/py/Makefile" ;; "dist/macosx/stimfit.plist") CONFIG_FILES="$CONFIG_FILES dist/macosx/stimfit.plist" ;; "dist/macosx/macports/insert_checksums.sh") CONFIG_FILES="$CONFIG_FILES dist/macosx/macports/insert_checksums.sh" ;; "dist/macosx/scripts/mkimage.sh") CONFIG_FILES="$CONFIG_FILES dist/macosx/scripts/mkimage.sh" ;; "dist/macosx/package.pmdoc/index.xml") CONFIG_FILES="$CONFIG_FILES dist/macosx/package.pmdoc/index.xml" ;; "dist/debian/mkdeb.sh") CONFIG_FILES="$CONFIG_FILES dist/debian/mkdeb.sh" ;; "dist/debian/mkquick.sh") CONFIG_FILES="$CONFIG_FILES dist/debian/mkquick.sh" ;; "setup.py") CONFIG_FILES="$CONFIG_FILES setup.py" ;; "dist/conda/py-stfio-debug/meta.yaml") CONFIG_FILES="$CONFIG_FILES dist/conda/py-stfio-debug/meta.yaml" ;; "dist/conda/py-stfio/meta.yaml") CONFIG_FILES="$CONFIG_FILES dist/conda/py-stfio/meta.yaml" ;; "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; "doc/sphinx/conf.py") CONFIG_FILES="$CONFIG_FILES doc/sphinx/conf.py" ;; "Makefile.static") CONFIG_FILES="$CONFIG_FILES Makefile.static" ;; *) 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+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || 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=`printf "%s\n" "$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 '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$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 || printf "%s\n" 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=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$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@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$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"; } && { printf "%s\n" "$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 printf "%s\n" "$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 { printf "%s\n" "/* $configure_input */" >&1 \ && 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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$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 printf "%s\n" "/* $configure_input */" >&1 \ && 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 || printf "%s\n" 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) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "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. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that 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 # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # 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 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 this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### 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 # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # 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 # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # 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 # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # 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 into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # 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 lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # 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 # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # 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 # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # 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 # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # 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 # 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 # 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 # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_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 cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _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 set != "${COLLECT_NAMES+set}"; 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 '$q' "$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 # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_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 # 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 # 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 # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_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 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi stimfit-0.16.7/dist/0000775000175000017500000000000014764352500010000 5stimfit-0.16.7/dist/debian/0000775000175000017500000000000014764352500011222 5stimfit-0.16.7/dist/debian/python3-stfio.files0000664000175000017500000000011514750344764014721 usr/lib/python*/*-packages/stfio/_*.so usr/lib/python*/*-packages/stfio/*.py stimfit-0.16.7/dist/debian/stimfit.files0000664000175000017500000000060114755262551013650 usr/share/applications/stimfit.desktop usr/share/icons/hicolor/16x16/apps/stimfit.png usr/share/icons/hicolor/32x32/apps/stimfit.png usr/share/icons/hicolor/48x48/apps/stimfit.png usr/share/icons/hicolor/128x128/apps/stimfit.png usr/share/icons/hicolor/256x256/apps/stimfit.png usr/share/icons/hicolor/512x512/apps/stimfit.png usr/lib/stimfit/*.py usr/lib/stimfit/*.so usr/bin/stimfit stimfit-0.16.7/dist/debian/stimfit.install0000664000175000017500000000060114755262551014214 usr/lib/stimfit/*.py usr/lib/stimfit/*.so usr/bin/stimfit usr/share/applications/stimfit.desktop usr/share/icons/hicolor/16x16/apps/stimfit.png usr/share/icons/hicolor/32x32/apps/stimfit.png usr/share/icons/hicolor/48x48/apps/stimfit.png usr/share/icons/hicolor/128x128/apps/stimfit.png usr/share/icons/hicolor/256x256/apps/stimfit.png usr/share/icons/hicolor/512x512/apps/stimfit.png stimfit-0.16.7/dist/debian/mkdeb.sh.in0000664000175000017500000000057514750344764013204 #! /bin/bash VERSION=@PACKAGE_VERSION@ make dist mkdir -p ../deb/ rm -rf ../deb/* cp -v stimfit-${VERSION}.tar.gz ../deb/ cp -v stimfit-${VERSION}.tar.gz ../deb/stimfit_${VERSION}.orig.tar.gz cd ../deb/ tar -xzf stimfit_${VERSION}.orig.tar.gz cd stimfit-${VERSION} cp -rv ../../../dist/debian ./ debuild -S -sa sudo pbuilder build --basetgz /var/cache/pbuilder/base.tgz ../*.dsc stimfit-0.16.7/dist/debian/docs0000664000175000017500000000002114750344764012016 NEWS README TODO stimfit-0.16.7/dist/debian/python3-stfio.install0000664000175000017500000000011414750344764015264 usr/lib/python*/*-packages/stfio/*.so usr/lib/python*/*-packages/stfio/*.py stimfit-0.16.7/dist/debian/stimfit.10000664000175000017500000000066614750344764012723 .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH STIMFIT "1" "February 2011" "stimfit 0.11.1" "User Commands" .SH NAME stimfit \- stimfit .SH SYNOPSIS .B stimfit [\fI-h\fR] [\fI--verbose\fR] [\fI-d \fR] [\fIFile to open\fR] .SH DESCRIPTION .TP \fB\-h\fR, \fB\-\-help\fR show this help message .TP \fB\-\-verbose\fR generate verbose log messages .TP \fB\-d\fR, \fB\-\-dir=\fR Working directory to change to stimfit-0.16.7/dist/debian/changelog0000664000175000017500000004767714764352347013052 stimfit (0.16.7-1) unstable; urgency=medium * Add build dependency on python3-setuptools (Closes: #1100323) * Drop menu entry in favour of desktop file -- Christoph Schmidt-Hieber Wed, 12 Mar 2025 18:39:07 +0000 stimfit (0.16.6-1) unstable; urgency=medium * Install icons into appropriate locations * Drop build dependency on sip -- Christoph Schmidt-Hieber Sun, 09 Feb 2025 21:17:35 +0000 stimfit (0.16.5-1) unstable; urgency=low * Update to latest NumPy C API * Fix debian building and packaging (Closes: #1068032) -- Christoph Schmidt-Hieber Fri, 07 Feb 2025 18:39:37 +0000 stimfit (0.16.4-1.1) unstable; urgency=medium * Non-maintainer upload. * use external libbiosig instead of internal (configure --with-biosig instead of --with-biosiglite) -- Alois Schloegl Thu, 15 Aug 2024 12:56:35 +1300 stimfit (0.16.4-1) unstable; urgency=medium * Non-maintainer upload. * uses Debian's libbiosig package to build stimfit Improves reading ATF, ABF2, AXG, and HEKA format, and provides advantages of dynamic linking * several minor bug fixes -- Alois Schloegl Fri, 05 Apr 2024 00:15:00 +0200 stimfit (0.16.0-1.2) unstable; urgency=medium * Non-maintainer upload. * Update to wxwidgets3.2. (Closes: #1019791) -- Olly Betts Thu, 05 Jan 2023 10:56:35 +1300 stimfit (0.16.0-1.1) unstable; urgency=medium * Non-maintainer upload. * Build-depend on python3-dev instead of python3-all-dev (Closes: #948020) * Patch: Avoid a deprecation warning breaking autoconf with Python 3.10. -- Stefano Rivera Thu, 24 Mar 2022 15:29:58 -0400 stimfit (0.16.0-1) unstable; urgency=low * Upgrade to Python 3 (Closes: #938572) -- Christoph Schmidt-Hieber Tue, 26 Nov 2019 09:35:41 +0200 stimfit (0.15.8-1) unstable; urgency=low * Address wx-gtk2 / wxpython-gtk3 incompatibility issue on bionic (LP: #1778433) -- Christoph Schmidt-Hieber Fri, 29 Jun 2018 09:18:39 +0200 stimfit (0.15.6-1) unstable; urgency=low * Adress shared library renaming error during debian packaging. (Closes: #896407) -- Christoph Schmidt-Hieber Tue, 24 Apr 2018 23:05:28 +0200 stimfit (0.15.5-1) unstable; urgency=low * Adds native intan CLP & tdms file reading * Upgrade libbiosiglite to 1.9.1 -- Christoph Schmidt-Hieber Mon, 12 Feb 2018 16:13:09 +0100 stimfit (0.15.4-1) unstable; urgency=low * Fix building with gcc-6 on armhf (Closes: #847526) * Add channel scrolling * Upgrade libbiosiglite to 1.8.4 -- Christoph Schmidt-Hieber Sat, 10 Dec 2016 16:55:51 +0000 stimfit (0.15.3-1) unstable; urgency=low * Fix building with gcc-6 (Closes: #811904) * Improve latency cursor Python interface -- Christoph Schmidt-Hieber Thu, 14 Jul 2016 10:49:03 +0100 stimfit (0.15.2-1) unstable; urgency=low * Fix RNG in tests with >= C++11 (Closes: #811904) * Use builtin biosig library -- Christoph Schmidt-Hieber Fri, 01 Apr 2016 10:29:55 +0100 stimfit (0.14.11-1) unstable; urgency=low * Improve usability of stfio_plot.Timeseries * Debian build fixes bug #804592 -- Christoph Schmidt-Hieber Wed, 18 Nov 2015 09:52:53 +0000 stimfit (0.14.10-1) experimental; urgency=low * Improve batch file conversion usability * Fix Debian dependencies -- Christoph Schmidt-Hieber Mon, 04 May 2015 04:20:24 +0100 stimfit (0.14.9-1) experimental; urgency=low * Fix several bugs during abf2 (pClamp10) file reading * Fix several issues during event detection -- Christoph Schmidt-Hieber Sun, 05 Apr 2015 12:33:50 +0100 stimfit (0.14.5-2) experimental; urgency=low * Fix several bugs during event detection * Fix several bugs during file reading (abf, axograph and hdf5) * Alternatively use wx 2.8 instead of wx 3.0 for Debian packages -- Christoph Schmidt-Hieber Mon, 03 Mar 2015 19:29:58 +0000 stimfit (0.13.19-1) unstable; urgency=low * Update to use wxWidgets 3.0 (Closes: #757289) -- Christoph Schmidt-Hieber Sat, 30 Aug 2014 14:40:04 +0000 stimfit (0.13.18-1) unstable; urgency=low * Support hdf5 1.8.13 new packaging layout (Closes: #756699) * Support dpkg-buildflags with --enable-module * Improved information/error messages -- Christoph Schmidt-Hieber Fri, 01 Aug 2014 10:57:51 +0000 stimfit (0.13.15-1) unstable; urgency=low * Fix half duration limits bug * Use neo's StimfitIO implementation * Address some lintian warnings -- Christoph Schmidt-Hieber Sun, 16 Feb 2014 12:48:51 +0000 stimfit (0.13.13-1) unstable; urgency=low * Import/Export from/to python-neo * Fix potential buffer overflows * Fix some bugs in Python code * Use libhdf5-dev instead of libhdf5-serial-dev dependency (Closes: #735157) * Use dh-autoreconf to fix FTBFS on ppc64el (Closes: #735231) * Distinguish only between Windows and non-Windows builds (implicitly posix) (Closes: #728094) -- Christoph Schmidt-Hieber Sun, 09 Feb 2014 10:56:06 +0000 stimfit (0.13.6-1) unstable; urgency=low * Export stfio recordings to pandas * Improved support for accessing date and time of recordings -- Christoph Schmidt-Hieber Wed, 11 Dec 2013 21:42:13 +0000 stimfit (0.13.5-1) unstable; urgency=low * New upstream release - Don't write test results to disk - Fall back to gcc/Unix for unknown platforms/compilers in axodefn.h (Closes: #728094) * Improved batch analysis * Multi-channel concatenation * Less disruptive warnings and error messages -- Christoph Schmidt-Hieber Sat, 30 Nov 2013 18:23:23 +0000 stimfit (0.13.2-1) unstable; urgency=low * New upstream release - Disambiguate template type in boost's reset (Closes: #720825) * Faster plotting * Add support for inner and outer rise time computations * Add option 'align to half-amplitude' when computing averages * Fix some potential buffer overflows * Improve biosig integration * Improve deconvolution-based event detection * Improve fit initialization for some functions -- Christoph Schmidt-Hieber Tue, 17 Sep 2013 16:47:30 +0000 stimfit (0.12.5-1) UNRELEASED; urgency=low * More robust initialization for nonlinear regression * Faster convergence for most fits * Add support for latest abf2 file format (Clampex 10.4) * Fix potential buffer overflow when computing averages -- Christoph Schmidt-Hieber Mon, 08 Jul 2013 19:55:04 +0000 stimfit (0.12.1-1) experimental; urgency=low * Use biosig as additional file reading backend -- Christoph Schmidt-Hieber Tue, 02 Apr 2013 21:22:06 +0000 stimfit (0.11.9-1) UNRELEASED; urgency=low * Fix latency measurements in manual peak mode * GUI adjustments * Build for Debian proper -- Christoph Schmidt-Hieber Fri, 29 Mar 2013 09:20:13 +0000 stimfit (0.11.8-0lucid1) lucid; urgency=low * Make objects iterable in pystfio * Prettify fit dialog -- Christoph Schmidt-Hieber Sun, 17 Feb 2013 13:02:28 +0000 stimfit (0.11.7-0lucid1) lucid; urgency=low * Add missing library to stfio debian package -- Christoph Schmidt-Hieber Sat, 16 Feb 2013 20:20:24 +0000 stimfit (0.11.6-0lucid1) lucid; urgency=low * Corrected some bugs in cursor dialogs -- Christoph Schmidt-Hieber Sat, 16 Feb 2013 14:30:00 +0000 stimfit (0.11.4-0precise1) precise; urgency=low * Fixed monoexponential fit with delay * Release hdf5 resources after reading / writing a file -- Christoph Schmidt-Hieber Fri, 20 Apr 2012 17:18:43 +0000 stimfit (0.11.1-1oneiric1) oneiric; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:41:23 +0000 stimfit (0.11.1-1natty1) natty; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:40:08 +0000 stimfit (0.11.1-1maverick1) maverick; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:39:02 +0000 stimfit (0.11.1-1lucid1) lucid; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:33:22 +0000 stimfit (0.11.0-1oneiric1) oneiric; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 15:50:54 +0000 stimfit (0.11.0-1natty1) natty; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 15:48:41 +0000 stimfit (0.11.0-1maverick1) maverick; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 15:42:22 +0000 stimfit (0.11.0-1lucid1) lucid; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 14:49:00 +0000 stimfit (0.10.18-2) UNRELEASED; urgency=low * Acknowledging previous NMU * Adjusted dh_python2 call to - invoke it only whenever it is present - do not carry hardcoded python version in X-Python-Version but rather specify current default using -V cmdline option * Use of DEB_BUILD_OPTIONS - Condition running tests on not having 'nocheck' - Rely on parallel= option to specify number of parallel builds, instead of hardcoded -j4 * Use of dh_numpy (if present) to specify numpy ABI dependency * Added ${python:Depends} to stimfit itself -- Yaroslav Halchenko Sun, 04 Mar 2012 17:03:34 -0500 stimfit (0.10.18-1.1) unstable; urgency=low * Non-maintainer upload. * Use dh_python2 to set proper dependencies for python-stfio. Note: this only happens for Python 2.7, building for all versions needs maintainer work and isn't suitable for NMU. Closes: #631983 -- Jonathan Wiltshire Sun, 04 Mar 2012 13:33:02 +0000 stimfit (0.10.18-1) unstable; urgency=low * Updated copyright notice for numpy.i -- Christoph Schmidt-Hieber Sat, 10 Sep 2011 15:46:33 +0000 stimfit (0.10.17-1oneiric1) oneiric; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 23:02:16 +0000 stimfit (0.10.17-1natty1) natty; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:55:12 +0000 stimfit (0.10.17-1maverick1) maverick; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:53:32 +0000 stimfit (0.10.17-1lucid2) lucid; urgency=low * Added source package -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:47:50 +0000 stimfit (0.10.17-1lucid1) lucid; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:38:59 +0000 stimfit (0.10.17-1) UNRELEASED; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 18:17:57 +0000 stimfit (0.10.16-1ubuntu3) natty; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 19:13:35 +0000 stimfit (0.10.16-1ubuntu2) maverick; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 19:10:52 +0000 stimfit (0.10.16-1ubuntu1) lucid; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 19:04:50 +0000 stimfit (0.10.16-1) UNRELEASED; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 16:59:56 +0000 stimfit (0.10.15-0ubuntu3) lucid; urgency=low * Igor file export -- Christoph Schmidt-Hieber Tue, 24 May 2011 23:42:50 +0000 stimfit (0.10.15-0ubuntu2) maverick; urgency=low * Igor file export -- Christoph Schmidt-Hieber Tue, 24 May 2011 22:36:01 +0000 stimfit (0.10.15-0ubuntu1) natty; urgency=low * Igor file export -- Christoph Schmidt-Hieber Tue, 24 May 2011 22:45:06 +0000 stimfit (0.10.14-0ubuntu1) lucid; urgency=low * Use unified menu on GTK to resolve problems with Unity and gnome-global-menu applet * Started support for viewing all channels -- Christoph Schmidt-Hieber Mon, 11 Apr 2011 14:56:55 +0000 stimfit (0.10.13-1ubuntu5) natty; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library * Reversioned because of source change -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 14:03:45 +0000 stimfit (0.10.13-1ubuntu4) maverick; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library * Reversioned because of source change -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 13:57:48 +0000 stimfit (0.10.13-1ubuntu3) natty; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 13:27:16 +0000 stimfit (0.10.13-1ubuntu2) maverick; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 13:21:56 +0000 stimfit (0.10.13-1ubuntu1) lucid; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 12:45:43 +0000 stimfit (0.10.13-1) unstable; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 12:33:21 +0000 stimfit (0.10.12-3) unstable; urgency=low * Fixed time stamp for Debian. -- Christoph Schmidt-Hieber Sat, 26 Feb 2011 12:27:04 +0000 stimfit (0.10.12-2) unstable; urgency=low * Fixed version number for Debian. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 21:10:56 +0000 stimfit (0.10.12-1) UNRELEASED; urgency=low * Fixed gtest build on sid. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 21:10:56 +0000 stimfit (0.10.12-1ubuntu1) natty; urgency=low * Fixed gtest build on natty. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 15:36:31 +0000 stimfit (0.10.11-1ubuntu5) natty; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:55:59 +0000 stimfit (0.10.11-1ubuntu4) maverick; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:39:29 +0000 stimfit (0.10.11-1ubuntu3) natty; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:08:14 +0000 stimfit (0.10.11-1ubuntu2) maverick; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:06:39 +0000 stimfit (0.10.11-1ubuntu1) lucid; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 13:53:47 +0000 stimfit (0.10.11-1) unstable; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Tue, 22 Feb 2011 20:12:18 +0000 stimfit (0.10.10-1ubuntu1) lucid; urgency=low * Failed upload required yet another reversioning... -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 18:11:03 +0000 stimfit (0.10.9-1ubuntu3) lucid; urgency=low * Failed upload required reversioning -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 17:54:56 +0000 stimfit (0.10.9-1ubuntu2) lucid; urgency=low * Moved Python files from dist-packages to private directory (/usr/lib/stimfit) to comply with debian packaging rules. * Minimal unit testing during build. -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 17:34:09 +0000 stimfit (0.10.9-1ubuntu1) maverick; urgency=low * Moved Python files from dist-packages to private directory (/usr/lib/stimfit) to comply with debian packaging rules. * Minimal unit testing during build. -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 17:31:57 +0000 stimfit (0.10.9-1) unstable; urgency=low * Moved Python files from dist-packages to private directory (/usr/lib/stimfit) to comply with debian packaging rules. * Minimal unit testing during build. * Initial Debian release (Closes: #612375) * Upload sponsored by Yaroslav Halchenko -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 16:23:29 +0000 stimfit (0.10.8-0ubuntu2) lucid; urgency=low * Increased matplotlib compatibility * Started to replace printing and graphics export functions using matplotlib as the backend -- Christoph Schmidt-Hieber Thu, 05 Feb 2011 19:44:35 +0000 stimfit (0.10.8-0ubuntu1) maverick; urgency=low * Increased matplotlib compatibility * Started to replace printing and graphics export functions using matplotlib as the backend -- Christoph Schmidt-Hieber Thu, 05 Feb 2011 19:19:41 +0000 stimfit (0.10.7-0ubuntu2) lucid; urgency=low * Fixed "Apply scaling to all windows" -- Christoph Schmidt-Hieber Mon, 31 Jan 2011 11:00:55 +0000 stimfit (0.10.7-0ubuntu1) maverick; urgency=low * Fixed "Apply scaling to all windows" -- Christoph Schmidt-Hieber Thu, 27 Jan 2011 17:12:21 +0000 stimfit (0.10.6-0ubuntu2) lucid; urgency=low * Fixed a bug when accessing files from the Python shell. -- Christoph Schmidt-Hieber Thu, 27 Jan 2011 17:12:21 +0000 stimfit (0.10.6-0ubuntu1) maverick; urgency=low * Fixed a bug when accessing files from the Python shell. -- Christoph Schmidt-Hieber Thu, 27 Jan 2011 17:12:21 +0000 stimfit (0.10.5-0ubuntu5) lucid; urgency=low * Reversioned for lucid. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 16:32:52 +0000 stimfit (0.10.5-0ubuntu4) lucid; urgency=low * Initial release for lucid (10.04). -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 16:24:41 +0000 stimfit (0.10.5-0ubuntu4) maverick; urgency=low * Added build-arch to debian rules. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 15:53:17 +0000 stimfit (0.10.5-0ubuntu3) maverick; urgency=low * Added source to upload. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 15:04:35 +0000 stimfit (0.10.5-0ubuntu2) maverick; urgency=low * Uploaded to wrong ppa. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 15:04:35 +0000 stimfit (0.10.5-0ubuntu1) maverick; urgency=low * Initial release. -- Christoph Schmidt-Hieber Sat, 22 Jan 2011 20:06:14 +0000 stimfit-0.16.7/dist/debian/mkquick.sh.in0000664000175000017500000000053214750344764013557 #! /bin/bash VERSION=@PACKAGE_VERSION@ make dist mkdir -p ../deb/ rm -rf ../deb/* cp -v stimfit-${VERSION}.tar.gz ../deb/ cp -v stimfit-${VERSION}.tar.gz ../deb/stimfit_${VERSION}.orig.tar.gz cd ../deb/ tar -xzf stimfit_${VERSION}.orig.tar.gz cd stimfit-${VERSION} mkdir -p debian cp -rv ../../../debian/* ./debian fakeroot debian/rules binary stimfit-0.16.7/dist/debian/control0000664000175000017500000000376214764351504012560 Source: stimfit Section: science Priority: optional Maintainer: Christoph Schmidt-Hieber Uploaders: Yaroslav Halchenko Build-Depends: debhelper (>= 10), dh-python, libbiosig-dev (>= 2.1.0), python3-dev, python3-numpy, python3-setuptools, libhdf5-dev, swig, python3-wxgtk4.0 (>= 4.0.7), libwxgtk3.2-dev, libfftw3-dev, liblapack-dev, chrpath, help2man, zlib1g-dev, pkgconf Standards-Version: 4.7.2 Homepage: http://www.stimfit.org Package: stimfit Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${python3:Depends}, libbiosig3, zlib1g-dev, python3-wxgtk4.0 (>= 4.0.7), python3-numpy, python3-matplotlib Recommends: python3-scipy Description: Program for viewing and analyzing electrophysiological data Stimfit is a free, fast and simple program for viewing and analyzing electrophysiological data. It features an embedded Python shell that allows you to extend the program functionality by using numerical libraries such as NumPy and SciPy. Package: stimfit-dbg Section: debug Priority: optional Architecture: any Depends: ${misc:Depends}, stimfit Recommends: python3-matplotlib, python3-scipy, python3-stfio Description: Debug symbols for stimfit Stimfit is a free, fast and simple program for viewing and analyzing electrophysiological data. It features an embedded Python shell that allows you to extend the program functionality by using numerical libraries such as NumPy and SciPy. This package contains the debug symbols for Stimfit. Package: python3-stfio Section: python Architecture: any Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends}, libbiosig3, zlib1g-dev, python3-numpy Provides: ${python3:Provides} Recommends: python3-matplotlib, python3-scipy, python3-pandas Description: Python module to read common electrophysiology file formats. The stfio module allows you to read common electrophysiology file formats from Python. Axon binaries (abf), Axon text (atf), HEKA (dat), CFS (dat/cfs), Axograph (axgd/axgx) are currently supported. stimfit-0.16.7/dist/debian/rules0000775000175000017500000000614114752314327012226 #!/usr/bin/make -f # Sample debian/rules that uses debhelper. # This file is public domain software, originally written by Joey Hess. # # This version is for packages that are architecture independent. # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 DEBPREFIX=$(CURDIR)/debian/tmp/usr PYVER := $(shell py3versions -vd) # Whenever libwxgtk3.0-gtk3-dev installed and wx-config present, need custom opts WXCONFIG_OPTS=$(shell wx-config --toolkit=gtk3 2>/dev/null 1>&2 && echo '--with-wx-config="wx-config --toolkit=gtk3"' || echo '') ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) MAKEFLAGS += -j$(NUMJOBS) endif ifneq ($(wildcard /usr/lib/$(DEB_HOST_MULTIARCH)/hdf5/serial/libhdf5.so),) export DEB_CPPFLAGS_MAINT_APPEND := -I/usr/include/hdf5/serial export DEB_LDFLAGS_MAINT_APPEND := -Wl,-L/usr/lib/$(DEB_HOST_MULTIARCH)/hdf5/serial endif build: build-arch build-indep build-arch: build-stamp build-indep: build-stamp build-stamp: dh_testdir clean: dh_testdir dh_testroot rm -f build-stamp # Add here commands to clean up after the build process. rm -rf ./.libs ./_libs ./.deps ./.stimfit rm -rf $(CURDIR)/man find -name '*.o' | xargs -r rm -f find -name '*.lo' | xargs -r rm -f find -name '*.a' | xargs -r rm -f find -name '*.la' | xargs -r rm -f find -name '*.so' | xargs -r rm -f rm -f $(CURDIR)/test.h5 dh_clean install: build PYTHON=/usr/bin/python$(PYVER) PYTHON_VERSION=$(PYVER) ./configure --enable-python --enable-debian --with-biosig --prefix=$(DEBPREFIX) $(WXCONFIG_OPTS) $(MAKE) ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) $(MAKE) check endif $(MAKE) install PYTHON=/usr/bin/python$(PYVER) PYTHON_VERSION=$(PYVER) ./configure --enable-module --enable-debian --with-biosig --prefix=$(DEBPREFIX) $(WXCONFIG_OPTS) $(MAKE) $(MAKE) install mkdir $(CURDIR)/man && \ cp ./debian/stimfit.1 ./man/stimfit.1 touch build-stamp dh_testroot # dh_prep dh_installdirs # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. binary-arch: build install dh_testdir dh_testroot dh_installchangelogs -X./ChangeLog dh_installdocs dh_installexamples dh_installmenu -pstimfit # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installcatalogs # dh_installpam dh_installmime -pstimfit # dh_installinit # dh_installcron # dh_installinfo # dh_installwm # dh_installudev dh_lintian # dh_bugfiles # dh_undocumented dh_python3 dh_installman $(CURDIR)/man/stimfit.1 dh_install --sourcedir=$(CURDIR)/debian/tmp dh_link dh_compress dh_strip --dbg-package=stimfit-dbg dh_fixperms dh_icons # dh_perl [ -x /usr/bin/dh_python3 ] && dh_python3 -V$(PYVER) --no-ext-rename || : [ -x /usr/bin/dh_numpy ] && dh_numpy || : dh_makeshlibs # https://stackoverflow.com/questions/11238134/dpkg-shlibdeps-error-no-dependency-information-found-for dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info dh_installdeb dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install stimfit-0.16.7/dist/debian/python3-stfio.lintian-overrides0000664000175000017500000000005214751351322017242 python3-stfio: custom-library-search-path stimfit-0.16.7/dist/debian/compat0000664000175000017500000000000314750344764012351 10 stimfit-0.16.7/dist/debian/copyright0000664000175000017500000001047614750344764013115 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: stimfit Upstream-Contact: Christoph Schmidt-Hieber Source: https://github.com/neurodroid/stimfit Files: * Copyright: 2011, Christoph Schmidt-Hieber License: GPL-2+ Files: src/libstfio/abf/axon/* Copyright: 1993-2000, Axon Instruments License: axon1 Files: src/libstfio/abf/axon2/* Copyright: 1993-2005, Molecular Devices 1993-2002, Axon Instruments License: axon2 Files: src/libstfio/intan/common.* Copyright: 2016, Intan Technologies License: GPL-3 Files: src/libstfio/intan/streams.* Copyright: 2016, Intan Technologies License: GPL-3 Files: src/libstfnum/levmar/* Copyright: 2004, Manolis Lourakis License: GPL-2+ Files: src/stimfit/py/numpy.i Copyright: 2005-2009, NumPy Developers License: BSD-new Files: src/test/gtest/* Copyright: 2008, Google Inc License: BSD-new License: axon1 Permission is granted to freely to use, modify and copy the code in this file. License: axon2 Permission is granted to freely to use, modify and copy the code in this file. License: GPL-2+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. License: GPL-3 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. . This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this package. If not, see . . On Debian systems, the full text of the GNU General Public License version 3 can be found in the file `/usr/share/common-licenses/GPL-3'. License: BSD-new 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 copyright holder 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. stimfit-0.16.7/dist/debian/mkdeb.sh0000664000175000017500000000056214764352426012572 #! /bin/bash VERSION=0.16.7 make dist mkdir -p ../deb/ rm -rf ../deb/* cp -v stimfit-${VERSION}.tar.gz ../deb/ cp -v stimfit-${VERSION}.tar.gz ../deb/stimfit_${VERSION}.orig.tar.gz cd ../deb/ tar -xzf stimfit_${VERSION}.orig.tar.gz cd stimfit-${VERSION} cp -rv ../../../dist/debian ./ debuild -S -sa sudo pbuilder build --basetgz /var/cache/pbuilder/base.tgz ../*.dsc stimfit-0.16.7/dist/debian/stimfit.desktop0000664000175000017500000000033414750344764014224 [Desktop Entry] Version=1.0 Type=Application Name=Stimfit GenericName=Stimfit Comment=View and analyze electrophysiology files TryExec=stimfit Exec=stimfit %F Icon=stimfit MimeType=application/x-foo; Categories=Science; stimfit-0.16.7/dist/conda/0000775000175000017500000000000014764352500011064 5stimfit-0.16.7/dist/conda/py-stfio/0000775000175000017500000000000014764352500012636 5stimfit-0.16.7/dist/conda/py-stfio/meta.yaml.in0000664000175000017500000000160414750344764015006 package: name: py-stfio version: "@PACKAGE_VERSION@" source: # Since this recipe is part of the git repo, the source is just a local path path: ../../.. patches: # Need to change the HDF5DIR, BIOSIGDIR, PYTHONDIR, BOOSTDIR, etc. user macros set in the config.vsprops files so that # the Conda package versions are used. Also, since conda builds in it's own build directory, the Boost directory needs # to be changed to an absolute path - vsprops.patch requirements: build: - hdf5-dll - biosig - fftw - clapack - python - numpy run: - python - numpy build: number: 0 about: home: https://github.com/neurodroid/stimfit license: GPL summary: "The stfio Python module allows to read and write data in common electrophysiology formats without running Stimfit." stimfit-0.16.7/dist/conda/py-stfio-debug/0000775000175000017500000000000014764352500013722 5stimfit-0.16.7/dist/conda/py-stfio-debug/meta.yaml.in0000664000175000017500000000161214750344764016071 package: name: py-stfio-debug version: "@PACKAGE_VERSION@" source: # Since this recipe is part of the git repo, the source is just a local path path: ../../.. patches: # Need to change the HDF5DIR, BIOSIGDIR, PYTHONDIR, BOOSTDIR, etc. user macros set in the config.vsprops files so that # the Conda package versions are used. Also, since conda builds in it's own build directory, the Boost directory needs # to be changed to an absolute path - vsprops.patch requirements: build: - hdf5-dll - biosig - fftw - clapack - python - numpy run: - python - numpy build: number: 0 about: home: https://github.com/neurodroid/stimfit license: GPL summary: "The stfio Python module allows to read and write data in common electrophysiology formats without running Stimfit." stimfit-0.16.7/dist/macosx/0000775000175000017500000000000014764352500011272 5stimfit-0.16.7/dist/macosx/app.r0000664000175000017500000054003214750344764012171 data 'icns' (-16455) { $"6963 6E73 0000 FFFB 6838 6D6B 0000 0908" $"0000 0054 AFAD A69F 9891 8B84 7D76 6F69" $"625B 544D 4740 3932 2B17 0000 0001 0100" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0027 BFF9 F5F7 F7F8 F8F9 F9F9 F9FA FAFA" $"FAFA FBFB FAF9 F8F8 F9F5 98B3 D7F5 F4EE" $"E9E2 DBD4 CDC6 BFB9 B2AB A39C 948D 3400" $"009A FAEF DFE3 E4E4 E4E4 E4E4 E4E4 E3E3" $"E3E3 E2E8 F3F3 FDFE FDFE F6F3 F1EA EAEA" $"EBEB ECEC EDF2 F1F0 EFEF EEEE EEEE 9300" $"008D FAF0 DEE1 E2E2 E2E2 E2E1 E1E1 E0E0" $"DFDF DFE4 F3F4 FEFE FDFE F4EF ECE2 E1E1" $"E1E1 E2E1 E1EC EDED EDED EEEE EEEE 8600" $"007C FAF2 DDE0 E0E0 E0E0 E0E0 E0E0 DFDF" $"DFDF DEE4 F3F3 FEFE FDFE F4EF ECE1 E1E1" $"E1E1 E2E1 E1EC EDED EDED EEEE EEEE 7800" $"006A FAF3 DDDF DFDF DFDF DFDF DFDF DFDF" $"DEDE DEE3 F2F3 FEFE FDFE F4EF ECE1 E1E1" $"E1E1 E1E1 E2ED EDED EDED EEEE EEEE 6A00" $"0059 FBF5 DDDE DEDE DEDE DEDE DEDE DEDE" $"DDDD DDE2 F2F3 FDFD FDFD F4EF ECE0 E0E0" $"E0E0 E1E1 E2EC ECEC ECED EDED EDED 5C00" $"0047 FBF6 DEDD DDDE DEDE DEDD DEDE DEDE" $"DEDE DDE2 F2F3 FEFE FDFE F4EF ECE0 E0E1" $"E1E1 E1E1 E2ED EDED EDED EEEE EEEE 4F00" $"0036 FBF7 DFDC DDDD DDDD DDDD DDDD DDDD" $"DDDD DDE1 F2F2 FEFE FDFE F4EF ECDF E0E1" $"E1E1 E1E1 E3ED EDED EDED EEEE EEEE 4100" $"0024 FBF8 DFDC DCDC DDDD DDDC DDDD DDDD" $"DDDD DCE1 F1F2 FEFE FDFE F4EF ECDF E0E0" $"E1E1 E1E1 E3ED EDED EDED EEEE EEEE 3300" $"0013 FBF9 E1DB DCDC DCDC DCDC DCDD DDDD" $"DDDD DCE0 F1F2 FEFE FDFE F4EF EBDF E0E0" $"E1E1 E1E1 E3ED EDED EDED EEEE EEEE 2500" $"0005 F8F9 E2DB DCDC DCDC DCDB DCDC DCDC" $"DDDD DCE0 F1F2 FDFE FDFE F4EF EBDF E0E0" $"E1E1 E1E1 E4ED EDED EDED EEEE EEEE 1600" $"0000 EBF9 E4DB DBDB DBDB DBDB DBDB DBDC" $"DCDC DCE0 F1F2 FDFD FDFD F3EF EBDF DFE0" $"E0E0 E1E1 E4EC ECEC EDED EDED EDEE 0800" $"0000 DBF9 E6DA DBDB DBDC DCDB DCDC DCDC" $"DCDD DCDF F1F2 FDFE FDFE F3EF EBDE E0E0" $"E1E1 E2E1 E5ED EDED EDED EEEE EEE7 0200" $"0000 C9FA E8DB DBDB DBDB DCDB DCDC DCDC" $"DCDD DCDF F1F2 FDFE FDFE F4EF EBDE E0E1" $"E1E1 E2E1 E5ED EDED EDED EEEE EEDC 0000" $"0000 B8FA EADB DBDB DBDB DCDB DCDC DCDC" $"DCDD DCDF F1F2 FDFE FDFE F4F0 EBDE E0E1" $"E1E1 E2E1 E6ED EDED EEED EEEE EECE 0000" $"0000 A7FA ECDB DBDB DBDB DCDB DCDC DCDC" $"DCDD DCDF F1F2 FDFE FDFE F4F0 EBDF E0E1" $"E1E1 E2E1 E6ED EDED EEED EEEE EEC0 0000" $"0000 95FA EEDB DBDB DBDB DCDB DCDC DCDC" $"DDDD DCDE F1F2 FDFE FDFE F4F0 EBDF E0E1" $"E1E2 E2E2 E7ED EDED EEED EEEE EEB2 0000" $"0000 84FA EFDB DADA DBDB DBDB DBDB DBDC" $"DCDD DDDF F1F2 FCFD FDFD F6F3 F1EA EDEE" $"F0F2 F3F4 F5F2 EFEE EDED EDEE EEA4 0000" $"0000 72FB F1DC DBDC DDDE DFE1 E3E5 E7E9" $"EBED EFF1 F2F1 F4F9 FDFE FCFB FAF7 F8F8" $"F8F8 F8F8 F8F8 F8F7 F4F1 EFEE EE96 0000" $"0000 24F5 F9F0 F1F3 F4F5 F6F6 F6F6 F7F7" $"F7F7 F6F7 F6F5 F2F2 F3F8 F9FC FBFA FAFB" $"FBFC FCFD FDFB FAF9 F9F9 F6E0 C64E 0000" $"0000 0081 FCF7 F7F7 F7F7 F7F7 F7F8 F9F9" $"FAFA FBFB F8F7 F9FB FCFD FAFA FDFD FEFD" $"FDFD FCFB FBFC FCFB BC51 0500 0000 0000" $"0000 055F F8FB FBFB FCFD FDFD FEFE FEFE" $"FEFE FDFE FDFB EFFB F9F8 F7F7 F7F8 F7F7" $"F7F7 F7F7 F7FA FAFA FAFA DE8D 3A02 0000" $"0000 4EF7 F9FD FDFD FDFD FDFC FBFB FAF9" $"F9F8 F7F7 FBFB F9F6 F2F1 F1F3 F5F5 F5F5" $"F5F6 F6F6 F6F8 F8F7 F7F6 F5F4 F3D2 0E00" $"0000 45F8 F5F7 F8F7 F6F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 FAFB FCFD FAF3 F0EF F0F2 F2F0" $"EFED EBEA E8EF EEEE EEEE EEEE EEEF 1A00" $"0000 34FA F5F4 F4F4 F4F4 F4F4 F4F4 F4F3" $"F2F1 EFEE F7F7 FAFE FDFD F1F0 EFE6 E4E3" $"E3E3 E3E3 E4ED EEEE EEEE EFEF EFEF 0B00" $"0000 22FB F6F3 F2F1 EFEE ECE9 E8E6 E4E1" $"E0DF DFE0 F2F3 F8FE FDFE F2F0 EFE4 E1E2" $"E2E3 E3E3 E5EE EEEE EEEE EFEF EFE9 0300" $"0000 10FB F7E5 E2E2 E1E1 E0DF DEDD DDDD" $"DEDE DEE0 F2F3 F8FE FDFE F2F0 F0E4 E1E2" $"E3E3 E3E3 E5EE EEEE EEEE EFEF EFDE 0000" $"0000 05F5 F8E1 DCDD DDDD DDDD DDDE DEDE" $"DEDE DEDF F1F3 F8FE FDFE F2F0 F0E4 E1E2" $"E3E3 E4E3 E6EE EEEE EFEE EFEF EFD0 0000" $"0000 00E9 F9E2 DCDC DCDC DDDD DDDD DDDE" $"DEDE DEDF F1F3 F8FD FDFD F2F0 F0E4 E2E2" $"E2E3 E3E3 E6ED EDEE EEEE EEEF EFC2 0000" $"0000 00D8 F9E4 DDDD DDDD DEDD DEDE DEDE" $"DFDF DFE0 F1F3 F8FE FDFE F3F1 F0E4 E2E3" $"E3E4 E4E4 E7EE EEEE EFEE EFEF F0B3 0000" $"0000 00C6 FAE6 DDDD DEDE DEDD DEDE DEDF" $"DFDF DFE0 F1F3 F8FE FDFE F3F1 F0E4 E2E3" $"E3E4 E4E4 E8EE EEEF EFEE EFEF F0A4 0000" $"0000 00B5 FAE8 DDDE DEDE DEDE DEDF DFDF" $"DFDF DFE0 F1F3 F8FE FDFE F2F1 F0E4 E2E3" $"E4E4 E4E4 E8EE EEEF EFEE EFF0 F096 0000" $"0000 00A4 FAEA DEDE DEDE DEDE DFDF DFDF" $"DFE0 DFE0 F0F3 F8FE FDFE F3F1 F0E4 E3E4" $"E4E4 E5E4 E8EE EFEF EFEF EFF0 F087 0000" $"0000 0092 FAEC DEDE DEDE DFDE DFDF DFDF" $"E0E0 E0E0 F0F3 F7FE FDFE F3F1 F0E4 E3E3" $"E3E4 E6E8 EBEE EFEF EFEF F0F0 F078 0000" $"0000 0081 FBED DEDE DFDF DFDE DFDF E0E0" $"E0E0 E0E1 F0F3 F7FE FDFE F3F1 F1E7 E9EC" $"EEF0 F1F1 F1EE EDEE EFEF F0F0 F06A 0000" $"0000 006F FBEF DFDE DEDE DFDF DFDF DFDF" $"DFE0 E0E1 F0F3 F6FD FDFD F8F7 F7F1 F0F1" $"F1F1 F1F1 F1F1 F0ED EFEF EFEF F05C 0000" $"0000 005D FBF1 DFDF DEDE DFDF DFE0 E3E6" $"E9EB EEEF EEF2 F4F8 FDFE F9F8 F7F1 F1F2" $"F2F2 F2F1 F2F2 F3F2 EFEE EFF0 F04D 0000" $"0000 004C FBF2 DFE0 E2E5 E8EB EDEF EFF0" $"F0F0 EFF0 EFEF F3F4 F9FE F9F8 F7F1 F1F2" $"F2F2 F2F2 F2F3 F3F3 F2F1 EEF0 F13F 0000" $"0000 0021 FCF8 EEEE EFEF EFEF F0F0 F0F0" $"F0F0 EFF0 F0EF EFF3 F5FA F9F8 F7F1 F1F2" $"F2F2 F2F2 F3F3 F3F3 F3F3 F3EF EF2F 0000" $"0000 0000 D4FA F0EF EFEF F0EF F0F0 F0F0" $"F0F0 EFF0 F0F1 EFF0 F4F5 AEF9 F8F1 F2F2" $"F2F2 F3F2 F3F3 F3F3 F3F4 E9B8 7D06 0000" $"0000 0000 8AFA F0F0 F0F0 F0EF F0F0 F0F0" $"F0F0 F0F0 F1F1 F1EF F1F5 17AC F8F2 F2F2" $"F2F3 F3F2 F3F0 C894 602C 0200 0000 0000" $"0000 0000 40FB F1EF EFEF EFEF EFEF EFEF" $"F0F0 F0F0 F0F0 F0F0 EFF3 1207 B8F2 F1F2" $"F2D9 A571 3D0C 0000 0000 0000 0000 0000" $"0000 0000 06ED F1F0 F0F0 F0EF F0F0 F0F0" $"F0F1 F0F1 F1F1 F1F1 F1C8 0500 0C92 824D" $"1A00 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 00AA F2F0 F0F0 F0EF F0F0 F0F1" $"F1F1 F1F1 E3B2 814D 1B00 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0061 F3F0 F0F0 F0F0 F0F1 F1EA" $"BF8C 5A26 0200 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0019 F3F0 F0F0 EFCB 9866 3207" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 87A4 713F 0E00 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"4943 4E23 0000 0108 FFFF FFFF DDDD 5555" $"FFFF AAAB F777 5555 FFFF AAAB DFDF 5555" $"FFFF AAAB F777 5555 FFFF AAAB DDDD 5555" $"FFFF AAAB F777 5555 FFFF AAAB DFDF 5555" $"FFFF AAAB F777 5555 8000 FFFF D555 5555" $"A222 FFFF D555 5555 8808 FFFF D555 5555" $"A222 FFFF D555 5555 8000 FFFF D555 5555" $"A222 FFFF D555 5555 8808 FFFF D555 5555" $"A222 FFFF FFFF FFFF 0000 0000 7FFF FFFE" $"7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE" $"7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE" $"7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE" $"7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE" $"7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE" $"7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE" $"7FFF FFFE 7FFF FFFE 7FFF FFFE 7FFF FFFE" $"7FFF FFFE 0000 0000 6968 3332 0000 1780" $"0900 284B 87E4 F1F1 F0F1 F281 F180 F024" $"EEEE EFED EBED EDDC D78E 383F 4147 534C" $"3946 4733 3A41 352D 3835 212C 3225 011A" $"341F 4FE9 FE82 FF00 FE80 FF81 FE22 FFFE" $"FEFC F9F6 EF60 2B29 6662 6055 5457 524D" $"5256 4A50 564E 4E57 5754 2318 1C03 41E1" $"FE82 FF00 FE83 FF13 FEFE FBF1 DFD8 D2CC" $"3F16 1E8B 7269 615C 5754 524B 844A 0849" $"5229 1F15 0037 DBFE 82FF 00FE 83FF 18FE" $"FDF1 E8D7 D2CE C93F 1822 8C73 6C66 615D" $"5B5A 4D4C 4B4B 4A4A 8049 0751 2F16 1700" $"2DD4 FE82 FF00 FE83 FF23 FEFB E9E2 D3CF" $"CBC7 3F18 2287 6E68 635F 5C5A 594C 4C4B" $"4B4A 4A49 4948 5423 131E 0024 CDFE 82FF" $"00FE 83FF 16FE F8E3 DDCF CBC9 C63E 1822" $"806A 6560 5D5B 5958 4C4B 4B4A 8149 0748" $"5122 0D22 001B C48A FE18 FCF2 DED9 CBC8" $"C6C3 3E18 2277 6662 5E5C 5958 574B 4B4A" $"4A49 4980 4807 531E 022E 0013 BBFE 82FF" $"00FE 80FF 16FE FEFA F6ED D9D5 C8C5 C3C2" $"3E18 226F 635F 5C5A 5857 564B 804A 0149" $"4980 4807 5812 0031 000C B1FE 82FF 19FE" $"FFFE FEFB F7F3 F0E8 D5D2 C4C2 C1C0 3D18" $"2268 605D 5B59 5756 5580 4A01 4949 8048" $"0847 560E 0030 0007 A6FC 82FE 1DFD FCFA" $"F7F4 F1EE EBE4 D1CF C1C0 C0BF 3D18 2363" $"5D5B 5958 5756 544A 4A49 4980 480A 4747" $"6002 0030 0004 9AF3 F780 F81B F7F5 F4F2" $"F0ED EBE9 E7E1 CECD BFBF BEBE 3C17 235E" $"5B59 5857 5655 534A 8049 1C48 4847 4746" $"5C00 002F 0302 8EEA EFEF F0F0 EFEE EDEB" $"EAE8 E6E5 E3DF CCCA 81BD 0A3C 1723 5B59" $"5857 5655 5552 8049 0048 8147 0946 5800" $"0028 0801 82E2 E881 E919 E8E7 E6E5 E4E2" $"E1E0 DCC9 C8BC BBBB BC3A 1723 5858 5756" $"5554 5451 8048 8047 0B46 4645 5600 0022" $"0E01 76DC E282 E309 E2E2 E1E0 DFDE DEDA" $"C8C7 80BA 07BB 3A17 2356 5756 5580 5400" $"5080 4880 470C 4646 4A4B 0000 230E 0169" $"D6DE DE82 DF08 DEDE DDDC DCDB D9C5 C480" $"B90F BA39 1623 5456 5554 5453 534F 4848" $"4747 8046 0A45 4848 0000 220D 005E D1DA" $"85DB 80DA 03D9 D7C4 C380 B807 B939 1623" $"5355 5454 8053 014E 4880 470D 4646 4545" $"4B41 0000 2211 0052 CDD7 80D8 81D9 82D8" $"02D6 C2C2 80B7 0DB8 3816 2351 5454 5353" $"5252 4E47 4780 4680 4508 4C3B 0000 1B13" $"0047 C880 D587 D602 D5C1 C180 B60C B737" $"1523 5153 5352 5251 514C 4780 4680 450C" $"444A 3C00 001A 1900 3DC4 D2D3 D381 D483" $"D502 D3C0 C080 B50D B635 121D 4546 4443" $"4140 3E3E 4143 8045 8044 084D 3400 0017" $"1900 33BF 80D0 14CF CECD CBCA C8C6 C5C3" $"C1BF BEBF BDB8 B4B4 2E09 1537 833B 803A" $"023B 3E41 8043 104C 2F00 000C 2502 24A7" $"B8B7 B6B6 B5B5 B6B6 80B7 80B8 10B9 BABD" $"BEBD B82E 0713 3438 3737 3636 3535 8036" $"0633 2F2E 3538 4C2D 8000 0623 141A 9BB1" $"B2B2 85B3 24B2 B2B3 B6B7 B6B4 B3B1 2602" $"0B2A 2B27 221E 1915 100B 0705 2132 4352" $"5630 0700 0002 3E1C 1693 82AB 80AC 10AB" $"A9A5 9F97 8C7F 726B 554E 4107 0303 0404" $"8003 4704 060A 0D13 191E 2437 4B5B 683E" $"0000 0534 030C 7E99 9187 7A6C 5E4F 4033" $"261B 110A 0600 0004 0C15 232A 1B17 1D23" $"292F 353B 3E40 3E40 4245 484B 4E51 5B69" $"0000 032B 0205 1012 0C08 0681 0520 070C" $"1829 3B4C 596B 7C8D 7C2A 1A2B 3C45 4B4E" $"5257 5C60 615A 5957 5553 5150 4E4D 6380" $"0024 3301 060C 1828 3A4B 5E70 8395 A7B6" $"C1CA D1D8 D6DC DDDD DFCF 1C19 2059 8373" $"6D65 5F5B 594F 4F80 4E04 4D4D 4C4B 5C80" $"001E 3000 35A3 BAC3 CAD2 DAE2 E9F1 F7F9" $"F8F4 F0EB D5D1 C8C0 BFBC 2019 1B44 5B5A" $"5A80 5901 574F 804E 054D 4D4C 4C4F 5380" $"000C 2F00 18C7 F8F6 F3EF EBE7 E3DF DC81" $"DB0B DAC8 C7C2 BDBD BB20 181A 445A 8059" $"0658 5856 4E4E 4D4D 804C 024B 4E4F 8000" $"0329 0608 AA80 D601 D7D7 80D8 81D9 0DDA" $"D9C7 C6C1 BBBC BA1F 181A 4459 5981 5800" $"5580 4D80 4C03 4B4B 5143 8000 0629 0804" $"9FD4 D5D5 80D6 80D7 82D8 09C5 C4BF BABA" $"B91F 1719 4480 5880 5701 544D 804C 054B" $"4B4A 4A50 3E80 0004 250B 0293 D380 D480" $"D580 D680 D70B D6C4 C3BE B9B9 B71E 1719" $"4458 8057 0256 5653 804C 064B 4B4A 4A49" $"4F3E 8000 0720 1001 85D1 D2D3 D381 D483" $"D50B C3C1 BDB8 B8B6 1D16 1944 5757 8156" $"0352 4C4B 4B80 4A03 4949 5134 8000 0821" $"1100 78CF D1D1 D2D2 81D3 82D4 09C2 C0BC" $"B6B6 B41C 1618 4480 5680 550A 514B 4B4A" $"4A49 4948 4851 2F80 0006 200F 006C CDD0" $"D081 D182 D20C D3D2 C1BF BBB5 B5B3 1C15" $"1844 5680 5502 5454 5080 4A06 4949 4848" $"474F 2E80 0007 1E12 005F CACE CFCF 81D0" $"83D1 09C0 BEB9 B4B4 B21B 1517 4480 5506" $"5452 504D 4A49 4980 4803 4747 5225 8000" $"0518 1800 53C7 CD81 CE83 CF1C D0CF BFBC" $"B8B2 B2B0 1B14 1641 4E4C 4947 4746 4649" $"4A48 4847 4746 4653 1E80 0004 151C 0048" $"C480 CC81 CD80 CE0C CFCE CDBE BBB8 B1B1" $"AF16 0F10 3782 4680 4508 4649 4847 4646" $"4551 1D80 0007 0E21 003D C0CA CBCB 80CC" $"12CB C9C6 C4C1 BFBD BEBB B9B5 AFAD 150E" $"1037 4646 8145 8144 0647 4746 4545 5514" $"8000 0A05 2600 33BC C8C6 C3C1 BEBC 84BB" $"09BC BDB9 B8B3 AC14 0D0F 3781 4580 4480" $"4306 4244 4645 445A 0881 0005 2E00 25A9" $"B7B7 80B8 81B9 83BA 07BB B6B6 AE13 0D0F" $"3782 4480 4380 4205 4141 4445 5D04 8100" $"0328 0B1C A380 B680 B786 B809 B9B9 B4B1" $"3A0C 0E37 4444 8043 8142 0641 413E 3E40" $"4866 8200 0421 1314 9DB4 80B5 82B6 84B7" $"06B8 B6AF 7417 0E37 8043 8042 0940 3D42" $"4145 534C 3A2C 1282 0005 0E23 0D97 B3B3" $"81B4 88B5 11B6 B091 3715 3642 423E 4041" $"4550 5640 3321 0587 0002 2F0F 9080 B283" $"B382 B40F B3B3 B1A6 A28C 093D 3741 4854" $"4235 280E 8C00 0328 1488 B081 B183 B20E" $"B1A8 9A92 867E 7A65 3900 1019 1F17 0190" $"0002 1722 7D80 AF81 B00A AA9A 9489 7E7C" $"694C 3316 0198 000F 0246 72AD AEAA 9B93" $"897D 7A6E 5139 1F05 9E00 0942 7088 7D7A" $"7558 3D27 079E 0055 0023 372D 2D34 3727" $"2E36 2A2B 3531 2934 3A28 3442 3334 4B4C" $"3342 5154 6B90 A3A6 A38E 8F8F 7C79 7A70" $"6365 634C 4F50 4002 1929 110C 89E9 E9E6" $"E2DE D5CC C4B9 ACA2 9487 7866 574B 4139" $"322C 5264 69D3 F0EF ECEA E8E5 E3E3 7FE2" $"DFE0 E0DD DBDB D9D3 4317 1400 1276 CDD1" $"D3D2 CFC9 C0B6 AB9E 9285 796D 5D49 4031" $"2B26 2029 3348 D8FA F2EA E4DF DCD9 D1D0" $"CECD CDCC CBCB CAC6 461F 1400 1064 B5B8" $"BAB9 B6B1 ABA3 998F 857A 7067 5842 3A2B" $"2723 1E27 3248 D8F6 EEE7 E2DE DBDA CDCC" $"CBCA CAC9 C8C7 C6C0 4716 1700 0D55 A0A2" $"A3A3 A19D 9790 8980 786F 675F 523D 367F" $"2824 211D 2731 48D8 F0E9 E4E0 DCDA D9CC" $"CBCA CAC9 C8C7 C6C5 C036 131E 000B 4A8D" $"8F90 908E 8B86 817A 736C 655E 584D 3832" $"2522 1F1C 2631 48D7 EBE5 E1DD DAD8 D7CB" $"CACA C9C8 C7C7 C5C4 BD2F 0D22 0008 407D" $"7F80 807E 7B77 736E 6862 5D57 5248 342F" $"221F 1E1B 2630 49D6 E6E1 DEDB D9D7 D5CA" $"C9C9 C8C7 C7C5 C4C3 BC26 022E 0006 3970" $"8072 2C70 6E6B 6763 5F5A 5551 4C44 302C" $"1F1E 1C1A 2530 49D5 E2DE DBD9 D7D5 D4C9" $"C8C8 C7C6 C5C4 C3C3 BB16 0031 0004 3465" $"8066 0C65 6361 5E5A 5753 4F4B 4840 2D2A" $"7F1E 1C1B 1A25 2F49 D3DE DBD8 D7D5 D4D2" $"C8C7 C7C6 C5C4 C3C2 C2B8 0F00 3000 032F" $"5B5C 5D5C 5C5A 5856 5350 4D4A 4744 3E2B" $"281C 1B1A 1925 2F49 D1DA D8D6 D5D4 D3D1" $"C7C6 C5C4 C3C3 C2C1 C1B9 0200 3000 022C" $"5255 5554 5453 514F 4D4B 4846 4341 3C29" $"271A 1A19 1824 2E4A CDD7 D6D4 D3D2 D1CF" $"C5C4 C4C3 C2C2 C1C0 C0AC 0000 2F03 0128" $"4B80 4E2C 4D4C 4B4A 4846 4442 403F 3A27" $"2519 1918 1824 2D4A C9D5 D4D2 D2D1 D0CD" $"C4C3 C3C2 C1C1 C0BF BEA4 0000 2808 0125" $"4680 492C 4848 4745 4443 4140 3E3D 3825" $"2419 1818 1723 2D4A C6D3 D2D1 D0CF CFCC" $"C3C2 C2C1 C0C0 BFBE BB9B 0000 220E 0121" $"4180 452C 4444 4342 4140 3E3D 3C3B 3724" $"2318 1817 1723 2C4A C3D1 D0CF CFCE CECA" $"C1C1 C0C0 BFBF BEBD BB8C 0000 230E 011E" $"3E81 410B 4040 3F3E 3D3C 3B3B 3A36 2422" $"8117 0622 2B4A C1CF CECE 80CD 11C8 C0C0" $"BFBF BEBD BDBC B884 0000 220D 001B 3B80" $"3F16 3E3E 3D3D 3C3B 3B3A 3939 3623 2217" $"1716 1721 2A4A BFCD CD81 CC13 C7BF BFBE" $"BEBD BCBC BBB8 7800 0022 1100 1839 3D3D" $"813C 0A3B 3B3A 3939 3838 3523 2117 8016" $"0421 294A BECC 80CB 13CA CBC5 BEBD BDBC" $"BCBB BAB9 B76A 0000 1B13 0015 3781 3B80" $"3A08 3939 3838 3737 3522 2181 1603 2028" $"4ABC 80CA 16C9 C9C8 C3BD BCBC BBBB BAB9" $"B8B5 6500 001A 1900 1236 3A3A 8239 8038" $"3E37 3736 3422 2117 1515 161D 2444 B0BC" $"BAB8 B7B5 B4B4 B6B9 BABA B9B9 B8B7 B556" $"0000 1719 000F 3438 3736 3634 3331 2E2C" $"2A28 2624 2220 211F 1A16 1517 1B3B A2AF" $"80B0 82AF 02B0 B2B4 80B6 0EB2 4B00 000C" $"2502 0720 2220 1F1E 1D1D 861C 081D 2021" $"1F1A 1519 3A9E 80AB 0DAA AAA9 A8A8 A6A2" $"998E 8383 8096 4080 0003 2314 0318 801C" $"811B 2C1A 1A19 1818 1717 1A1B 1917 1615" $"0607 2787 8B7E 7061 5142 3425 190F 293F" $"4B57 5E3A 0800 0002 3E1C 0614 1616 1515" $"8314 0F13 1311 100E 0F15 0B0C 0A04 0304" $"0906 0481 0301 0401 8002 3B03 0F1B 2C3F" $"2B00 0005 3403 030F 1211 0F0D 0C0B 0908" $"0706 0504 0303 0000 0306 0B0E 0E09 0707" $"0809 090A 0A0B 0A06 0708 090A 0B0D 0E1A" $"3E00 0003 2B02 0580 0483 0516 070C 1829" $"3B4C 596B 7C8D 7A22 0D10 100F 0F11 1316" $"191B 1C80 1482 1301 123C 8000 2233 0106" $"0C18 283A 4B5E 7083 95A7 B6C1 CAD1 D8D6" $"DCDD DDDF CE12 0E0F 2C43 302B 2621 1E1C" $"8113 0012 8013 0111 3B80 001D 3000 35A3" $"BAC3 CAD2 DAE2 E9F1 F7F9 F8F4 F0EB D5D1" $"C8C0 BEBC 170D 0E1C 1F1F 801E 011D 1C81" $"1300 1280 1301 1832 8000 0C2F 0018 C7F8" $"F6F3 EFEB E7E3 DFDC 81DB 11DA C8C7 C2BC" $"BDBB 170D 0E1C 1F1F 1E1E 1D1D 1B81 1300" $"1280 1301 1831 8000 0329 0608 AA80 D601" $"D7D7 80D8 81D9 0CDA D9C7 C6C1 BBBB B917" $"0D0E 1B1F 801E 021D 1D1A 8113 0512 1313" $"121C 2880 0006 2908 049F D4D5 D580 D680" $"D782 D80B C5C4 BFBA BAB8 170D 0E1B 1F1E" $"811D 001A 8512 011C 2780 0004 250B 0293" $"D380 D480 D580 D680 D70C D6C4 C3BE B9B9" $"B716 0D0E 1B1E 1E81 1D00 1981 1305 1213" $"1212 1B2A 8000 0720 1001 85D1 D2D3 D381" $"D483 D50A C3C1 BDB7 B8B6 160D 0E1B 1E80" $"1D02 1C1C 1981 1381 1201 1E23 8000 0821" $"1100 78CF D1D1 D2D2 81D3 82D4 0AC2 C0BC" $"B6B6 B415 0D0E 1B1E 801D 021C 1C18 8113" $"8112 011F 2180 0006 200F 006C CDD0 D081" $"D182 D20B D3D2 C1BF BBB5 B5B3 150D 0D1B" $"801D 801C 0018 8113 8112 011E 2380 0007" $"1E12 005F CACE CFCF 81D0 83D1 09C0 BEB9" $"B3B4 B114 0C0D 1B80 1D03 1C1A 1815 8013" $"0612 1112 1211 221D 8000 0518 1800 53C7" $"CD81 CE83 CF1C D0CF BFBC B8B2 B2B0 150C" $"0C18 1715 1210 100F 1012 1312 1211 1212" $"1124 1980 0004 151C 0048 C480 CC81 CD80" $"CE0E CFCE CDBE BBB8 B1B1 AE0D 0304 0E10" $"1083 0F02 1013 1281 1101 241A 8000 070E" $"2100 3DC0 CACB CB80 CC10 CBC9 C6C4 C1BF" $"BDBE BBB9 B5AF AD0C 0303 0E81 1083 0F01" $"1212 8011 012A 1280 000A 0526 0033 BCC8" $"C6C3 C1BE BC84 BB09 BCBD B9B8 B2AB 0B03" $"030E 8010 020F 0F0E 800F 070E 0E10 1211" $"1032 0881 0005 2E00 25A9 B7B7 80B8 81B9" $"83BA 08BB B6B6 AE0B 0203 0E10 810F 020E" $"0F0F 800E 050D 0E11 1238 0481 0003 280B" $"1CA3 80B6 80B7 86B8 07B9 B9B4 B135 0203" $"0E82 0F82 0E05 0D0D 131A 264C 8200 0421" $"1314 9DB4 80B5 82B6 84B7 06B8 B6AF 720F" $"030E 820F 0A0E 0E0F 1A1E 293F 3D30 2811" $"8200 050E 230D 97B3 B381 B488 B511 B6B0" $"9133 0C0E 0F0E 0E17 1D26 3945 342D 2005" $"8700 022F 0F90 80B2 83B3 82B4 0FB3 B3B1" $"A6A2 8C08 321B 202E 4133 2D26 0E8C 0003" $"2814 88B0 81B1 83B2 0EB1 A89A 9286 7E7A" $"6539 000E 141C 1601 9000 0217 227D 80AF" $"81B0 0AAA 9A94 897E 7C69 4C33 1601 9800" $"0F02 4672 ADAE AA9B 9389 7D7A 6E51 391F" $"059E 0009 4270 887D 7A75 583D 2707 9E00" $"0400 2236 241C 7F23 2616 1D25 1819 2520" $"1724 2A17 2333 2324 3C3E 2535 3E32 3630" $"3341 3927 3637 232C 3528 222E 2B18 252C" $"1F01 1929 1106 7CDE DDDC D8D3 C9C0 B7AB" $"9F94 8577 6653 4539 2F26 1F19 1F1F 1C4D" $"4140 3433 3732 2C33 382A 3139 2F30 3A3B" $"391C 1714 000E 67BC C0C2 C1BD B7AF A59A" $"8E81 7569 5D4D 3930 201A 150F 0D10 1578" $"544B 443E 3A37 3486 2E2A 3922 1F14 000D" $"56A5 A8AA A9A6 A19B 9389 7F75 6B61 5749" $"332B 1B17 130E 0F13 1978 574F 4945 413F" $"3E31 3030 2F81 2E2B 2D38 2A16 1700 0B48" $"9093 9493 918D 8781 7971 6860 574F 432E" $"2718 1412 0D0F 1319 7152 4C47 4340 3E3D" $"3130 2F2F 812E 2B2D 3D20 131E 0009 3D7E" $"8081 807E 7B77 716B 645D 564F 493D 2923" $"1512 100C 0F13 1A67 4E49 4541 3F3D 3C30" $"302F 2F80 2E2D 2D2D 391F 0D22 0007 346E" $"7071 706F 6C68 645F 5953 4D48 4339 2520" $"1311 0E0B 0F13 1A5E 4A46 4340 3E3C 3B30" $"2F2F 2E2E 812D 073D 1C02 2E00 052E 6180" $"631E 615F 5C58 5450 4B46 423E 3521 1D11" $"0F0D 0B0F 131A 5647 4441 3F3D 3C3A 302F" $"2F80 2E80 2D26 4311 0031 0004 2856 5758" $"5756 5452 4F4C 4844 403D 3932 1E1B 0F0D" $"0C0A 0F13 1A50 4442 3F3E 3C3B 3980 2F02" $"2E2D 2E80 2D07 410D 0030 0002 254C 804E" $"1F4D 4B4A 4744 413E 3B38 362F 1C19 0D0C" $"0B09 0E13 1A4A 4240 3E3D 3B3B 392F 2F2E" $"2E81 2D28 2C4D 0200 3000 0222 4446 4746" $"4544 4341 3E3C 3A37 3533 2D1A 180C 0B0A" $"080E 131A 4640 3E3D 3C3B 3A38 2F80 2E81" $"2D08 2C4A 0000 2F03 011F 3E80 401B 3F3E" $"3D3B 3A38 3634 3230 2B18 170B 0A09 080E" $"131A 433F 3D3C 3B3A 3A37 812E 802D 092C" $"2B47 0000 2808 011C 3880 3B17 3A39 3837" $"3634 3331 302E 2A17 160A 0908 070E 121A" $"403D 3C3B 803A 0136 2E81 2D80 2C08 2B47" $"0000 220E 011A 3480 374C 3636 3534 3331" $"302F 2E2D 2916 1509 0807 070E 121A 3E3C" $"3B3B 3A39 3936 2E2E 2D2D 2C2D 2C2C 313C" $"0000 230E 0117 3134 3433 3332 3231 302F" $"2E2D 2C2B 2815 1408 0707 060E 121A 3C3B" $"3B3A 3A39 3935 2E80 2D81 2C08 2F3A 0000" $"220D 0015 2E80 3117 3030 2F2F 2E2D 2D2C" $"2B2A 2815 1407 0706 060E 121B 3B3B 3A3A" $"8039 0034 812D 802C 092B 3336 0000 2211" $"0013 2C80 2F80 2E0A 2D2D 2C2B 2B2A 2A27" $"1413 0780 0602 0E12 1B80 3A04 3939 3838" $"3480 2D81 2C09 2B34 3100 001B 1300 102B" $"822D 2A2C 2C2B 2B2A 2A29 2927 1413 0606" $"0506 0E12 1B39 3A39 3838 3737 322D 2D2C" $"2C2B 2C2B 2B32 3300 001A 1900 0E29 822C" $"802B 082A 2A29 2928 2614 1307 8005 0E0B" $"0E15 2D2D 2B29 2826 2525 272A 2C2C 802B" $"212A 372C 0000 1719 000C 282A 2A29 2827" $"2523 211F 1D1B 1917 1513 1311 0A05 0503" $"030B 2086 2102 2224 2780 2A0C 3529 0000" $"0C25 0204 1415 1412 1181 1084 0F19 1012" $"1311 0B05 0209 1D1E 1E1D 1D1C 1C1B 1D1E" $"1E1C 1A1B 2428 3C29 8000 0323 1401 0D83" $"0F2F 0E0D 0C0B 0A09 0809 0D0E 0C09 0705" $"0201 0515 1614 110F 0D0B 0806 0403 1E31" $"5067 5D2E 0700 0002 3E1C 0407 0808 0706" $"0505 8304 8003 0506 0F0B 202A 0684 0316" $"040A 1522 3241 5160 82A4 B1B6 6400 0005" $"3403 0202 0403 0384 0281 0324 0000 0515" $"274C 623E 3747 5868 7989 98A3 A8A7 ABB1" $"B8BE C5CB D1DA BD00 0003 2B02 0504 0304" $"0482 0520 0607 090C 0F11 0F12 1416 1E27" $"355F 92AE BEC5 CDD5 DDE4 E7E0 DDD9 D4CF" $"CAC5 C1BF AD80 0014 3301 0608 0A0C 1013" $"1619 1C1F 2225 282A 2D2F 2729 2680 2414" $"2B30 42AB EEE8 E3DD D6D1 CDC2 C1C1 C0BF" $"BFBE BDBB 9C80 0014 3000 0E23 2729 2C2F" $"3235 4254 534D 4845 423F 2C2A 2580 1F03" $"292F 3491 80CD 80CC 0ACA C0C0 BFBF BEBD" $"BCBC BA92 8000 042F 0007 3769 806B 056A" $"6659 443E 3E80 3D0C 3C29 2924 1F1E 1E28" $"2E33 91CB CC80 CB0B CAC8 BFBE BEBD BDBC" $"BBBA B788 8000 0329 0603 3382 3E01 3D3E" $"823D 043C 3B2A 2824 801E 0327 2D32 9281" $"CA0C C9C9 C6BE BDBC BCBB BAB9 B9B7 7680" $"0003 2908 0230 853D 823C 033B 2A28 2380" $"1E05 262C 3192 C8C9 80C8 0BC7 C4BC BCBB" $"BABA B9B8 B7B5 6C80 0003 250B 012C 823D" $"003C 803D 803C 043B 3B29 2823 801E 0325" $"2B30 9281 C70C C6C6 C2BB BABA B9B8 B7B6" $"B5B3 6480 0004 2010 0128 3C81 3D84 3C0B" $"3B3B 2928 231E 1D1D 242A 2F92 80C5 80C4" $"0AC0 B9B9 B8B7 B7B6 B5B4 B355 8000 0321" $"1100 2487 3C80 3B03 3A29 2823 801D 0323" $"292E 9381 C30C C2C2 BEB8 B7B6 B6B5 B4B3" $"B2B1 4980 0004 200F 0021 3B81 3C84 3B04" $"3A3A 2A27 2280 1D05 2228 2D93 C2C2 81C1" $"0ABC B6B5 B5B4 B3B2 B1B0 AE43 8000 031E" $"1200 1D87 3B80 3A03 3929 2723 801D 1421" $"262C 93C0 C1C0 C0BE BBB8 B5B4 B3B2 B2B1" $"B0AF AE35 8000 0418 1800 1939 813B 013A" $"3B82 3A0F 3939 2927 231D 1C1C 2025 2A90" $"B9B6 B4B2 80B1 09B3 B4B2 B1B0 AFAE ADAC" $"2980 0004 151C 0016 3988 3A04 3938 2A26" $"2380 1C03 1A1E 2386 81B0 0CAF AFAE AEAF" $"B2B0 AEAD ACAB A823 8000 040E 2100 1338" $"833A 1039 3633 302E 2B2A 2B27 2621 1C1C" $"181C 2286 82AE 0BAD ADAC ACAB AEAE ACAA" $"AAA7 1780 000A 0526 0010 3739 3633 302E" $"2B82 2A00 2980 2A07 2625 201B 161B 2086" $"80AD 0DAC ACAB ABAA AAA9 A8A9 ABA9 A8A6" $"0981 0003 2E00 0928 812A 0029 802A 8429" $"072A 2524 1F15 1A1F 8681 AB0C AAAA A9A9" $"A8A7 A6A5 A5A7 A9A3 0481 0003 280B 0625" $"8829 0028 8229 0625 232B 181E 86AA 80A9" $"0BA8 A8A7 A7A6 A5A4 9E90 8988 9582 0003" $"2113 0424 8129 0028 8329 8228 0829 2722" $"3522 1D85 A8A8 80A7 0AA6 A395 8E85 7A79" $"6A4B 3313 8200 030E 2303 2389 2881 2712" $"2829 253E 4023 85A6 A59A 9088 7F7A 7556" $"3D24 0587 0002 2F08 2181 2800 2783 2802" $"2728 2880 270C 2432 420B 506F 7F78 765C" $"422D 0E8C 0002 2810 1F81 2800 2782 280F" $"2727 2529 2D31 3C49 3F2A 0012 2125 1801" $"9000 0417 1C1D 2728 8227 0A26 262E 313A" $"4B43 352A 1401 9800 0F02 361A 2727 2624" $"2D2E 3446 4537 2E1C 059E 0009 2D2A 2E31" $"434B 3A2F 2307 9E00 696C 3332 0000 0B23" $"0213 3D97 80F5 1DF6 F5F6 F5F5 F4F4 F3F2" $"F3E6 A63A 434E 5045 4E3E 4B3B 4439 3C40" $"1821 0B70 FE80 FF00 FE80 FF0D FEFF FDF2" $"E3DB 7017 666F 6158 534E 834A 0438 2001" $"61FD 80FF 00FE 80FF 18FE FFF3 E1D3 CD6C" $"196A 7066 605B 554C 4B4A 4A49 483B 1907" $"53FA 80FF 00FE 80FF 18FE FEEA DACD C96B" $"1965 6A62 5D59 544B 4B4A 4949 4A34 1808" $"47F5 85FE 17F9 E1D4 C8C5 6A18 5C64 5F5B" $"5853 4B4A 4949 484B 2E16 0A3B F080 FF3C" $"FEFF FEFB F6F0 DBCE C4C2 6918 5560 5C59" $"5751 4A49 4948 484B 2915 0B30 E8FC FDFD" $"FCF9 F6F1 EDE9 D5CA C0BF 6818 505C 5957" $"5650 4949 4848 474B 2311 0F25 DB80 F11C" $"F0EE ECE9 E6E4 D1C7 BDBD 6718 4C59 5756" $"554F 4948 4847 474C 1F0C 131B CF81 E71C" $"E6E4 E3E1 DFCE C4BB BB65 1749 5756 5554" $"4E48 4847 4746 4C1A 051C 13C6 DF80 E01D" $"DFDF DEDD DCCB C1B9 B964 1748 5655 5453" $"4D48 4747 4646 4C14 0020 0BBD D9DA 80DB" $"1CDA DAD9 D9C9 BFB7 B863 1646 5454 5353" $"4C47 4746 4645 4E0E 0020 05B3 D5D6 84D7" $"19C7 BEB6 B662 1646 5353 5251 4A46 4645" $"4544 5207 0021 02A7 D2D3 D380 D410 D3D2" $"D1C4 BDB5 B55E 0F37 4241 3F3D 3D40 4380" $"4418 5500 0020 018E BFBE BDBC BBB9 B9B8" $"B8B9 BCBE B95C 082D 3938 3881 370A 3437" $"3A51 0000 1E11 77B0 B084 B11B B2B2 A89D" $"4402 181D 1814 0F0B 060A 2243 5937 0000" $"2708 609D 9488 7A6B 7F5D 4E3E 2F1F 1611" $"1D20 1213 1A20 262C 3136 3D43 4650 6221" $"0020 030A 0D08 070F 2032 4457 6978 8EA3" $"912A 2947 6261 5F5F 5C56 5452 504E 5220" $"0021 0462 8EA7 BFD1 DBE2 E7EB EEE3 DACC" $"C856 193A 625A 5959 544E 4E4D 4D4C 531A" $"001E 018B EDEA E6E3 DFDB DADA DBCD C7BC" $"BD53 1936 5A59 5958 534E 4D4C 4C4B 5214" $"001A 066E D5D5 D6D7 D780 D81C D9CB C4BB" $"BB51 1836 5958 5857 524D 4C4C 4B4A 540C" $"0017 0960 D3D4 D4D5 D580 D607 D7CA C2B9" $"B950 1736 8057 1156 514C 4B4B 4A49 5705" $"0017 0B53 D0D2 D2D3 D381 D41B C8C1 B7B7" $"4F16 3656 5655 554F 4B4A 4A49 4856 0000" $"140B 46CD D0D0 D1D1 81D2 06C6 BFB5 B54D" $"1635 8155 0E4E 4A49 4948 4753 0000 120E" $"39CA CECE 80CF 80D0 26C5 BDB3 B34C 1534" $"504E 4B48 484A 4848 4746 4C00 000E 122E" $"C6CC CCCD CDCE CECC CAC1 BBB3 B048 0F2A" $"8046 8045 0F48 4746 4549 0000 0319 23C1" $"C8C6 C3C1 BE81 BC05 BBB8 B046 0E2A 8045" $"0744 4443 4345 4644 4280 0003 1F17 ADB7" $"80B8 81B9 06BA BAB8 B549 0D2A 8044 0743" $"4342 4241 4143 4180 0006 2210 A6B5 B5B6" $"B683 B70F B8B5 7F11 2943 4342 4240 4142" $"4944 381F 8000 0418 129F B3B3 80B4 82B5" $"0CB4 B599 272D 4041 454A 3E2E 1F08 8300" $"0409 1F97 B1B1 82B2 0AB1 A59B 907E 5F0A" $"252C 230F 8900 0129 8C80 AF07 A59B 8F85" $"644A 2F13 9000 082E 7D8F 8669 4F33 1B02" $"9100 2312 2E26 7573 6B6C 5F63 5356 4745" $"3D37 4131 4E62 95BA B9AA AB9C 9C90 8C84" $"7C7C 321D 041D C87F D5D6 D1C7 B9A9 9785" $"7459 4737 2C2C 3DAF F9EF E7E1 DCD7 D6D5" $"D3D2 CF71 1F01 1BA4 B3B4 B0A7 9C8E 7F70" $"6346 3527 2223 33AE F3E8 E1DC D6CC CBCA" $"C9C7 C46B 1907 1884 9495 928B 8378 6D62" $"583E 2F23 1F22 32AE EBE3 DDD9 D4CB CAC9" $"C7C6 C260 1808 146C 7C7C 7A75 6F67 5F57" $"4F37 2A20 1D22 31AE E4DE DAD7 D1C9 C8C7" $"C6C4 C154 160A 115A 7F69 6967 645F 5A54" $"4E48 3227 1D1B 2130 ADDE DAD7 D5CF C8C7" $"C5C4 C3BF 4815 0B0E 4E5B 5B59 5753 4F4B" $"4743 2F24 1B1A 202F ABD9 D6D4 D3CD C6C4" $"C3C2 C1BE 3D11 0F0B 4450 504F 4D4B 4845" $"423F 2C22 1919 202E A8D5 D3D2 D1CA C4C3" $"C2C1 C0BC 320C 1308 3E48 4847 4644 4240" $"3E3C 2A20 1818 1F2D A5D2 D1D0 CFC8 C2C1" $"C0BF BEBA 2705 1C06 3980 421C 413F 3E3D" $"3B3A 291F 1717 1E2C A3CF CECE CDC6 C0BF" $"BFBE BCB8 1C00 2004 3580 3E1C 3D3C 3B3A" $"3938 281E 1617 1E2B A1CD CCCC CBC4 BEBE" $"BDBC BBB6 1200 2002 3280 3B1C 3A3A 3938" $"3837 281E 1616 1D2A A0CB CACA C9C1 BDBC" $"BBBA B9B5 0800 2101 2E81 397A 3837 3634" $"3326 1F16 1619 2292 B8B6 B4B3 B3B5 B8B9" $"B8B7 B100 0020 0120 2826 2422 211F 1D1C" $"1C1D 1F20 1B16 1B87 ADAC ACAB AAA9 A49B" $"9592 9500 001E 1012 1B1A 1A19 1918 1717" $"1618 1A15 1309 074E 5D4E 3F30 2113 0F26" $"3D4F 3500 0027 080B 1211 0F0E 0D0B 0A08" $"0703 0605 0B0B 0706 0707 0808 0705 0708" $"0914 2718 0020 0380 0513 070F 2032 4457" $"6978 8EA3 8F1F 1017 2220 1E1D 1914 8113" $"4A1C 1700 2104 628E A7BF D1DB E2E7 EBEE" $"E3DA CBC7 500E 1A26 1F1E 1D19 1313 1213" $"131E 1500 1E01 8BED EAE6 E3DF DBDA DADB" $"CDC7 BCBC 4D0E 171F 1E1D 1D18 1313 1213" $"121F 1000 1A06 6ED5 D5D6 D7D7 80D8 1CD9" $"CBC4 BABA 4C0D 171E 1E1D 1D17 1313 1213" $"1221 0B00 1709 60D3 D4D4 D5D5 80D6 08D7" $"CAC2 B9B9 4B0D 171E 801D 0017 8212 0A28" $"0500 170B 53D0 D2D2 D3D3 81D4 0DC8 C1B7" $"B74A 0D17 1E1D 1C1C 1613 1380 120A 2B00" $"0014 0B46 CDD0 D0D1 D181 D20D C6BF B5B5" $"490D 171D 1D1C 1C16 1313 8012 082C 0000" $"120E 39CA CECE 80CF 80D0 0CC5 BDB3 B348" $"0C15 1916 1411 1113 8012 1811 2900 000E" $"122E C6CC CCCD CDCE CECC CAC1 BBB3 B042" $"030B 1010 810F 0F12 1211 1129 0000 0319" $"23C1 C8C6 C3C1 BE81 BC07 BBB8 B040 030B" $"1010 810F 040E 1012 1127 8000 031F 17AD" $"B780 B881 B906 BABA B8B5 4402 0A80 0F81" $"0E03 0D0E 132A 8000 0622 10A6 B5B5 B6B6" $"83B7 04B8 B57D 080A 800F 070E 0E14 1A2A" $"302C 1A80 0004 1812 9FB3 B380 B482 B50C" $"B4B5 9922 1011 1823 3230 261C 0883 0004" $"091F 97B1 B182 B20A B1A5 9B90 7E5F 0A1C" $"221E 0F89 0001 298C 80AF 07A5 9B8F 8564" $"4A2F 1390 0008 2E7D 8F86 694F 331B 0291" $"003A 122D 1B68 665E 6051 5644 4737 342C" $"2632 2236 3231 373A 2F3A 2A39 2834 292E" $"3312 1D04 16B7 C4C5 C0B6 A898 8775 6348" $"3725 1B0D 0F54 5042 3934 2F2B 2B80 2C1C" $"2D2C 1F01 1594 A3A4 9F97 8C7E 6F61 5336" $"2517 120D 1359 544A 443F 3A30 2F7F 2F2E" $"2E2D 3019 0712 7585 8582 7C73 695E 5349" $"2F20 1310 0D13 514E 4641 3E38 302F 2E2E" $"2D2F 2B18 0810 5E6D 6D6B 6660 5850 4840" $"281B 110E 0D13 4848 433F 3D37 2F2F 2E2D" $"2D32 2516 0A0D 4C5A 5A58 5550 4B45 3F39" $"2418 0E0C 0D13 4144 403D 3B36 2F2E 2E2D" $"2D32 2215 0B0B 404C 4C4B 4845 413D 3834" $"2015 0C0A 0C13 3C41 3E3C 3B35 2F2E 802D" $"4533 1E11 0F09 3742 4140 3F3C 3936 3331" $"1E13 0A09 0C13 383F 3D3B 3A34 2E2E 2D2D" $"2C33 1A0C 1307 313A 3A39 3836 3432 302E" $"1C12 0808 0C13 353D 3B3A 3933 2E2D 2D2C" $"2C34 1705 1C05 2D80 3413 3331 302E 2D2C" $"1B10 0707 0B13 343B 3A39 3933 2D2D 802C" $"4535 1300 2003 2931 3030 2F2E 2D2C 2B2A" $"1A10 0706 0B12 333A 3A39 3932 2D2D 2C2C" $"2B37 0E00 2001 272E 2E2D 2D2C 2B2B 2A29" $"1A0F 0606 0B12 323A 3938 3831 2D2C 2C2B" $"2B3D 0700 2101 2480 2C23 2B2A 2928 2625" $"1810 0605 070A 2329 2725 2424 2729 2B2B" $"2A41 0000 2001 161B 1917 1514 1211 800F" $"3612 120C 0603 191F 1F1E 1D1D 1F1F 1E22" $"2742 0000 1E10 090E 0D0C 0B0A 0A09 0807" $"090D 0805 0302 0D0F 0D0B 0806 0309 2761" $"7D42 0000 2708 0204 8503 5C01 0410 3848" $"282D 3E4F 5F70 7F90 A4B1 B9C4 D532 0020" $"0305 0405 0607 0A0E 1114 1716 191A 222E" $"5BA3 D3DA DDDE DCD4 D0CB C5C1 BD31 0021" $"0217 1F25 2A2F 3C45 403E 3E32 2B21 2126" $"3176 D2CE CDCC C7C0 C0BF BDBC BA26 001E" $"0127 5B5C 5C59 4C3E 803D 062F 281F 1F25" $"2F72 80CB 0CCA C5BE BDBC BBBA B71A 001A" $"0621 843D 1A3C 3C2F 281E 1E23 2E72 C9C9" $"C8C8 C2BC BBBA B9B8 B40F 0017 091D 3D3D" $"843C 162F 271E 1E22 2C72 C7C6 C6C5 BFBA" $"B9B8 B7B5 B205 0017 0B19 833C 803B 072F" $"271E 1E21 2A72 C480 C30D BCB8 B7B6 B4B3" $"AA00 0014 0B15 3B3C 823B 083A 3A2F 271D" $"1D20 2871 80C1 0FC0 BAB5 B4B3 B2B0 9E00" $"0012 0E12 3A3B 3B83 3A17 2E27 1D1D 1F27" $"6FBB B9B6 B3B3 B4B2 B1AF AE91 0000 0E12" $"0E39 833A 0938 352D 261F 1C1A 1F65 B080" $"AF11 AEAE B0AE ACAB 8500 0003 190B 3838" $"3532 302D 812A 0528 251E 181C 6580 AD07" $"ACAB AAA9 ABAB A978 8000 021F 0528 8729" $"0F27 241B 1B64 ABAB AAA9 A9A8 A6A5 A4A1" $"6D80 0005 2204 2629 2928 8029 8128 0F29" $"262E 1D64 A8A8 A7A7 A297 8E84 6B4F 2880" $"0002 180B 2485 2880 270B 2836 2F66 9A91" $"8777 583F 2409 8300 0509 1C22 2828 2780" $"2880 2708 2C32 3C38 0B37 402B 1089 0001" $"241F 8027 0726 2B2F 3E39 2F22 1190 0008" $"2027 2D3B 3932 2317 0291 0069 7333 3200" $"0002 F701 1FBF 80FA 0CF9 F9EE B63F 5C4F" $"4845 4236 10AB 81FF 3DF6 D79B 4069 5C50" $"4A49 4010 9AFF FEFE FBE9 CB96 385F 594E" $"4948 3B10 86F7 F6F2 EBDD C493 3359 564C" $"4847 3610 71E3 E4E2 DFD5 BE90 3056 544B" $"4746 3210 60D8 D97F D9D8 D0BA 8D2E 5452" $"4946 452D 104E C9C8 C7C6 C2BB 8A1F 3D3B" $"3B3C 3E29 113C A499 8A7C 6C60 4710 1C1D" $"1E2B 4D2E 101D 536A 849B ADB6 7631 605C" $"5550 4E38 0E40 E0DD DAD9 D3C1 8727 5958" $"504C 4B32 0B32 D2D3 D4D5 CFBD 8426 5756" $"4E4A 492C 0926 CDD0 D0D1 CBB9 8025 524F" $"4B48 4728 041F C7C8 C6C4 C1B8 7C1C 4645" $"4446 4523 001A B0B7 81B8 158C 1C43 4341" $"4340 1800 14A7 B3B3 B4B0 A58B 2134 281B" $"0A80 0006 1592 9371 4C2B 1085 0053 1860" $"A299 866F 543E 3679 D7C7 BBB2 A97C 1057" $"A49D 8970 4F2B 2270 EADD D0CA C794 103B" $"736F 6456 4023 1F6F DED7 CCC7 C487 102B" $"5553 4D46 371E 1D6C D6D2 C8C3 C17A 1021" $"4544 413D 321C 1B68 D0CE C4C0 BE6D 101B" $"3D3C 7F3B 3930 1A1A 66CB CAC0 BCBA 6110" $"1430 2E2C 2924 1D18 55B2 B0AF ACA5 5111" $"0D16 1412 100E 0E0D 192E 2010 112A 1D10" $"1B50 6A84 9BAD B671 1422 1D16 1313 190E" $"40E0 DDDA D9D3 C184 121E 1D15 1312 170B" $"32D2 D3D4 D5CF BD81 121D 1C15 1212 1609" $"26CD D0D0 D1CB B97E 111A 1713 1211 1504" $"1FC7 C8C6 C4C1 B879 0710 0F0F 1111 1400" $"1AB0 B781 B815 8B08 0F0E 1018 1F11 0014" $"A7B3 B3B4 B0A5 8B16 1A19 1509 8000 0615" $"9293 714C 2B10 8500 2118 5493 8A77 5F43" $"2D20 3241 352F 2D2C 2810 4C94 8D79 6040" $"1C0F 344C 4035 2F2E 2E10 327F 6460 5547" $"3115 0D2C 443D 332E 2D2B 1023 4744 3F38" $"2910 0B26 3F3B 322E 2D27 101A 3736 332F" $"240C 0924 3B39 302D 2C24 1015 2F2E 2D2B" $"220B 0922 3A38 2F2C 2B22 100F 2321 1E1C" $"170E 0812 2321 2224 2820 1109 0907 0606" $"050A 2219 2A38 4661 9752 1008 131A 2629" $"2720 2669 D3D5 CEC6 C073 0E14 4C4C 413D" $"3623 2150 CAC9 C0BC B965 0B13 813C 0B35" $"2320 4EC5 C4BB B7B5 5809 1080 3B1D 3A34" $"221E 4CBE BAB5 B2B0 4B04 1139 3734 312D" $"251B 41AE AEAC ADAB 3F00 1328 8129 0B28" $"2540 A9A8 A297 8025 0012 2680 2807 272B" $"3436 6544 250B 8000 0611 2731 2A22 1A0D" $"8500 6974 3332 0000 8B31 0000 0000 8200" $"0A10 5874 7DA2 BFD3 E0E7 EAEB 84EE 00EF" $"81F0 82EF 05F0 F0EF EFEE ED82 EE05 EDEC" $"EAE9 EAEA 80EB 06E9 E7E5 E3E4 E6E7 80E9" $"21E7 DDAB ADAE AFB2 6906 0000 081C 3329" $"2523 2327 2D33 3739 3B31 0405 0607 0808" $"0909 069F 0010 0745 734D 425F 84B8 E4F1" $"F1F0 EFEE EDEB EB82 EC03 EDEC EBEA 80EB" $"13EC EBEC ECEB EAEA EBEB ECEC EDEC EBEB" $"ECED EDEF F082 F180 F286 F337 F0E4 886A" $"627A 635A 5552 5558 5D63 696B 655E 5556" $"6069 737D 807E 7861 4751 5A65 6F73 726E" $"5C34 3C44 4C55 5859 573D 1F25 2B32 383C" $"3F41 300B 8200 0919 724F 3A2F 3F45 62BD" $"EC97 FD83 FC80 FB06 FAFA F9F8 F7F6 F580" $"F380 F24F F1F1 F0EE EEEF EFF0 EDD0 9853" $"3A36 353C 4458 5457 5D63 6870 7572 504F" $"5257 5C61 676A 6351 4C4D 5154 585B 5B57" $"524D 4D52 565A 5F5E 5952 4C4E 545A 6167" $"6766 645C 653E 0100 000C 6738 2B39 3C17" $"095F A6DF B5FE 0CFC D27D 4E45 3845 322D" $"2E43 4A4A 8049 8048 384A 4C4E 5052 5456" $"5247 4A51 555B 5F65 6966 474B 5156 5C60" $"686C 6249 4B51 585F 656E 726D 5852 545C" $"2300 000C 4E2A 3D1B 090B 0C57 A3D5 FEFF" $"FFFE 80FF 0CFE FFFF FEFF FFFE FFFF FEFF" $"FFFE 80FF 0CFE FFFF FEFF FFFE FFFF FEFF" $"FFFE 80FF 05FE FFFF FEFF FF80 FE24 FDFC" $"FBF9 F8F6 F4F3 E9BE 251C 1B1B 1A19 1C31" $"6DC5 7670 6A65 615E 5A58 5553 5150 4E4D" $"4D4C 4B81 4A83 4981 4888 4915 4B54 5457" $"2800 000A 4342 0D0D 0C06 0450 A4D4 FEFF" $"FFFE 80FF 0CFE FFFF FEFF FFFE FFFF FEFF" $"FFFE 80FF 0CFE FFFF FEFF FFFE FFFF FEFF" $"FFFE 80FF 2FFE FFFF FEFE FCF8 F4EC E5E0" $"DCD9 D7D5 D3D1 CCB3 1F14 1313 1212 1831" $"61D9 6E69 6662 5F5C 5957 5553 514F 4E4C" $"4B4A 4948 4881 4781 4880 4980 4A83 4B81" $"4C10 4A5A 582A 0000 0C45 280D 0601 0103" $"479F CCA7 FE2C FCF9 F5F2 EBE1 DEDB D9D6" $"D4D2 D0CF CAB2 2016 1718 1819 2141 70DB" $"7975 716E 6B67 6562 605E 5C5A 5957 5654" $"5452 4B86 4A81 4B84 4A81 4908 4858 5B2F" $"0000 0C41 3280 0008 0102 409C C9FE FFFF" $"FE80 FF0C FEFF FFFE FFFF FEFF FFFE FFFF" $"FE80 FF0C FEFF FFFE FFFF FEFF FFFE FFFF" $"FE80 FF2F FEFF FDF9 F5F1 EEE4 DDDA D8D6" $"D3D2 D0CF CDC9 B221 1718 1819 1A22 4373" $"DA79 7572 6F6C 6967 6563 615F 5E5C 5B5A" $"595A 5B54 804E 014D 4D80 4C81 4B81 4A02" $"494A 4A80 490A 4849 4763 5C32 0000 0E43" $"3F80 0008 0102 3899 C5FC FFFF FE80 FF0C" $"FEFF FFFE FFFF FEFF FFFE FFFF FE80 FF0C" $"FEFF FFFE FFFF FEFF FFFE FFFF FE80 FF32" $"FEFE F7F4 F0ED EAE1 DAD8 D6D4 D2D1 CFCE" $"CCC9 B221 1718 1919 1A23 4473 D678 7471" $"6E6B 6967 6563 6160 5E5D 5C5B 5A5B 5B53" $"4E4D 4D80 4C80 4B02 4A4B 4B81 4A01 494A" $"8149 0B48 4946 6D5C 3700 0011 4F1B 0180" $"0004 0131 95C1 FAA4 FE32 FDF4 F0ED EBE8" $"DFD8 D6D4 D2D1 CFCE CDCB C8B1 2117 1819" $"191A 2344 73D0 7672 6F6D 6A68 6664 6260" $"5F5E 5D5C 5B5A 5B5B 534D 4D4C 4C81 4B82" $"4A84 4981 4814 4651 5D3E 0000 0F53 2306" $"0000 0101 2B91 BEF8 FFFF FE80 FF0C FEFF" $"FFFE FFFF FEFF FFFE FFFF FE80 FF0C FEFF" $"FFFE FFFF FEFF FFFE FFFF FE80 FF31 FEFC" $"F1EE EBE8 E6DD D6D4 D3D1 CFCE CDCC CBC7" $"B121 1718 1819 1A23 4473 CC74 706E 6B69" $"6765 6361 605E 5D5C 5B5A 5A5B 5B52 4D4D" $"814C 804B 014A 4B82 4A80 4908 4849 4948" $"4948 5760 3680 000D 3F2F 0C00 0001 0123" $"8DBB F4FF FFFE 80FF 0CFE FFFF FEFF FFFE" $"FFFF FEFF FFFE 80FF 0CFE FFFF FEFF FFFE" $"FFFF FEFF FFFE 80FF 35FE FBEE EBE9 E6E4" $"DBD5 D3D1 D0CE CDCC CBCA C7B1 2017 1818" $"191A 2344 73C8 726F 6C6A 6765 6462 605F" $"5E5D 5C5B 5A59 5B5A 514D 4D4C 4B4C 4C80" $"4B03 4A4B 4A49 804A 8049 0848 4949 4848" $"4A60 690E 8000 024D 2508 8000 0401 1D89" $"B8F0 A4FE 30F9 EBE9 E6E4 E2DA D3D1 D0CE" $"CDCC CBCA C9C6 B021 1718 1819 1A23 4473" $"C370 6D6B 6866 6463 6160 5E5D 5C5B 5A5A" $"595A 5A51 4C4C 814B 834A 8349 8348 034B" $"696E 1080 000D 5F18 0F00 0001 0118 84B6" $"EDFF FFFE 80FF 0CFE FFFF FEFF FFFE FFFF" $"FEFF FFFE 80FF 0CFE FFFF FEFF FFFE FFFF" $"FEFF FFFE 80FF 2FFE F7E9 E6E4 E2E0 D8D1" $"D0CE CDCC CBCA C9C8 C6B0 2017 1818 191A" $"2444 72BE 6E6B 6967 6563 6260 5F5E 5D5C" $"5B5A 5958 5A5A 5080 4C80 4B02 4A4B 4B80" $"4A00 4980 4A80 4908 4849 4948 4846 5574" $"1280 000D 3918 2300 0001 0113 7FB3 E9FF" $"FFFE 80FF 0CFE FFFF FEFF FFFE FFFF FEFF" $"FFFE 80FF 0CFE FFFF FEFF FFFE FFFF FEFF" $"FFFE 80FF 2FFE F5E7 E4E2 E0DE D6D0 CECD" $"CCCB CAC9 C8C7 C5B0 2017 1818 191A 2444" $"72B5 6C6A 6866 6462 615F 5E5D 5C5B 5A5A" $"5958 5A59 5080 4C80 4B01 4A4B 814A 0249" $"4A4A 8149 0148 4980 4803 4F50 7510 8000" $"0D40 1B34 0000 0101 0F79 B0E4 FFFF FE80" $"FF0C FEFF FFFE FFFF FEFF FFFE FFFF FE80" $"FF3F FEFF FFFE FFFF FEFF FFFE FFFF FEFF" $"FFFE FCF3 E4E2 E0DE DCD5 CECD CCCB CAC9" $"C8C7 C6C4 B020 1718 1819 1A24 4470 AD6A" $"6866 6463 6160 5F5E 5C5C 5B5A 5959 585A" $"594F 804C 804B 014A 4B81 4A0E 494A 4949" $"4849 4948 4948 4748 5952 6081 0002 4E1F" $"0E80 0004 010B 73AE E0A2 FE30 FCFA F1E2" $"E0DE DCDB D3CD CCCA CAC9 C8C7 C6C5 C3AF" $"2017 1818 191A 2444 6FA5 6967 6563 6260" $"5F5E 5D5C 5B5A 5959 5857 5A58 4F81 4B82" $"4A83 4984 4804 4748 6352 6881 000D 4B20" $"1E00 0001 0109 6CAB DBFF FFFE 80FF 0CFE" $"FFFF FEFF FFFE FFFF FEFF FFFE 80FF 3FFE" $"FFFF FEFF FFFE FFFF FEFF FFFE FDFB FAF8" $"EFE0 DEDC DBD9 D2CB CAC9 C8C8 C7C6 C5C4" $"C3AF 2017 1718 1919 2445 6E9D 6766 6462" $"6160 5E5D 5C5B 5A5A 5959 5857 5A58 4E80" $"4B02 4A4B 4B80 4A02 494A 4A81 4902 4849" $"4980 4804 4748 4E52 7081 000D 2B20 3100" $"0001 0107 65A9 D6FF FFFE 80FF 0CFE FFFF" $"FEFF FFFE FFFF FEFF FFFE 80FF 3FFE FFFF" $"FEFF FFFE FFFF FEFF FEFD FBF9 F7F5 EDDE" $"DCDA D9D8 D1CA C9C8 C7C7 C5C4 C4C3 C2AF" $"2017 1718 191A 2445 6D96 6664 6361 605F" $"5E5D 5C5B 5A59 5958 5857 5958 4E80 4B02" $"4A4B 4B80 4A02 494A 4A81 4902 4849 4980" $"4804 4748 5052 7481 0002 3626 1E80 0004" $"0105 5DA6 D29D FE36 FDFC FAF8 F6F5 F3EB" $"DCDA D9D7 D6D0 C9C8 C7C6 C5C4 C4C3 C3C2" $"AE20 1717 1819 1925 456B 9065 6361 605F" $"5E5D 5C5B 5A5A 5958 5857 5759 574D 4B82" $"4A84 4984 4880 4703 4859 544A 8100 0D41" $"2D19 0000 0101 0554 A3CD FDFF FE80 FF0C" $"FEFF FFFE FFFF FEFF FFFE FFFF FE80 FF37" $"FEFF FFFE FFFF FEFF FEFD FBF9 F7F6 F4F3" $"F1E9 DBD8 D7D6 D5CE C8C7 C6C5 C4C3 C3C2" $"C2C1 AE1F 1717 1819 1925 456A 8A63 6260" $"5F5E 5D5C 5B5A 5A59 8058 0457 5759 574D" $"804B 804A 0249 4A4A 8049 0048 8049 8048" $"0747 4848 4748 6454 5181 000D 1332 2D00" $"0001 0104 4CA0 C9FB FFFE 80FF 0CFE FFFF" $"FEFF FFFE FFFF FEFF FFFE 80FF 38FE FFFF" $"FEFF FFFE FDFB FAF8 F6F5 F4F2 F1EF E8D9" $"D7D6 D5D4 CDC6 C5C4 C4C3 C3C2 C2C1 C1AD" $"1F17 1718 1919 2545 6984 6261 5F5E 5D5C" $"5B5B 5A59 5958 8157 0559 574C 4A4B 4B80" $"4A02 494A 4A80 4900 4880 4980 4807 4748" $"4847 4752 545A 8100 0216 3D3D 8000 0501" $"0345 9EC6 F997 FE18 FDFB FAF8 F7F5 F4F3" $"F1F0 EFEE E6D7 D5D4 D3D2 CCC4 C4C3 C3C2" $"C280 C11E C0AD 1F16 1718 1819 2545 677F" $"6160 5E5D 5C5C 5B5A 5959 5858 5757 5656" $"5956 4C81 4A83 4985 4883 4702 5054 6081" $"0002 1A49 1880 0007 0102 3E9A C3F6 FFFE" $"80FF 0CFE FFFF FEFF FFFE FFFF FEFF FFFE" $"80FF 80FE 18FC FBFA F8F7 F6F4 F3F2 F0EF" $"EEED ECE5 D6D4 D3D2 D1CB C3C3 C2C2 81C1" $"17C0 C0AD 1F16 1718 1819 2645 667A 605F" $"5E5D 5C5B 5A5A 5958 5880 5704 5656 5856" $"4C80 4A02 494A 4A83 4902 4849 4981 4807" $"4748 4847 475A 5631 8100 0D13 4A27 0200" $"0001 0136 97C0 F3FF FE80 FF0B FEFF FFFE" $"FFFF FEFF FFFE FFFF 81FE 17FD FCFB F9F8" $"F7F6 F4F3 F2F1 F0EE EDEC EBEB E3D5 D3D2" $"D1D0 CA80 C201 C1C1 80C0 18BF BFAC 1F16" $"1718 1819 2645 6576 5F5E 5D5C 5B5A 5A59" $"5958 5857 8156 0258 554B 804A 0249 4A4A" $"8049 1148 4949 4849 4848 4748 4847 4847" $"4746 6658 3882 0002 4238 0480 0004 012F" $"93BD EE8E FE1B FDFC FBFA F9F9 F7F6 F5F4" $"F3F2 F1F0 EFED ECEB EAEA E9E2 D4D1 D0D0" $"CFC9 80C1 80C0 81BF 13AC 1F16 1718 1819" $"2645 6473 5E5D 5C5B 5A5A 5959 5880 5707" $"5656 5556 5855 4B4A 8449 8448 8447 0446" $"4556 593F 8200 0F52 2304 0000 0101 2890" $"BAE9 FAFB FBFC FC83 FD80 FC1F FBFB FAFA" $"F9F8 F7F6 F6F5 F4F3 F2F1 F0EF EEED ECEB" $"EAE9 E8E8 E1D2 D0CF CFCE C8C1 80C0 81BF" $"15BE BFAC 1F16 1718 1819 2645 636F 5D5C" $"5B5B 5A59 5958 5880 5780 5608 5558 544A" $"494A 4A49 4A81 4902 4849 4981 4802 4748" $"4880 4704 4645 525A 4582 000E 6318 1200" $"0001 0121 8CB8 E4F7 F7F8 F882 F900 FA81" $"F91F F8F8 F7F7 F6F5 F4F4 F3F2 F1F0 EFEE" $"EDED ECEB EAE9 E8E7 E7E6 E0D1 CFCE CECD" $"C8C0 82BF 81BE 12AB 1E16 1717 1819 2645" $"616C 5C5B 5B5A 5959 5858 8057 8056 0755" $"5558 544A 494A 4A80 4904 4849 4948 4982" $"4801 4748 8147 0446 455D 6015 8200 0236" $"1724 8000 0601 1B87 B5E0 F3F4 80F5 85F6" $"21F5 F5F4 F4F3 F3F2 F1F1 F0EF EFEE EDEC" $"EBEB EAE9 E8E7 E7E6 E5E5 DFD0 CECD CDCC" $"C7BF BF82 BE18 BDBD BEAB 1E16 1717 1819" $"2645 6069 5B5B 5A59 5958 5857 5756 5682" $"5502 5753 4A82 4984 4884 4781 4603 4469" $"6516 8200 0C44 1B30 0000 0101 1682 B3DC" $"F1F1 81F2 83F3 81F2 1CF1 F1F0 F0EF EEEE" $"EDEC ECEB EAE9 E9E8 E7E7 E6E5 E5E4 E4DE" $"CFCD CCCC CBC7 81BE 01BD BE81 BD10 AB1E" $"1617 1718 1927 465F 675B 5A59 5958 5880" $"5780 5681 550B 5753 4A49 4A49 4849 4948" $"4949 8048 0047 8048 8047 0746 4747 4643" $"5C6A 1982 000C 531E 0E00 0001 0111 7DB0" $"D8EE EE81 EF85 F080 EF11 EEEE EDED ECEB" $"EBEA EAE9 E8E8 E7E6 E6E5 E4E4 80E3 07DD" $"CFCC CCCB CBC6 BE84 BD0F BCBD AA1E 1617" $"1718 1927 465E 645A 5959 8058 0157 5780" $"5682 5502 5752 4A80 4904 4849 4948 4981" $"4800 4780 4880 4700 4680 4703 494E 6F1C" $"8200 0B48 1E20 0000 0101 0D77 AED4 EB80" $"EC89 ED12 ECEC EBEB EAEA E9E9 E8E8 E7E7" $"E6E5 E5E4 E4E3 E380 E206 DCCE CBCB CACA" $"C581 BD82 BC0D BDAA 1E16 1617 1818 2746" $"5D62 5959 8058 0057 8056 0355 5655 5480" $"5502 5752 4A80 4902 4849 4980 4805 4748" $"4847 4848 8147 0746 4746 4653 4F61 0282" $"0002 2F1F 3280 0006 010A 71AB D1E8 E981" $"EA85 EB80 EA80 E903 E8E8 E7E7 80E6 06E5" $"E4E4 E3E3 E2E2 81E1 06DB CDCA CAC9 C9C5" $"85BC 11BB BCA9 1D15 1617 1818 2746 5C60" $"5958 5857 5780 5680 5582 5402 5751 4985" $"4885 4784 4602 5F50 6683 000D 3B25 1800" $"0001 0108 6AA9 CDE6 E7E7 81E8 05E9 E8E9" $"E9E8 E981 E881 E705 E6E6 E5E5 E4E4 80E3" $"03E2 E2E1 E181 E001 DBCC 80C9 05C8 C4BC" $"BBBC BC82 BB0D BCA8 1D16 1617 1818 2746" $"5B5F 5858 8057 8156 8055 8154 0757 5149" $"4849 4948 4981 4802 4748 4881 4702 4647" $"4781 4602 544F 6F83 0002 442B 1D80 0005" $"0107 62A6 CAE4 81E5 89E6 81E5 80E4 01E3" $"E380 E201 E1E1 80E0 81DF 01DA CC81 C800" $"C487 BB0D A81C 1516 1717 1827 465A 5D58" $"5757 8056 0555 5655 5455 5581 5405 5650" $"4948 4949 8048 0547 4848 4748 4881 4702" $"4647 4781 4602 494F 7783 0002 182F 2F80" $"0005 0106 59A3 C8E1 80E3 8BE4 81E3 80E2" $"80E1 80E0 80DF 81DE 02DA CBC8 80C7 00C3" $"86BA 0DBB A71C 1516 1717 1827 4659 5C57" $"5780 5680 5581 5480 5303 5456 5049 8148" $"8547 8446 8045 0346 5350 5283 0002 1E39" $"3881 0004 0552 A0C5 DF80 E183 E280 E384" $"E281 E180 E081 DF80 DE81 DD01 D9CB 80C7" $"01C6 C386 BA0C BBA7 1C15 1617 1718 2846" $"585B 5781 5681 5580 5400 5380 5402 564F" $"4980 4805 4748 4847 4848 8047 0046 8047" $"8046 0045 8046 025F 5151 8300 0224 441B" $"8100 0603 4A9D C3DD DFDF 81E0 87E1 82E0" $"82DF 80DE 82DD 04DC DCDD D8CA 80C6 06C5" $"C2B9 B9BA BAB9 80BA 0CB9 BAA7 1C15 1617" $"1718 2846 575A 8056 8055 0254 5555 8054" $"0553 5453 5456 4F81 4804 4748 4847 4881" $"4700 4680 4780 4600 4580 4602 5751 5983" $"0002 1443 2B81 0005 0243 9AC0 DADD 80DE" $"8DDF 82DE 81DD 82DC 09DB DBDC D8C9 C5C5" $"C4C4 C186 B90C BAA6 1C15 1616 1718 2846" $"5759 5681 5581 5482 5304 5254 554E 4886" $"4785 4682 4503 4649 5162 8400 0146 3E81" $"0006 013C 97BE D8DC DC83 DD87 DE84 DD82" $"DC84 DB01 D7C9 81C4 05C1 B8B8 B9B9 B882" $"B90C A61C 1515 1617 1828 4656 5856 5681" $"5580 5401 5354 8153 0954 554D 4847 4848" $"4748 4880 4702 4647 4781 4602 4546 4681" $"4502 5553 3F84 0002 561E 0380 0004 0134" $"94BB D681 DB84 DC01 DDDD 89DC 83DB 83DA" $"01D7 C980 C401 C3C1 83B8 0EB9 B9B8 B9A5" $"1C15 1516 1718 2946 5557 8055 0154 5581" $"5480 5309 5253 5354 554D 4847 4848 8347" $"0246 4747 8146 0245 4646 8145 0261 543A" $"8400 025F 1813 8000 0501 2D90 B9D4 D981" $"DA91 DB84 DA81 D902 DAD6 C881 C300 C082" $"B781 B80C B9A5 1C15 1516 1718 2946 5557" $"5582 5482 5381 5202 5455 4C83 4785 4684" $"4580 4402 5C55 4184 0002 3B1A 2480 0005" $"0126 8CB7 D3D8 82D9 91DA 88D9 06D6 C8C2" $"C3C3 C2C0 80B7 01B8 B780 B80E B7B8 A51B" $"1415 1617 1729 4654 5655 5581 5401 5354" $"8153 0652 5352 5454 4C48 8347 0246 4747" $"8046 0045 8046 8045 0644 4545 434B 5649" $"8400 0249 1D28 8000 0601 2088 B4D1 D7D7" $"82D8 93D9 01D8 D982 D802 D9D5 C881 C202" $"C0B7 B682 B713 B8B7 B8A5 1B14 1516 1617" $"2946 5456 5554 5453 5454 8053 0252 5353" $"8052 0353 544B 4880 4705 4647 4746 4747" $"8046 0045 8046 8045 0644 4545 4259 5928" $"8400 0258 1D10 8000 0601 1A84 B2CF D6D6" $"83D7 94D8 82D7 02D8 D5C7 81C1 00BF 84B6" $"0FB7 B7B8 A41B 1415 1616 1729 4653 5554" $"5482 5384 5205 5153 544B 4747 8546 8545" $"8244 0340 6560 1D84 0002 451C 2180 0006" $"0115 7FB0 CDD5 D582 D69B D701 D5C7 81C1" $"00BF 82B6 80B7 0BB6 B7A4 1B14 1516 1617" $"2946 5381 5480 5302 5253 5380 520C 5152" $"5253 534A 4746 4747 4647 4780 4609 4546" $"4645 4645 4544 4545 8044 033E 6F64 2184" $"0002 341E 3380 0005 0110 79AD CBD4 82D5" $"88D6 86D7 0CD6 D7D7 D6D7 D7D6 D7D7 D6D7" $"D4C7 80C1 03C0 BFB5 B584 B60A B7A3 1A14" $"1515 1617 2946 5280 5481 5302 5253 5380" $"520B 5152 5253 534A 4746 4747 4647 8146" $"0245 4646 8145 0244 4545 8044 0343 4D68" $"2584 0002 4223 1380 0005 010D 73AA C9D3" $"82D4 85D5 94D6 06D4 C7C0 C1C1 C0BE 80B5" $"01B6 B581 B60C B7A2 1A14 1515 1617 2A46" $"5254 5480 5382 5201 5151 8050 074F 5050" $"4847 4647 4780 4605 4546 4645 4646 8145" $"0144 4581 4403 4D4E 6818 8400 0245 281E" $"8100 040B 6DA8 C7D2 81D3 84D4 95D5 02D6" $"D3C6 81C0 02BE B4B4 84B5 1AB6 A21A 1414" $"1516 1629 4550 5251 5050 4F4E 4E4D 4C4B" $"4A49 4746 4544 8042 0144 4582 4683 4584" $"4405 4343 4457 5068 8500 021F 2B30 8000" $"0401 0865 A5C5 80D2 83D3 86D4 02D5 D5D4" $"8DD5 0BD3 C6BF C0C0 BFBE B4B4 B5B5 B481" $"B504 B6A1 1912 1280 130C 243B 4546 4443" $"4241 403F 3E3D 3D83 3C07 3B3C 3C3D 3E41" $"4344 8045 0146 4680 4500 4480 4580 4405" $"4344 4460 5170 8500 0227 3333 8000 0501" $"075D A2C3 D182 D201 D3D2 83D3 02D4 D4D3" $"8CD4 80D3 05D2 D2D0 C3C0 C080 BF00 B885" $"B403 B5A1 110A 800B 030C 1A2F 3881 3C0A" $"3B3C 3C3B 3C3C 3B3C 3C3B 3C85 3B04 3D3F" $"4143 4481 4502 4445 4581 4405 4344 4443" $"4E79 8500 022E 3D1C 8100 0406 56A0 C1D0" $"82D1 8BD2 80D1 0ED0 D0CF CFCE CDCC CCCB" $"C9C8 C7C5 C4C1 83BF 05BE BCB7 B4B3 B380" $"B40A B5A0 0F08 090A 0A0C 1A2E 388C 3B87" $"3A05 3B3C 3D40 4243 8344 8143 0344 4E4D" $"6E85 0002 143B 2C80 0006 0104 4E9D BFCF" $"D084 CF14 CECE CDCD CCCC CBCA C9C8 C7C5" $"C4C3 C1C0 BFBE BDBC BB83 BA04 B9BA BBBD" $"BE81 BF03 BEBF BCB7 80B4 0CB3 B4A0 0E08" $"0809 0A0B 1A2E 373A 803B 0C3A 3B3B 3A3B" $"3B3A 3B3B 3A3B 3B3A 803B 873A 053C 3E40" $"4243 4380 4405 4343 4458 4F50 8600 0249" $"2B0F 8000 1502 4595 B8C8 C8C7 C6C5 C4C3" $"C2C0 BFBE BCBB BABA B9B8 B883 B786 B883" $"B903 BABB BDBE 80BF 80BE 0FBD B8B4 B3B4" $"9F0E 0708 0909 0B1A 2E37 3A80 3B88 3A04" $"3939 3838 3980 3A05 393A 3A39 3A3A 8139" $"033A 3C3F 4081 4203 4359 545B 8600 0262" $"1D1E 8100 0237 85A5 81B5 83B4 83B5 85B6" $"84B7 86B8 06B9 B9BA BDBE BFBF 81BE 0EBD" $"B8B5 9F0C 0707 0809 0A1A 2D36 3A3A 8039" $"0338 3837 3780 3681 3580 3402 3536 3884" $"390F 3838 3736 3534 3332 3130 2F2D 3759" $"5665 8600 0333 2316 1180 0004 2E7D 9FB0" $"B283 B383 B482 B501 B6B5 83B6 84B7 02B8" $"B8B7 83B8 02B9 BABC 83BE 0BBD BDA6 1C02" $"0406 0708 1729 3185 3403 3534 3435 8434" $"0133 3282 3112 2F2D 2A27 2421 1E1B 1C2A" $"3C25 373C 394F 4759 4C86 000A 0941 1C22" $"0400 0027 7A9D AF82 B282 B383 B484 B584" $"B600 B780 B601 B7B6 80B7 86B8 01B7 B680" $"B40A 9E08 0101 0002 0516 2830 3380 3482" $"3323 3231 302F 2E2C 2B28 2624 211E 1B17" $"1310 0D0B 1C4D 3133 4A37 4C4E 332E 3232" $"3641 445B 6E11 8700 092C 2F16 1C00 0022" $"779B AE82 B182 B283 B386 B403 B3B3 B2B2" $"80B1 80B0 02AF B1B5 83B7 02B4 B2B2 82B1" $"02B3 9E09 8002 1901 010F 242D 302F 2E2C" $"2A28 2624 211E 1B18 1411 0E0C 0907 0603" $"0280 0181 000F 0F2A 3637 2B33 3F51 5D77" $"9841 4034 1F0B 8800 0A26 4F26 270A 001D" $"7399 ADB0 83B1 82B2 01B1 B180 B001 AFAF" $"85AE 01AF AE82 AF26 B0AF B0B0 B2B6 B7B6" $"B7B6 B1B1 B0AF ADAB A8A5 A278 0403 0302" $"0302 060F 1818 1512 0F0C 0A08 0605 0482" $"030C 0202 0303 0100 0101 0001 0100 0180" $"000B 0F29 4048 4451 5F70 8474 4310 8800" $"0C30 512C 2118 2400 186F 96AB AEAE 80AD" $"80AC 82AB 82AC 01AD AC80 AD02 AEAE AD81" $"AE00 AF81 AE12 ADAC AAA9 A6A6 A5A1 9B90" $"8A83 7B72 695E 5348 1784 0380 048C 031C" $"0203 0301 0001 0100 0101 0204 050A 0C10" $"1719 2E4F 5F5A 4F56 606E 8174 3B86 000C" $"552C 2829 1729 0011 668E A4A8 A882 A981" $"AA83 AB84 AC1E ABAA A8A6 A4A1 9D99 948E" $"8881 7A71 685F 544A 4551 3028 221E 2026" $"2C2C 1808 0495 030F 0408 0909 0E10 181C" $"2229 2B31 3336 3939 813A 0939 405A 6161" $"5A62 6B7A 6985 0003 5328 2A01 8002 070E" $"628C A3A8 A8A9 A880 A982 AA2C A9A8 A7A6" $"A4A1 9E9A 9691 8B85 7F77 7067 5E54 4940" $"372E 251D 170F 0A06 0402 002F 0F10 1112" $"141B 2630 342B 1708 0588 0410 0505 060A" $"0B11 141A 2124 2D30 363A 383A 3B8F 3C06" $"4462 6C63 6673 0D84 0003 512A 1F02 8003" $"230E 5B89 A1A7 A6A5 A4A3 A09E 9B97 938E" $"8983 7C75 6E65 5C53 4A40 372E 261E 1813" $"0E0A 0807 0581 0400 0385 001C 0811 1213" $"1316 1F2A 3236 2C16 0A06 0607 0B0D 1017" $"1921 262C 3335 3A3C 3E83 4002 4141 3E85" $"3D12 3E3E 3F41 4345 474A 4D50 5255 5758" $"566E 637D 1A84 0003 4D23 2102 8004 2305" $"2F6C 8486 807A 736C 645B 5249 4037 2F27" $"2019 140F 0C09 0707 0504 0505 0405 0504" $"0505 0481 0501 0401 8500 1203 0E13 1314" $"1519 232D 3539 3834 3436 393D 3F40 8241" $"8742 1043 4340 4041 4345 474A 4C4F 5254" $"5658 5859 815A 0859 5958 5758 526B 771B" $"8400 0354 1909 0181 040D 0923 312F 2620" $"1914 100C 0A07 0606 9605 1704 0100 0308" $"0B19 202D 414A 635F 2314 1516 171C 2731" $"383D 418A 430D 4445 4648 4B4E 5055 5855" $"5658 595A 805B 005C 805B 0F5A 5958 5655" $"5452 5150 4F4E 4E4B 7071 1B84 0004 481B" $"1D00 0382 0500 068A 0502 0606 0580 064D" $"0506 0605 0606 0506 0605 070E 111B 2A31" $"4854 6377 8092 9AA3 ADAB AEAF B0B0 A85C" $"1815 1617 1920 2A34 3A3F 4344 4445 4648" $"4A4D 4F52 5659 5C5F 6163 6465 666A 6961" $"5F5F 5E5C 5B59 5756 5453 5150 4F4F 824E" $"814D 034C 5674 1C84 000A 351D 2E00 0205" $"0606 0506 058F 0613 0707 0B15 172B 3243" $"5A64 7E87 96A4 A9B3 B6B8 B8B5 80B4 80B5" $"2BB2 B3B5 B8BD C2C8 B243 1617 1819 1B23" $"2E36 3C45 575E 6063 6466 696C 6F72 7576" $"7674 716E 6B6A 6558 5553 5250 5081 4F84" $"4E80 4D00 4C80 4D03 5655 6D0E 8400 0542" $"2121 0001 048A 0615 0709 0A15 1A25 383F" $"5963 798B 94A5 ABB1 B8B8 B9B9 BABA 80BB" $"31BC BCBD BEBC BEC3 C8CE D4DA DADF E4E6" $"E8E9 EAEB E239 1717 1819 1A1E 2632 4DA5" $"AA96 9794 9089 8179 716A 6460 5D5C 5B5A" $"5C5A 5080 4F85 4E84 4D81 4C03 4D61 576A" $"8500 0651 2619 0000 0306 8007 280A 0C12" $"1E22 3640 5167 7089 929F AAAF B5B7 B8B8" $"B9B9 BABA BBBB BCBC BEC0 C4C8 CED4 DAE1" $"E8EF F3F0 EEF0 81F1 1BE7 E6E4 E3E1 DFDD" $"DBD8 6817 1718 191A 1B1C 274A 809F 7268" $"625E 5C5B 5B81 5A06 595A 5959 5C59 5080" $"4F02 4E4F 4F83 4E01 4D4E 824D 814C 0268" $"5773 8500 4A29 242A 0000 0107 2353 7082" $"9399 A7AD B1B6 B6B7 B7B8 B8B9 B9BA BABB" $"BCBE C1C5 CAD0 D6DD E4EA F0F5 F9FC FDFE" $"FEFF FFFE FEF4 ECEA E8E5 E3E0 D3D0 CCCA" $"C7C5 C3C2 C164 1617 1819 1A1A 1B24 4655" $"805B 025A 5B5B 805A 0259 5A5A 8159 085C" $"594F 4E4F 4F4E 4F4F 804E 024D 4E4E 814D" $"024C 4D4D 814C 024D 577C 8500 2029 2B34" $"0000 011E 6493 AFB6 B6B7 B7B8 B9B9 BABB" $"BEC1 C6CB D1D8 DFE6 ECF2 F6FA FCFD 86FE" $"0DFC FAF8 F5F2 EDDD D3D1 CECD CBCA BF84" $"BE0C BF63 1617 1819 191A 1B24 4655 5B82" $"5A85 5904 5859 5B58 4F84 4E84 4D83 4C05" $"4B4B 4C57 576C 8500 1733 3417 0000 0114" $"5582 A6BB C1C6 CCD2 D9E0 E7ED F2F7 FAFC" $"FD80 FE80 FF12 FEFF FFFE FBF9 F6F3 EFEB" $"E7E4 E2E0 DEDD DDDB CE82 C804 C9BE BDBE" $"BD82 BE0C 6216 1718 1819 1A1B 2446 545B" $"5B81 5A02 595A 5A80 5900 5880 5904 5B58" $"4F4E 4F81 4E02 4D4E 4E80 4D00 4C80 4D80" $"4C00 4B80 4C02 6257 5285 0002 1D39 2880" $"000A 0835 73BD EDF6 F9FA FCFC FD81 FE0F" $"FFFF FEFE FCF9 F6F3 EFEB E7E3 E0DE DDDC" $"84DB 80DC 02DA CEC7 82C8 82BD 0EBE BEBD" $"BE62 1617 1718 191A 1B24 4654 805A 0459" $"5A5A 595A 8159 0658 5959 585B 574F 804E" $"044D 4E4E 4D4E 814D 024C 4D4D 814C 064B" $"4C4B 4C62 575A 8500 0202 433A 8000 0503" $"187B D5F5 FD80 FE0B FDFC F8F6 F1EE EAE6" $"E2DE DCDB 80DA 80D9 88DA 80DB 01DA CE83" $"C700 BD81 BC81 BD0B 6216 1618 1819 1A1A" $"2446 545A 8559 8458 035B 574E 4E85 4D84" $"4C83 4B03 4C4F 5863 8500 1203 531B 0100" $"0001 0B77 C1E2 ECE8 E4E0 DDDB DAD9 83D8" $"01D9 D884 D902 DADA D984 DA80 DB01 D9CE" $"83C7 00BD 81BC 0EBD BDBC BD61 1616 1718" $"191A 1A24 4654 805A 8059 0558 5959 5859" $"5981 5807 5A56 4E4D 4E4E 4D4E 814D 024C" $"4D4D 814C 014B 4C82 4B02 5958 4985 000A" $"035B 1C0B 0000 0106 64AA CC82 D601 D7D6" $"80D7 02D8 D8D7 81D8 02D9 D9D8 84D9 01DA" $"D984 DA07 D9CE C6C7 C7C6 C7C7 86BC 0A61" $"1516 1718 1919 1A25 4654 8359 0258 5959" $"8058 0057 8058 055A 554E 4D4E 4E80 4D04" $"4C4D 4D4C 4D82 4C80 4B00 4A80 4B02 6559" $"3A86 0009 3C24 1500 0001 045C A7C9 81D5" $"83D6 84D7 86D8 86D9 02DA D9CD 83C5 00BC" $"84BB 0BBC 6015 1617 1818 191A 2546 5380" $"5985 5881 5703 585A 554E 814D 854C 834B" $"824A 025F 5A41 8600 0A4B 2817 0000 0103" $"53A4 C7D4 80D5 83D6 02D7 D7D6 81D7 02D8" $"D8D7 83D8 02D9 D9D8 84D9 08D8 CDC4 C5C5" $"C4C5 C5BC 85BB 0A60 1516 1718 1819 1A25" $"4653 8059 0258 5959 8058 0257 5858 8157" $"025A 544E 804D 044C 4D4D 4C4D 814C 064B" $"4C4B 4B4A 4B4B 804A 0349 525B 4986 000A" $"5B1A 0F00 0001 024B A1C5 D483 D502 D6D6" $"D580 D602 D7D7 D682 D704 D8D7 D8D8 D783" $"D881 D901 D8CD 83C4 00BB 80BA 82BB 0D60" $"1516 1717 1819 1A25 4653 5859 5980 5805" $"5758 5857 5858 8157 0159 5481 4D02 4C4D" $"4D80 4C02 4B4C 4C81 4B02 4A4B 4B80 4A03" $"475E 5F25 8600 0A46 191F 0000 0102 429D" $"C3D3 80D4 83D5 83D6 80D7 00D6 83D7 02D8" $"D8D7 84D8 08D7 CDC3 C4C4 C3C4 C4BB 85BA" $"0C5F 1516 1617 1819 1A25 4653 5859 8158" $"0257 5858 8057 0056 8057 0759 534D 4C4D" $"4D4C 4D81 4C02 4B4C 4C81 4B80 4A06 494A" $"4A46 6C63 1D86 0002 381B 3280 0005 013B" $"99C1 D3D3 84D4 84D5 86D6 87D7 02D8 D7CD" $"83C3 00BA 84B9 0DBA 5F15 1516 1718 1919" $"2546 5358 5886 5781 5602 5759 5283 4C84" $"4B83 4A80 4904 4A45 6768 2186 000A 461F" $"1000 0001 0133 96BF D280 D383 D484 D586" $"D605 D7D7 D6D7 D7D6 81D7 01D6 CC80 C303" $"C2C3 C3BA 85B9 0A5E 1415 1617 1818 1925" $"4653 8058 0257 5858 8057 0256 5757 8056" $"0357 5952 4D83 4C01 4B4C 814B 024A 4B4B" $"814A 8049 034C 526D 2586 000A 4823 1D00" $"0001 012C 92BC D181 D301 D4D3 83D4 85D5" $"01D6 D588 D605 D7D7 D6CC C2C3 81C2 00BA" $"80B8 82B9 0D5E 1415 1617 1818 1925 4653" $"5758 5883 5701 5657 8156 0257 5851 814C" $"024B 4C4C 804B 024A 4B4B 814A 0249 4A4A" $"8049 0355 5369 0B86 0002 2625 2F80 0004" $"0124 8EBA D081 D284 D385 D48A D580 D601" $"D5CC 80C2 04C1 C2C2 B9B7 84B8 0A5E 1415" $"1616 1718 1926 4653 8257 8456 8055 0356" $"5851 4C85 4B83 4A82 4905 4848 495F 546C" $"8700 0230 2C30 8000 0401 1E89 B7CF 81D2" $"01D3 D283 D302 D4D4 D381 D405 D5D5 D4D5" $"D5D4 86D5 04D6 D5CC C1C2 81C1 03B9 B7B8" $"B782 B80A 5D14 1515 1617 1819 2646 5380" $"5704 5657 5756 5781 5609 5556 5556 5850" $"4C4B 4C4C 804B 024A 4B4B 804A 0049 804A" $"8049 0548 4949 5353 7487 0002 3A34 1B80" $"0007 0118 85B5 CED1 D2D1 83D2 83D3 80D4" $"00D3 84D4 04D5 D4D5 D5D4 81D5 01D4 CC83" $"C100 B985 B70A 5C14 1415 1617 1818 2646" $"5380 5701 5657 8156 0255 5656 8055 0556" $"5750 4C4B 4C81 4B02 4A4B 4B80 4A02 494A" $"4A81 4905 4848 494D 527C 8700 021C 382A" $"8000 0401 137F B2CC 83D1 86D2 87D3 88D4" $"01CB C182 C000 B884 B60B B75B 1314 1516" $"1718 1826 4652 8356 8555 0354 5657 4F80" $"4B84 4A84 4982 4803 4956 5356 8700 020A" $"433F 8100 060E 79AF CBD1 D1D0 81D1 01D2" $"D183 D288 D304 D4D3 D4D4 D381 D401 D3CB" $"83C0 00B8 85B6 0A5B 1314 1516 1717 1826" $"4652 8356 0255 5656 8055 0554 5555 5656" $"4F81 4B01 4A4B 814A 0249 4A4A 8149 8048" $"0547 4849 6254 5787 0003 0C53 1802 8000" $"030B 73AC CA80 D002 D1D1 D083 D185 D204" $"D3D2 D3D3 D288 D300 CB80 C003 BFC0 BFB8" $"80B5 82B6 0A5B 1314 1516 1617 1826 4652" $"8056 0255 5656 8355 0954 5554 5656 4E4B" $"4A4B 4B80 4A02 494A 4A84 4980 4805 4748" $"4859 5460 8700 030A 5421 0980 0003 086B" $"A9C8 80CF 84D0 87D1 8BD2 02D3 D2CA 83BF" $"01B7 B484 B50A 5A13 1414 1516 1718 2646" $"5285 5584 5402 5555 4D82 4A84 4983 4881" $"4703 484E 556A 8800 023E 2C10 8000 0306" $"64A6 C680 CF02 D0D0 CF83 D002 D1D1 D084" $"D105 D2D2 D1D2 D2D1 85D2 00CA 80BF 06BE" $"BFBE B7B4 B5B4 82B5 0A5A 1313 1415 1617" $"1727 4652 8056 8055 0254 5555 8354 0356" $"564D 4B80 4A02 494A 4A80 4902 4849 4981" $"4801 4748 8047 0348 5955 4588 0002 4D22" $"0A80 0006 045C A3C4 CFCF CE81 CF01 D0CF" $"84D0 02D1 D1D0 89D1 81D2 01D1 CA83 BE00" $"B685 B40A 5A13 1314 1516 1617 2746 528B" $"5504 5455 544D 4B80 4A01 494A 8149 0248" $"4949 8148 8047 0546 4747 6656 4188 0002" $"5E19 1080 0003 0354 A0C2 83CE 86CF 8AD0" $"02D1 D1D0 82D1 01CA BE82 BD00 B684 B30B" $"B459 1213 1415 1616 1727 4651 8155 8056" $"0D55 5554 5453 514F 4D4C 4B4C 4C4B 4A81" $"4983 4883 4781 4602 5557 4988 0002 3619" $"2480 0004 024C 9DC0 CD83 CE01 CFCE 84CF" $"02D0 D0CF 8ED0 00C9 83BD 00B5 85B3 0A59" $"1213 1415 1516 1728 4753 8056 0855 5453" $"5250 4E4C 4A48 8047 0646 4748 4B4C 4C4A" $"8049 0148 4981 4801 4748 8247 0546 4645" $"5257 5188 0002 401C 3480 0003 0244 9ABE" $"80CD 02CE CECD 83CE 02CF CFCE 85CF 07D0" $"CFD0 D0CF D0D0 CF82 D000 C980 BD03 BCBD" $"BCB5 80B2 82B3 1058 1313 1415 1617 1727" $"4650 5250 4E4C 4A49 8047 0F46 4747 4647" $"4746 4746 4649 4B4B 4A49 4980 4802 4748" $"4881 4701 4647 8046 0344 5D5B 2188 0002" $"4E20 0E80 0006 013C 96BC CCCD CC81 CD01" $"CECD 85CE 04CF CECF CFCE 8BCF 00C9 83BC" $"00B5 85B2 0058 8013 8114 0E22 3C45 4847" $"4746 4747 4647 4746 4747 8546 0447 4A4B" $"4B49 8048 0147 4882 4780 4605 4546 426B" $"5E26 8800 0248 2120 8000 0401 3592 BACB" $"83CC 86CD 8CCE 81CF 02D0 C9BC 82BB 00B4" $"85B1 0A57 1010 0F0F 1010 111E 3843 8B46" $"8445 0546 484A 4A49 4881 4782 4680 4504" $"4642 5D62 2C88 0002 2B23 3280 0006 012E" $"8FB8 CACC CB83 CC87 CD02 CECE CD83 CE81" $"CF00 D080 CF01 C7BD 82BB 00B6 85B1 0F54" $"0C0D 0E0E 0F10 101F 3842 4647 4746 4784" $"4605 4546 4645 4646 8245 0447 494A 4A48" $"8047 0C46 4746 4645 4646 4545 4950 6731" $"8800 0235 291D 8000 0401 278B B5C9 80CB" $"01CC CB84 CC01 CDCC 83CD 80CE 81CF 0BCE" $"CECD CCCB C9C7 C5C1 BFBC BB81 BA00 B484" $"B00A 540C 0D0D 0E0F 0F10 1F38 4283 4608" $"4546 4645 4646 4546 4681 450B 4445 4544" $"4545 4849 4A48 4747 8146 8245 0351 5368" $"0488 0002 4131 1E81 0005 2086 B3C8 CACA" $"86CB 80CC 80CD 82CE 12CD CCCB CAC8 C6C4" $"C1C0 BEBE BDBE BFBF BEBB B9BA 80B9 00B3" $"83AF 0B53 0C0D 0D0E 0F0F 101F 3842 468B" $"4588 4405 4648 4949 4746 8245 0544 4445" $"5957 7089 0002 0E32 2F80 0004 011A 81B0" $"C780 CA01 CBCA 80CB 80CC 82CD 08CC CCCA" $"C9C7 C5C3 C0BF 81BD 00BC 80BD 06BC BDBD" $"BEBF BDBA 82B9 00B2 82AF 1253 0C0C 0D0E" $"0E0F 101F 3842 4546 4645 4646 4546 8145" $"0344 4545 4480 4580 440B 4344 4443 4444" $"4749 4847 4646 8145 0444 4549 5178 8900" $"0211 3E30 8000 0401 157C ADC6 80CA 01CB" $"CB82 CC08 CBCA C9C8 C6C4 C2BF BE81 BC00" $"BB89 BC1C BDBE BEBC B9B9 B8B9 B8B8 B1AF" $"AFAE AE52 0B0C 0D0D 0E0F 101F 3842 4546" $"4683 4505 4445 4544 4545 8144 0443 4444" $"4344 8243 0D45 4748 4846 4544 4544 4445" $"4B4E 7C89 0003 154A 1702 8000 0311 78AC" $"C680 CB0B CACA C9C8 C6C5 C3C0 BEBC BBBB" $"83BA 8DBB 03BC BEBD BB81 B802 B7B7 B080" $"AE0A 520B 0C0D 0D0E 0F0F 1F38 4282 4589" $"4485 4382 420C 4346 4747 4645 4444 4345" $"554F 5389 0012 0839 2506 0000 010D 72A8" $"C3C7 C5C3 C1BF BDBB BA81 B901 BAB9 85BA" $"04BB BABB BBBA 88BB 04BC BDBD BAB8 81B7" $"0EB6 AFAD AD51 0A0C 0C0D 0E0E 0F1F 3842" $"8045 0544 4545 4445 4583 4400 4380 4483" $"4301 4243 8242 0A44 4747 4645 4443 4461" $"505B 8A00 0240 2010 8000 0509 669D B6BA" $"B983 B802 B9B9 B884 B989 BA80 BB1C BABB" $"BBBA BBBB BCBD BCB9 B7B7 B6B7 B6B5 AEAD" $"510A 0B0C 0D0E 0E0F 1F38 4280 4502 4445" $"4583 4405 4344 4443 4444 8143 0242 4343" $"8042 0E41 4242 4141 4245 4646 4543 444F" $"5166 8A00 0254 1B1E 8000 0305 5A94 B084" $"B786 B88B B987 BA03 BBBC BBB8 82B6 0CB4" $"AD50 0A0B 0C0D 0D0E 0F1F 3841 8544 8743" $"8542 8641 0743 4546 4545 4D54 6F8A 0002" $"3324 1A80 0005 0453 91AF B7B6 83B7 02B8" $"B8B7 84B8 02B9 B9B8 8DB9 07BA B9B9 BABB" $"BBBA B682 B50B B24F 090B 0C0D 0D0E 0F1F" $"3841 8044 0843 4444 4344 4443 4444 8043" $"0042 8043 0142 4381 4202 4142 4280 410B" $"4041 4140 4041 4445 4763 583B 8A00 092A" $"3528 0300 0002 4B8E AD82 B686 B788 B804" $"B9B8 B9B9 B880 B900 B885 B902 BBBB B981" $"B50C B4B3 8313 0A0C 0C0D 0E0E 2038 4180" $"4405 4344 4443 4444 8343 0042 8043 8042" $"0241 4242 8341 8040 083F 3E3C 3734 5160" $"624A 8A00 0908 4B19 1A00 0002 448B AB80" $"B585 B68A B790 B803 BABA B8B5 80B4 0BB2" $"9260 100B 0C0D 0D0E 2038 4187 4386 4285" $"4181 400B 3D39 3238 3C44 4E51 5456 724E" $"8B00 0850 2328 0000 013D 89A9 82B5 86B6" $"80B7 00B6 87B7 01B8 B780 B806 B7B8 B8B7" $"B8B8 B781 B813 BAB9 B7B4 B3B3 B29B 6F36" $"0D0C 0D0D 0E20 3841 4344 8443 0442 4343" $"4243 8242 0241 4242 8041 1140 3E3B 3532" $"4042 4B50 4C43 444A 5564 6966 068B 0002" $"3A30 2980 0004 3685 A8B4 B483 B502 B6B6" $"B585 B604 B7B6 B7B7 B691 B711 B8B9 B8B5" $"B3B3 B1A1 8934 1B0B 0C0D 0E20 3841 8043" $"0842 4343 4243 4342 4343 8042 0041 8042" $"1541 4140 3D38 2F3B 444A 4B54 4744 494F" $"5F79 644D 391D 048D 0009 1743 1914 0000" $"3082 A5B3 81B4 02B5 B5B4 83B5 80B6 00B5" $"8AB6 07B7 B7B6 B7B7 B6B7 B783 B610 B7B8" $"B7B4 B2B1 A39F 491E 370B 0D0E 2037 4080" $"4304 4243 4342 4381 4217 4142 4241 403E" $"3A34 3142 494E 5744 4447 4E5A 6B6F 5F40" $"2B02 9300 0757 1C19 0000 2A7F A381 B387" $"B48F B582 B685 B510 B6B7 B8B6 B3B0 A2A5" $"7635 2532 0C0D 2037 4086 4280 4112 3F3B" $"3534 3E49 4853 5644 464C 5769 735E 4B35" $"0E98 0008 3C25 2600 0023 7BA1 B281 B302" $"B4B4 B383 B480 B500 B49A B510 B7B7 B5B1" $"A3A7 7268 3321 220C 2037 4043 4381 4213" $"4140 3D37 3238 474E 514D 4846 4B54 636F" $"6D51 3F21 9D00 0926 361D 0D00 1D77 9FB1" $"B284 B304 B4B3 B4B4 B387 B405 B5B5 B4B5" $"B5B4 80B5 07B4 B5B5 B4B5 B5B4 B583 B400" $"B580 B620 A4A7 5915 4621 1F1E 1F37 4042" $"4140 3E3A 3239 3C45 4E4B 4B44 4951 5D70" $"6F5B 4721 0CA1 0008 034A 1A17 0018 739D" $"B085 B289 B392 B483 B31E B4B5 BAA8 A85A" $"000D 2429 393B 2D38 3531 4242 4C4F 4B43" $"444A 5364 6560 513A 0EA7 0008 4A24 2300" $"136E 9AAF B186 B202 B3B3 B288 B304 B4B3" $"B4B4 B380 B402 B3B4 B486 B31D B2AE A699" $"8793 A9A9 6000 000F 693F 3A41 3846 5244" $"4348 4F5E 7960 4837 1B02 AB00 0733 3326" $"030F 6A98 AE81 B102 B2B2 B187 B208 B3B3" $"B2B3 B3B2 B3B3 B286 B311 B2B3 B3B2 B2AF" $"A89C 8977 7677 7A8C 9899 A342 8000 0B30" $"4F41 4043 4756 666A 5C3B 28B1 0007 1A4D" $"221B 0B64 95AD 80B0 89B1 91B2 11AF A99E" $"8C7C 7574 7A86 8E81 7B78 7C85 8A64 0281" $"0006 1015 1516 151C 0BB5 0007 0157 1F1D" $"085F 93AC 81B0 02B1 B1B0 88B1 20B2 B1B2" $"B2B1 B2B2 B1B2 B2B1 B1AF AAA0 917E 7676" $"7B81 8887 7D78 787E 8278 5341 1C05 C300" $"0A3F 2829 0758 90AA AFB0 B0AF 83B0 02B1" $"B1B0 80B1 00B0 85B1 14AF ABA3 957F 7876" $"767E 8A88 7E7A 777C 8A77 613F 260D C800" $"0619 3B2A 1051 8DA9 87AF 87B0 14AF ACA4" $"9885 7378 767D 8986 817A 7779 8382 6E49" $"320C CD00 0A07 502A 2D48 8AA7 AEAF AFAE" $"86AF 17B0 AFAF ACA5 9A89 7474 7376 838D" $"817B 7878 808F 7057 3214 02D2 0005 4935" $"3F41 87A6 84AE 17AF AFAE AEAB A69C 8C7A" $"7171 7681 8D7F 7976 777F 8379 623D 23D8" $"0005 3543 593D 83A4 83AD 14AB A79E 8F7C" $"7373 767B 8686 7A76 767A 827D 5845 2009" $"DC00 1B12 5B55 4D7F A2AC ABA7 9F92 7E74" $"7273 7A85 867C 7775 7985 7A66 442D 13E2" $"0016 5159 6A63 8382 706F 7379 8284 7F78" $"7577 7F83 734E 3910 02E6 0011 4164 6B72" $"737B 877D 7674 757D 9173 5C38 1C05 DD00" $"8200 470E 4B55 3731 3939 353C 464D 5759" $"412C 292C 3135 3A3E 3B31 2926 2A2E 3337" $"3A35 2F29 262C 3238 3E40 3A32 2A29 3139" $"424A 4E48 3F35 3340 4D5A 686E 6C67 582B" $"3943 4D5F 4106 0000 091E 3C80 3A09 3B3C" $"3E40 4142 4237 0808 8109 020A 0A06 9F00" $"0906 3E61 3727 2636 2C1B 1D83 1C51 1F24" $"292E 3438 3F41 2C25 2B31 373D 434B 4E2C" $"292E 353B 434A 5151 292A 2F38 3F48 5058" $"592F 292A 3035 3B41 4340 2D28 282E 353C" $"4661 7E83 85A5 979C ADBF D1DD DFE0 E1E0" $"DEDB D8D8 D9DB DDDF DFDE DBC8 A9AB ADAF" $"80B2 14B0 9F73 7577 797B 7C7C 7B62 3F41" $"4345 4849 4A4B 3910 8200 2616 673F 2A20" $"2928 0C17 3282 817E 7A73 6C65 5E59 5550" $"4D4A 4742 3D38 3330 2C2A 2726 2423 2221" $"2120 811F 831E 811D 2821 2529 2D30 3538" $"3920 252D 333D 434D 546E 7572 727A 8CA9" $"C2D7 DFE2 E3E4 E5E5 E2E1 E2E2 E3E4 E5E5" $"E4E2 84E1 01DF DE83 DC21 DBDA D7D5 D4D5" $"D6D6 D7D6 D5D4 D1D1 7602 0000 0C62 2F20" $"2B2A 0700 0B15 45F1 F8FA FBFC 86FE 3BFC" $"F9F6 F4F1 EFEE ECEA E3DB D4CE C9C4 C0B7" $"ADA5 9F98 8F85 7C71 665D 544C 4640 3B36" $"3330 2E2D 2B2A 2928 2725 435E 707B 7480" $"7573 91D4 EBEB EAEA E9E8 E680 E52C E4E4" $"E3E2 E2E0 DDDC DDDD DEDE DFDF DDD8 D8D9" $"D9DA DADB DBD8 D3D3 D4D5 D6D7 D9D9 D8D5" $"D5D4 CC31 0000 0B46 1F31 0E80 0008 101E" $"33BD D4D6 D8DA DC82 DD49 DCDB DAD9 D7D6" $"D4D1 CFCD CBC8 C5C2 BFBC B9B6 B3B0 ADAA" $"A6A3 9E9A 9690 8B85 7F7A 7570 6B66 615C" $"5752 4D48 433E 3A2D 1E58 5A59 5754 5259" $"9DDD FDFB FBFA FAF8 F7F6 F5F3 F1EF EEED" $"ECEB EAEA 80E9 80E8 80E7 81E6 80E5 20E4" $"E3E2 E1E0 DFDD DCDA D9D4 CFC5 3D00 000A" $"3A3B 0400 0001 0115 293C BAD4 D6D8 D9DB" $"81DC 49DB DAD9 D7D5 D2CF CCC8 C4BF BBB7" $"B2AD A8A2 9D98 928D 8882 7D78 736E 6964" $"5D53 4F4B 4845 423F 3934 312E 2C2A 2826" $"2520 1738 3A38 3635 3546 92CD FEFA F7F4" $"F0ED EAE8 E6E3 E2E0 DEDD DBDA D980 D882" $"D782 D601 D5D5 82D4 80D5 80D6 09D7 D4C6" $"C23D 0000 0B3F 1F80 000B 0102 152C 3CAE" $"CDCF D1D2 D4D4 80D5 4ED4 D3D2 D0CF CCC9" $"C6C2 BFBB B7B3 AEAA A5A1 9C97 928D 8984" $"7F7B 7672 6E6A 6658 4D4A 4743 413A 3230" $"2D2B 2927 2624 231E 162E 3234 3537 384E" $"A0D8 FEFE FDFC F9F7 F4F1 EEEB E9E7 E5E4" $"E2E1 DFDF DCD1 CECE 88CD 13CC CCCB CBCA" $"CAC9 C9C8 C7C7 C9BD C03F 0000 0C3C 2D80" $"0064 0102 132B 3AA1 C3C5 C7C9 CACB CBCC" $"CBCB CAC9 C7C5 C3C0 BDBA B7B4 B0AC A8A4" $"A09B 9792 8E8A 8581 7C78 7470 6C69 6458" $"4B47 4441 3E36 2F2D 2B29 2726 2423 221E" $"162B 2F30 3233 354A 9AD4 FEFD F9F5 F2EF" $"ECE9 E7E5 E3E1 DFDE DDDC DBDB DED8 D2D1" $"D1D0 CFCE CDCD CC80 CB80 CA80 C980 C80B" $"C7C7 C6C5 BFBC 4000 000E 423E 8000 0A01" $"0111 2A38 93BA BCBD BFC0 82C1 53C0 BFBD" $"BBBA B7B5 B2AF ACA8 A4A1 9D99 9591 8D88" $"8480 7C78 7470 6C69 6661 5548 4542 3F3C" $"342D 2B2A 2826 2523 2221 1D16 2B2F 3132" $"3335 4B9B D5FE FBF7 F4F1 EEEB E9E7 E5E3" $"E1E0 DEDD DCDB DCDC D4CE CDCD CCCD CCCB" $"CC80 CB04 CAC9 CAC9 C980 C880 C70B C6C6" $"C3C2 BA42 0000 114E 1B01 8000 0901 0F29" $"3687 B1B3 B5B6 B781 B84C B7B7 B6B4 B3B1" $"AFAC AAA7 A4A1 9D9A 9693 8F8B 8783 7F7B" $"7874 706C 6966 635F 5345 4240 3D3B 322C" $"2A28 2725 2423 2120 1D16 2B2F 3032 3335" $"4B9B D5FE F9F5 F2EF ECEA E7E5 E3E2 E0DF" $"DEDC DBDA DCDC D380 CD01 CCCC 80CB 81CA" $"81C9 01C8 C880 C71A C6C6 C5C1 BAB9 4600" $"000F 5323 0600 0001 010D 2835 7CA9 ABAC" $"ADAE AF80 B04E AFAE ADAC ABA9 A7A5 A2A0" $"9D9A 9793 908D 8985 827E 7B77 7370 6C69" $"6663 605C 5143 403E 3B39 312A 2927 2624" $"2322 2120 1D16 2B2F 3032 3335 4C9B D5FE" $"F6F3 F0ED EBE8 E6E4 E2E1 DFDE DDDC DBDA" $"DBDB D2CD CD80 CC81 CB01 CACA 82C9 80C8" $"80C7 05C5 C5C0 BDB8 3B80 000F 3F2F 0C00" $"0001 010B 2734 72A1 A3A4 A5A6 82A7 4EA6" $"A5A4 A3A1 9F9D 9B98 9693 908D 8A87 8380" $"7D79 7673 6F6C 6966 6360 5D5A 4F41 3E3C" $"3A37 2F29 2826 2523 2221 201F 1C16 2A2F" $"3032 3335 4C9C D5FE F4F1 EEEB E9E7 E5E3" $"E1E0 DFDD DCDB DAD9 DBDA D2CD CCCC 80CB" $"80CA 02C9 CACA 80C9 80C8 09C7 C6C7 C6C4" $"C5BE C1BA 1180 0002 4D25 0880 0008 0109" $"2633 689A 9C9D 9E80 9F00 A080 9F4C 9E9C" $"9B9A 9896 9492 8F8D 8A87 8481 7E7B 7875" $"726F 6B68 6562 605D 5A57 4D3F 3C3A 3836" $"2E28 2625 2422 2120 1F1F 1C16 2A2E 3031" $"3334 4D9C D5FD F2EF ECEA E7E5 E3E2 E0DF" $"DEDC DBDB DAD9 DADA D1CC CC80 CB80 CA81" $"C980 C881 C708 C6C6 C5C4 C5BC C6BC 1280" $"000F 5F18 0F00 0001 0108 2532 6093 9596" $"9797 8298 4D97 9695 9493 918F 8D8B 8987" $"8482 7F7C 7976 7370 6E6B 6865 625F 5D5A" $"5855 4B3D 3A38 3634 2D26 2524 2322 2120" $"1F1E 1B16 2A2E 3031 3334 4D9C D5FC EFED" $"EAE8 E6E4 E2E1 DFDE DDDC DBDA D9D8 DAD9" $"D0CC CC80 CB81 CA80 C981 C880 C708 C6C5" $"C5C4 C5B8 C0BD 1380 000E 3918 2300 0001" $"0106 2431 588D 8E8F 9083 914B 9090 8F8E" $"8C8B 8987 8583 817F 7C7A 7774 726F 6C6A" $"6764 625F 5C5A 5856 5349 3B39 3735 332C" $"2524 2322 2120 1F1E 1E1B 162A 2E30 3132" $"344D 9CD5 FBED EBE9 E6E4 E3E1 E0DE DDDC" $"DBDA D9D9 D8DA D9CF 80CB 80CA 82C9 81C8" $"80C7 09C6 C5C5 C4C4 C5BA BEB9 1180 000F" $"401B 3400 0001 0105 2331 5186 8889 8A8A" $"828B 4B8A 8988 8786 8583 8280 7E7C 7A77" $"7572 706E 6B69 6664 615F 5C5A 5855 5351" $"4839 3735 3332 2A24 2322 2120 1F1E 1E1D" $"1B16 2A2E 2F31 3234 4E9C D5FA EBE9 E7E5" $"E3E1 E0DF DDDC DBDA D9D9 D8D7 D9D8 CE80" $"CB80 CA80 C982 C804 C7C7 C6C6 C580 C404" $"C3C5 BCBE 9D81 0002 4E1F 0E80 0009 0104" $"2130 4B80 8283 8384 8185 4F84 8483 8281" $"807F 7E7C 7A78 7775 7270 6E6C 6967 6563" $"605E 5C59 5755 5351 4F46 3735 3432 302A" $"2322 2120 1F1F 1E1D 1D1B 162A 2D2F 3132" $"344E 9DD5 F9E9 E7E5 E3E2 E0DF DDDC DBDA" $"DAD9 D8D7 D7D9 D7CE CBCA CA81 C981 C881" $"C702 C6C6 C580 C405 C3C3 C5BF BE9F 8100" $"0F4B 201E 0000 0101 031F 2F46 7A7C 7D7E" $"7E82 7F4B 7E7E 7D7C 7B7A 7877 7574 7270" $"6E6C 6A68 6664 615F 5D5B 5957 5553 514F" $"4D44 3634 3231 2F29 2221 201F 1F1E 1D1D" $"1C1A 1629 2D2F 3032 334F 9DD5 F8E7 E5E4" $"E2E0 DFDE DDDB DADA D9D8 D7D7 D6D8 D7CD" $"80CA 80C9 04C8 C9C8 C7C8 81C7 02C6 C5C5" $"80C4 05C3 C3C5 B7BD A281 000D 2B20 3100" $"0001 0103 1D2F 4274 7778 8079 017A 7A80" $"794C 7877 7776 7473 7271 6F6D 6C6A 6866" $"6462 605E 5C5A 5856 5452 514F 4D4C 4334" $"3231 302E 2821 201F 1F1E 1D1D 1C1C 1A16" $"292D 2F30 3234 4F9D D5F7 E6E4 E2E0 DFDE" $"DDDC DBDA D9D8 D7D7 D6D6 D8D6 CCCA CA81" $"C980 C809 C7C8 C7C6 C7C6 C5C4 C5C4 80C3" $"04C2 C5B7 BCA0 8100 0236 261E 8000 0701" $"021B 2E3F 6E72 7385 744C 7372 7271 706F" $"6D6C 6B69 6866 6462 615F 5D5B 5957 5654" $"5250 4F4D 4C4A 4233 3130 2E2D 2720 201F" $"1E1D 1D1C 1C1B 1A16 292D 2F30 3233 4F9D" $"D5F6 E4E2 E1DF DEDD DBDB DAD9 D8D7 D7D6" $"D6D5 D8D6 CCC9 C982 C881 C780 C600 C580" $"C480 C305 C2C2 C5B8 BC70 8100 0D41 2D19" $"0000 0101 0219 2D3C 686E 6E85 6F27 6E6E" $"6D6C 6B6A 6968 6765 6462 615F 5D5C 5A58" $"5755 5352 504E 4D4B 4A49 4132 302E 2D2C" $"261F 1F1E 1D1D 801C 1F1B 1916 292D 2E30" $"3133 509D D5F5 E2E1 DFDE DDDC DBDA D9D8" $"D7D7 D6D6 D5D5 D7D5 CB80 C980 C883 C780" $"C580 C480 C305 C2C2 C5BC BB73 8100 0E13" $"322D 0000 0101 0217 2D3A 6369 6A6A 846B" $"266A 6A69 6867 6665 6463 6260 5F5D 5C5A" $"5957 5654 5251 4F4E 4C4B 4A48 473F 312F" $"2D2C 2B25 1F1E 1D1D 801C 191B 1B19 1629" $"2D2E 3031 3350 9DD4 F3E1 DFDE DDDC DBDA" $"D9D8 D7D7 D680 D503 D4D7 D4CA 82C8 81C7" $"06C6 C6C5 C4C5 C4C4 82C3 05C2 C1C5 B5BA" $"7681 0002 163D 3D80 0008 0102 152C 385E" $"6566 6683 6780 6640 6564 6362 6160 5F5E" $"5D5C 5A59 5756 5553 5250 4F4D 4C4B 4948" $"4746 3E30 2D2C 2B2A 251E 1D1D 1C1C 1B1B" $"1A1A 1916 292C 2E2F 3133 519E D4F1 DFDE" $"DDDB DADA D9D8 D7D7 D680 D506 D4D4 D6D4" $"CAC8 C881 C780 C601 C5C5 81C4 80C3 80C2" $"05C1 C1C4 B4B8 7981 0002 1A49 1880 0007" $"0101 132B 3759 6262 8563 2662 6261 6160" $"5F5E 5D5C 5B5A 5857 5655 5352 514F 4E4D" $"4B4A 4948 4646 453D 2F2C 2B2B 2A24 1D1D" $"1C1C 801B 191A 1A19 1628 2C2E 2F31 3251" $"9ED4 EFDE DCDB DADA D9D8 D7D7 D6D5 D580" $"D405 D3D6 D3C9 C8C8 81C7 01C6 C680 C581" $"C480 C380 C205 C1C1 C3B6 B844 8100 0C13" $"4A27 0200 0001 0110 2A36 545E 805F 8160" $"805F 245E 5E5D 5C5C 5B5A 5958 5756 5553" $"5251 504F 4D4C 4B4A 4947 4645 4444 3C2E" $"2B2B 2A29 241D 1C1C 801B 191A 1A19 1915" $"282C 2E2F 3032 519E D2EE DCDB DAD9 D9D8" $"D7D6 D6D5 D580 D404 D3D3 D6D2 C880 C702" $"C6C7 C680 C580 C403 C3C4 C3C3 80C2 80C1" $"04C0 C1BC B747 8200 0242 3804 8000 0601" $"0E29 3550 5B5B 855C 235B 5B5A 5A59 5958" $"5756 5554 5352 5150 4F4E 4D4B 4A49 4847" $"4645 4443 423C 2D2B 2A29 2823 1C80 1B80" $"1A80 191E 1528 2C2D 2F30 3252 9ED1 EDDB" $"DAD9 D8D8 D7D6 D6D5 D5D4 D4D3 D3D2 D3D5" $"D2C8 C780 C601 C5C5 82C4 81C3 80C2 80C1" $"80C0 02B7 B54B 8200 0C52 2304 0000 0101" $"0D28 344C 5858 8559 2358 5857 5756 5655" $"5453 5252 5150 4F4E 4D4C 4B4A 4948 4646" $"4544 4342 413B 2C2A 2928 2822 1C80 1B81" $"1A14 1919 1528 2B2D 2E30 3252 9ED1 EADA" $"D9D8 D7D7 D6D5 D580 D480 D306 D2D2 D5D1" $"C7C6 C681 C580 C483 C380 C280 C105 C0C0" $"BEB6 B54E 8200 0B63 1812 0000 0101 0B27" $"3349 5586 5680 5521 5454 5352 5251 504F" $"4E4E 4D4C 4B4A 4948 4746 4544 4342 4241" $"413A 2B29 2828 2722 1B1B 821A 1619 1918" $"1527 2B2D 2E30 3253 9ECF E8D9 D8D7 D6D6" $"D5D5 D4D4 80D3 81D2 02D4 D0C7 80C5 01C4" $"C581 C480 C381 C280 C181 C003 BBBB B51A" $"8200 0236 1724 8000 0401 0926 3246 8853" $"8052 1E51 5050 4F4F 4E4D 4C4B 4B4A 4948" $"4746 4545 4443 4241 4140 4039 2B28 2827" $"2622 801A 8219 1318 1815 272B 2D2E 2F31" $"539F CEE5 D7D7 D6D5 D5D4 D480 D301 D2D2" $"81D1 02D4 D0C5 82C4 82C3 81C2 80C1 81C0" $"05BF BFB8 C2B6 1A82 000C 441B 3000 0001" $"0107 2532 4350 5084 5181 501F 4F4F 4E4E" $"4D4D 4C4B 4A4A 4948 4747 4645 4443 4342" $"4140 403F 3F39 2A28 2726 2621 801A 8219" $"1218 1815 272B 2C2E 2F31 539F CDE2 D7D6" $"D5D5 D4D4 80D3 80D2 81D1 02D3 CFC5 80C4" $"01C3 C481 C380 C201 C1C2 81C1 08C0 BFC0" $"BFBF B4BF B71C 8200 0A53 1E0E 0000 0101" $"0624 3141 814E 804F 824E 804D 1E4C 4C4B" $"4A4A 4949 4847 4746 4544 4443 4241 4140" $"3F3F 3E3E 382A 2726 2625 211A 8019 0018" $"8019 1018 1815 272A 2C2D 2F31 549E CCDF" $"D6D5 D4D4 80D3 01D2 D282 D103 D0D0 D3CE" $"81C4 80C3 02C2 C3C3 80C2 81C1 80C0 81BF" $"03B5 BAB8 1D82 000A 481E 2000 0001 0105" $"2230 3E82 4C01 4D4D 824C 804B 1D4A 4A49" $"4948 4847 4646 4544 4443 4242 4140 403F" $"3E3E 3D3D 3829 2626 2525 2081 1900 1880" $"1911 1818 1526 2A2C 2D2F 3154 9FCA DDD5" $"D4D4 D3D3 80D2 80D1 82D0 02D2 CDC4 83C3" $"80C2 01C1 C281 C180 C080 BF05 BEBF B7BA" $"A303 8200 022F 1F32 8000 0401 0421 303C" $"814A 804B 824A 8049 0148 4880 470E 4645" $"4544 4443 4242 4141 403F 3F3E 3E80 3D06" $"3729 2625 2524 2086 180E 1715 272A 2C2D" $"2E30 549F C9DB D4D3 D380 D280 D180 D080" $"CF02 D0D2 CC80 C383 C281 C181 C080 BF80" $"BE03 BFBB B9A3 8300 0C3B 2518 0000 0101" $"031F 2F3B 4848 8349 8248 8047 0146 4680" $"450D 4443 4342 4241 4140 403F 3F3E 3D3D" $"803C 0137 2880 2502 2420 1984 180E 1717" $"1626 2A2B 2D2E 3055 9FC8 D9D3 D380 D280" $"D181 D081 CF04 D2CB C3C2 C381 C282 C182" $"C080 BF80 BE03 BFB6 B9A6 8300 0244 2B1D" $"8000 0501 021D 2E39 4687 4781 4601 4545" $"8044 1843 4342 4241 4140 403F 3F3E 3E3D" $"3D3C 3C3B 3C37 2825 2524 2420 8118 0017" $"8018 0C17 1716 2629 2B2C 2E30 559F C7D7" $"80D2 80D1 80D0 84CF 02D1 CBC3 80C2 01C1" $"C281 C180 C003 BFC0 BFBF 80BE 80BD 03BF" $"B1B8 AA83 0002 182F 2F80 0004 0102 1B2D" $"3880 4581 4683 4580 4480 4380 4209 4141" $"4040 3F3F 3E3E 3D3D 803C 803B 0136 2880" $"2401 2320 8717 0A16 2629 2A2C 2E2F 569F" $"C6D5 80D1 80D0 82CF 82CE 02D0 CAC2 83C1" $"82C0 81BF 80BE 80BD 04BC BFB4 B77E 8300" $"021E 3938 8100 0402 182D 3743 8744 8243" $"8042 0141 4180 4001 3F3F 803E 033D 3D3C" $"3C80 3B03 3A3B 3628 8024 0623 1F18 1718" $"1817 8018 0D17 1716 2629 2B2C 2D2F 569F" $"C5D4 D181 D081 CF84 CE02 D0C9 C283 C180" $"C001 BFC0 80BF 81BE 80BD 04BC BFB8 B778" $"8300 0224 441B 8100 0402 162C 3641 8543" $"8342 8041 8040 803F 803E 013D 3D80 3C80" $"3B80 3A0B 3628 2424 2323 1F18 1718 1817" $"8018 0C17 1715 2529 2A2C 2D2F 569F C4D2" $"80D0 80CF 01CE CF81 CE80 CD02 CED0 C881" $"C183 C080 BF81 BE80 BD80 BC03 BFB4 B67B" $"8300 0214 432B 8100 0501 142B 3540 4182" $"4284 4181 4080 3F80 3E80 3D80 3C80 3B06" $"3A3A 3939 3A35 2780 2301 221F 8717 0A15" $"2528 2A2B 2D2F 579F C3D1 80CF 83CE 81CD" $"04CC CCCE CFC7 83C0 82BF 81BE 81BD 07BC" $"BCBB BBBE AEB5 7F84 0001 463E 8100 0401" $"122A 343F 8A40 823F 803E 803D 813C 803B" $"803A 8039 0135 2780 2306 2220 1716 1717" $"1680 170E 1617 1525 2829 2B2C 2E57 9FC3" $"D0CF CF81 CE83 CD80 CC02 CDCF C681 C001" $"BFC0 81BF 80BE 03BD BEBD BD80 BC80 BB03" $"BEB1 B457 8400 0256 1E03 8000 0401 1029" $"343D 8A3F 823E 813D 813C 803B 803A 8239" $"0135 2780 2306 221F 1716 1717 1680 170C" $"1617 1524 2829 2B2C 2E58 9FC2 CF80 CE83" $"CD83 CC05 CDCE C6C0 BFC0 81BF 83BE 81BD" $"80BC 80BB 03BD B6B3 4D84 0002 5F18 1380" $"0004 010E 2933 3C8B 3E82 3D81 3C80 3B81" $"3A80 3980 3802 3935 2781 2200 1F87 160A" $"1524 2729 2A2C 2E58 9FC1 CE82 CD83 CC81" $"CB02 CCCD C581 BF82 BE81 BD81 BC80 BB80" $"BA03 BBB4 B251 8400 023B 1A24 8000 0401" $"0C28 333B 843E 013D 3E84 3D81 3C82 3B81" $"3A80 3901 3839 8038 0B35 2722 2322 211F" $"1716 1717 1680 170B 1617 1524 2729 2A2C" $"2D58 9FC0 81CD 83CC 83CB 06CC CDC4 BFBE" $"BFBF 82BE 81BD 81BC 80BB 81BA 02AD B155" $"8400 0249 1D28 8000 0401 0A27 323A 873D" $"013C 3D84 3C81 3B80 3A01 393A 8139 8238" $"0135 2780 2206 211F 1616 1717 1680 170C" $"1617 1523 2728 2A2B 2D58 9FC0 CD83 CC83" $"CB80 CA03 CCCC C3BF 83BE 80BD 83BC 01BB" $"BB81 BA04 B9B7 B4B0 3084 0002 581D 1080" $"0004 0108 2531 3A8A 3C83 3B82 3A82 3981" $"3880 3703 3835 2722 8021 001F 8716 0A15" $"2326 2829 2B2D 599F BFCC 85CB 83CA 05C9" $"CBCC C2BE BE82 BD82 BC81 BB80 BA81 B903" $"B3BB B222 8400 0245 1C21 8000 0501 0724" $"3139 3B80 3C04 3B3C 3C3B 3C84 3B01 3A3B" $"823A 8039 0238 3939 8038 0137 3880 3708" $"3427 2122 2221 1F16 1580 1680 170B 1617" $"1523 2628 292B 2D59 9FBE 81CB 02CA CBCB" $"83CA 06C9 CAC9 CBCB C1BE 83BD 80BC 01BB" $"BC80 BB81 BA81 B903 AFC1 B224 8400 0234" $"1E33 8000 0401 0623 3038 873B 023A 3B3B" $"843A 8339 8338 8237 0834 2721 2222 211F" $"1615 8216 0D17 1617 1523 2627 292A 2C5A" $"9FBE CA80 CB83 CA01 C9CA 81C9 02CB CBC1" $"81BD 83BC 80BB 81BA 80B9 80B8 03AE B4B2" $"2784 0002 4223 1380 0005 0105 212F 373A" $"803B 043A 3B3B 3A3B 843A 0239 3A3A 8139" $"0138 3981 3801 3738 8337 0B34 2721 2222" $"211F 1615 1616 1581 160A 1715 2225 2729" $"2A2C 5A9F BE81 CA83 C980 C808 C7C6 C6C7" $"C6BE BDBC BD81 BC82 BB81 BA80 B907 B8B8" $"B7B8 B1B4 AD19 8400 0245 281E 8100 0303" $"202F 3787 3A86 3984 3883 3781 3602 3734" $"2881 2100 1F84 1580 1619 1522 2526 2829" $"2B5A 9EBB C7C7 C6C6 C5C4 C4C3 C2C1 C0BE" $"BDBC BBB9 80B8 04BA BBBB BCBC 81BB 81BA" $"81B9 80B8 05B7 B7B8 B4B5 A785 0002 1F2B" $"3080 0005 0103 1E2E 3639 803A 0539 3A3A" $"393A 3A83 3900 3880 3983 3801 3738 8137" $"0036 8137 0134 2880 2106 201F 1615 1616" $"1582 1612 1520 2224 2526 2755 95B0 BBBA" $"B9B7 B6B5 B4B4 B381 B283 B108 B2B4 B6B8" $"B9BA BBBA BB81 BA80 B980 B880 B703 B8B7" $"B4AA 8500 0227 3333 8000 0401 021C 2D36" $"8A39 0538 3939 3839 3981 3883 3780 3601" $"3535 8034 0831 2522 2121 2021 1A16 8015" $"8016 0C15 1614 191B 1C1D 1E1F 4B88 A3B0" $"86B1 05B0 B1B1 B0B1 B184 B003 B2B4 B6B8" $"82B9 81B8 80B7 05B6 B6B8 AAB3 AE85 0002" $"2E3D 1C81 0003 021A 2D35 8D38 8037 1536" $"3635 3534 3433 3231 312F 2F2D 2C2B 2928" $"2624 2122 2280 2102 201E 1984 150A 1417" $"191A 1C1D 1F4B 88A2 AF8D B086 AF04 B0B2" $"B4B6 B781 B801 B7B7 80B6 04B5 B8AD B19E" $"8500 0214 3B2C 8000 0601 0217 2C34 3838" $"8137 1836 3635 3534 3433 3231 3130 2E2D" $"2C2A 2928 2625 2322 2120 1F1E 821D 031C" $"1D1E 2082 2104 2020 1E19 1680 150B 1614" $"1719 1A1B 1D1E 4B87 A2AE 93AF 84AE 03B0" $"B2B4 B582 B605 B5B5 B8AF AE7A 8600 0249" $"2A0F 8000 1501 1327 2E32 3130 2F2E 2C2B" $"2A28 2725 2423 2220 1F1F 1E82 1D0B 1C1D" $"1D1C 1D1D 1C1D 1D1C 1D1D 821C 011D 1F82" $"211D 201F 1E1A 1615 1514 1618 191B 1C1E" $"4B87 A1AE AFAE AFAE AFAF AEAF AFAE AFAF" $"80AE 80AD 84AE 82AD 05AC ADAD AFB1 B380" $"B404 B3B6 AAAA 7E86 0002 621D 1E81 0006" $"0A19 1E20 1F1E 1E85 1D96 1C81 1B03 1C1D" $"1F20 8021 1320 201F 1F1A 1613 1117 191A" $"1C1D 4C87 A1AD AEAD AD80 AC80 AB01 AAAA" $"80A9 82A8 01AA AB81 AD80 AC0F ABA9 A7A4" $"A19D 9994 8F8A 837C 7F9D A583 8600 0333" $"2316 1180 0009 0614 191C 1C1D 1D1C 1D1D" $"931C 031B 1C1C 1B80 1C03 1B1C 1C1B 811C" $"021D 1F20 8021 0D20 201F 1F1B 1E0B 1118" $"1A1C 4A83 9C8C A880 A71A A6A4 A3A0 9E9B" $"9994 8E87 8077 6E64 5A4F 4951 5D4C 595D" $"6081 8897 5E86 000A 0940 1B22 0400 0005" $"1318 1B86 1C06 1B1C 1C1B 1C1C 1B80 1C0B" $"1B1C 1C1B 1C1C 1B1C 1C1B 1C1C 8D1B 101A" $"1A18 1716 1512 0105 0A09 0F18 4881 9AA6" $"82A7 26A6 A5A4 A2A0 9D99 9590 8A83 7C74" $"6B61 574D 4238 2E26 3060 484B 6158 7075" $"625B 5B58 5860 6276 8013 8700 082C 2F16" $"1C00 0004 1218 951B 081A 1A19 1918 1817" $"1616 8015 0214 1619 831A 0117 1583 1422" $"1512 0302 0205 090B 3577 919B 9894 8F89" $"837C 746B 6258 4F44 3A31 281F 1812 0C08" $"0503 0281 000F 0F2D 3E3F 3036 3F4E 5873" $"9844 4436 200B 8800 0926 4F26 270A 0003" $"1217 1A88 1B08 1A1A 1919 1818 1716 1682" $"1506 1415 1514 1515 1480 1509 1415 1516" $"1A1B 1A1B 1A15 8214 8013 000E 8003 2102" $"0306 1435 514F 453C 3229 211A 140E 0B08" $"0504 0303 0202 0303 0100 0101 0001 0100" $"0180 000B 0F26 352F 1E28 354A 6663 3D10" $"8800 1330 512C 2118 2400 0211 1619 1918" $"1817 1716 1615 1581 1402 1515 1480 150B" $"1415 1514 1515 1415 1514 1515 8414 0F13" $"1316 1817 1611 100F 0E0D 0B0A 0807 0584" $"0304 0709 0704 048A 0307 0203 0301 0001" $"0100 8701 0A0E 2936 2E1F 2734 4660 6033" $"8600 0B55 2C28 2917 2900 000B 1113 1487" $"138D 1480 1318 1212 1110 100F 0E0D 0B0A" $"0807 0A20 0504 0505 070A 0B0B 0805 0496" $"0303 0404 0201 8002 8003 8604 0903 0C2C" $"342F 222A 3348 5885 0003 5328 2A01 8002" $"0300 0B11 1380 1405 1314 1413 1414 8613" $"8012 0F11 1010 0F0E 0C0B 0A08 0705 0404" $"0303 0283 000D 2A08 0809 0A0B 0C0E 0F0F" $"0D09 0505 8D04 0905 0506 0707 0808 0A0A" $"068E 0580 0406 0D2F 3526 2B49 0C84 0003" $"512A 1F02 8003 0201 0910 8413 8012 0F11" $"1110 0F0F 0D0C 0B09 0807 0605 0403 0380" $"0281 0381 0400 0385 000C 0408 090A 0B0C" $"0D0F 1010 0E09 0682 0505 0606 0708 0809" $"810A 840B 090C 0B06 0506 0605 0606 0581" $"060F 0708 090A 0B0C 0D0E 0F10 100E 3729" $"5419 8400 034D 2321 0280 040F 0304 0C10" $"100F 0E0D 0C0B 0908 0705 0504 8403 8104" $"0805 0504 0505 0405 0504 8105 0104 0185" $"0007 0108 0A0B 0C0C 0D0E 8010 030F 0C0A" $"0A80 0B89 0C00 0B82 0C80 070A 0808 090B" $"0C0D 0E0F 1011 1181 1209 1313 1213 1312" $"1238 4F1A 8400 0354 1909 0182 0402 0304" $"0484 0381 0495 0513 0401 0003 080B 1920" $"2D41 4A63 5C1B 0B0C 0C0D 0E0F 8011 0210" $"0E0D 880C 800D 0B0E 0F10 1114 1410 1011" $"1112 1280 1382 1483 1382 1202 4249 1A84" $"0004 481B 1D00 0390 0502 0606 0580 0620" $"0506 0605 0606 0506 0605 070E 111B 2A31" $"4854 6377 8092 9AA3 ADAB AEAF B0B0 A757" $"0F80 0D02 0E0F 1080 1101 100E 800D 190E" $"0F10 1112 1315 1617 191A 1B1C 1D21 2119" $"1818 1717 1615 1514 1484 130A 1213 1312" $"1313 1217 204E 1B84 000A 351D 2E00 0205" $"0606 0506 058F 0613 0707 0B15 172B 3243" $"5A64 7E87 96A4 A9B3 B6B8 B8B5 80B4 80B5" $"1DB2 B3B5 B8BD C2C8 B13C 0D0C 0D0E 0E10" $"1112 1213 1618 191A 1C1D 2023 2629 2C80" $"2D07 2B29 2727 2318 1514 8413 0312 1313" $"1280 130A 1213 1312 1313 1224 214C 0E84" $"0005 4221 2100 0104 8A06 1507 090A 151A" $"2538 3F59 6379 8B94 A5AB B1B8 B8B9 B9BA" $"BA80 BB15 BCBC BDBE BCBE C3C8 CED4 DADA" $"DFE3 E6E8 E9EA EBE1 310C 800D 120E 0F10" $"121A 716C 4C4D 4C48 433C 352E 2824 211F" $"801E 0420 1E14 1313 9212 0233 244C 8500" $"0651 2619 0000 0306 8007 280A 0C12 1E22" $"3640 5167 7089 929F AAAF B5B7 B8B8 B9B9" $"BABA BBBB BCBC BEC0 C4C8 CED4 DAE1 E8EF" $"F3F0 EEF0 81F1 18E7 E5E4 E3E1 DFDD DAD8" $"630C 0D0E 0D0E 0F0F 111D 4E6B 3129 2421" $"811F 801E 001D 801E 0220 1D14 8013 0912" $"1313 1213 1312 1313 1280 1309 1213 1312" $"1313 123C 2457 8500 5D29 242A 0000 0107" $"2353 7082 9399 A7AD B1B6 B6B7 B7B8 B8B9" $"B9BA BABB BCBE C1C5 CAD0 D6DD E4EA F0F5" $"F9FC FDFE FEFF FFFE FEF4 ECEA E8E5 E3E0" $"D3CF CCC9 C7C5 C3C1 C05F 0C0D 0E0D 0E0F" $"0E11 1C21 211F 1F1E 1F1F 1E1F 1E1D 1E1E" $"1D1E 1E1D 201D 1480 1309 1213 1312 1313" $"1213 1312 8013 0912 1313 1213 1312 1A24" $"6385 0020 292B 3400 0001 1E64 93AF B6B6" $"B7B7 B8B9 B9BA BBBE C1C6 CBD1 D8DF E6EC" $"F2F6 FAFC FD86 FE10 FCFA F8F5 F2ED DDD3" $"D1CE CDCB CABF BEBE BD82 BE01 5F0C 800D" $"800E 0411 1C21 211F 841E 841D 0320 1C14" $"1393 1202 2825 5685 0017 3334 1700 0001" $"1455 82A6 BBC1 C6CC D2D9 E0E7 EDF2 F7FA" $"FCFD 80FE 80FF 12FE FFFF FEFB F9F6 F3EF" $"EBE7 E4E2 E0DE DDDD DBCE 82C8 00C9 81BD" $"82BE 015E 0C80 0D80 0E08 111C 2120 1F1F" $"1E1F 1F80 1E16 1D1E 1E1D 1E1D 1D20 1C13" $"1213 1312 1313 1213 1312 1313 1280 1309" $"1213 1312 1313 1236 263F 8500 021D 3928" $"8000 0A08 3573 BDED F6F9 FAFC FCFD 81FE" $"0FFF FFFE FEFC F9F6 F3EF EBE7 E3E0 DEDD" $"DC84 DB80 DC02 DACE C782 C885 BD02 BE5E" $"0C80 0D80 0E08 111C 2120 1F1F 1E1F 1F80" $"1E02 1D1E 1E81 1D0F 201C 1312 1313 1213" $"1312 1313 1213 1312 8013 0912 1313 1213" $"1312 3627 4985 0002 0243 3A80 0005 0318" $"7BD5 F5FD 80FE 0BFD FCF8 F6F1 EEEA E6E2" $"DEDC DB80 DA80 D988 DA80 DB01 DACE 83C7" $"00BD 84BC 03BD 5D0C 0C80 0D05 0E0E 111C" $"2120 831E 841D 041C 1D20 1C13 9412 021E" $"2855 8500 1203 531B 0100 0001 0B77 C1E2" $"ECE8 E4E0 DDDB DAD9 83D8 01D9 D884 D902" $"DADA D984 DA80 DB01 D9CE 83C7 00BD 85BC" $"015D 0C80 0D80 0E05 111C 2120 1F1F 801E" $"051D 1E1E 1D1E 1E81 1D0F 1F1B 1312 1313" $"1213 1312 1313 1213 1312 8013 0912 1313" $"1213 1211 2C29 3D85 000A 035B 1C0B 0000" $"0106 64AA CC82 D601 D7D6 80D7 02D8 D8D7" $"81D8 02D9 D9D8 84D9 01DA D984 DA0B D9CE" $"C6C7 C7C6 C7C7 BCBB BCBB 82BC 015D 0C80" $"0D80 0E05 111C 2020 1F1F 801E 041D 1E1E" $"1D1E 821D 0F1F 1B13 1213 1312 1313 1213" $"1312 1313 1280 1302 1213 1380 1203 113B" $"2A30 8600 093C 2415 0000 0104 5CA7 C981" $"D583 D684 D786 D886 D902 DAD9 CD83 C500" $"BC84 BB03 BC5C 0C0C 800D 050E 0E11 1C20" $"2081 1E84 1D80 1C03 1D1F 1A13 9212 0411" $"1032 2C39 8600 0A4B 2817 0000 0103 53A4" $"C7D4 80D5 83D6 02D7 D7D6 81D7 02D8 D8D7" $"83D8 02D9 D9D8 84D9 07D8 CDC4 C5C5 C4C5" $"C580 BB00 BA82 BB01 5C0C 800D 800E 0211" $"1C20 801F 801E 021D 1E1E 801D 001C 801D" $"0F1F 1A13 1213 1312 1313 1213 1312 1313" $"1280 1302 1213 1380 1203 1023 2F43 8600" $"0A5B 1A0F 0000 0102 4BA1 C5D4 83D5 02D6" $"D6D5 80D6 02D7 D7D6 82D7 04D8 D7D8 D8D7" $"83D8 81D9 01D8 CD83 C400 BB82 BA04 BBBA" $"BB5C 0C80 0D80 0E0B 111C 201F 1F1E 1D1E" $"1E1D 1E1E 801D 001C 801D 0F1F 1913 1213" $"1312 1313 1213 1312 1313 1280 1301 1213" $"8112 030F 3234 2186 000A 4619 1F00 0001" $"0242 9DC3 D380 D483 D583 D680 D700 D683" $"D702 D8D8 D784 D80B D7CD C3C4 C4C3 C4C4" $"BBBA BAB9 82BA 015C 0C80 0D80 0E0B 111C" $"201F 1E1E 1D1E 1E1D 1E1E 801D 001C 801D" $"0F1F 1913 1213 1312 1313 1213 1312 1313" $"1280 1309 1213 1211 1212 0E43 3B1A 8600" $"0238 1B32 8000 0501 3B99 C1D3 D384 D484" $"D586 D687 D702 D8D7 CD83 C300 BA85 B900" $"5B80 0C80 0D05 0E12 1C20 1F1E 841D 831C" $"021D 1F18 9012 8111 030F 3C41 2086 000A" $"461F 1000 0001 0133 96BF D280 D383 D484" $"D586 D605 D7D7 D6D7 D7D6 81D7 01D6 CC80" $"C306 C2C3 C3BA B9B9 B882 B901 5B0C 800D" $"800E 0812 1C20 1F1E 1E1D 1E1E 801D 031C" $"1D1D 1C80 1D0F 1F18 1312 1313 1213 1312" $"1313 1213 1312 8013 8012 0611 1212 1920" $"4925 8600 0A48 231D 0000 0101 2C92 BCD1" $"81D3 01D4 D383 D485 D501 D6D5 88D6 05D7" $"D7D6 CCC2 C381 C200 BA80 B880 B903 B8B9" $"5A0C 800D 800E 0812 1C20 1F1E 1E1D 1E1E" $"801D 161C 1D1D 1C1D 1C1D 1F18 1312 1313" $"1213 1312 1313 1213 1312 8013 8012 0611" $"1212 2522 470B 8600 0226 252F 8000 0401" $"248E BAD0 81D2 84D3 85D4 8AD5 80D6 01D5" $"CC80 C203 C1C2 C2B9 80B7 82B8 005A 800C" $"810D 0312 1C1F 1E84 1D84 1C02 1D1E 178E" $"1283 1102 3323 4D87 0002 302C 3080 0004" $"011E 89B7 CF81 D201 D3D2 83D3 02D4 D4D3" $"81D4 05D5 D5D4 D5D5 D486 D504 D6D5 CCC1" $"C281 C100 B981 B705 B8B8 B7B8 5A0C 810D" $"040E 0D11 1C1F 801E 011D 1E81 1D02 1C1D" $"1D80 1C1C 1D1E 1713 1213 1312 1313 1213" $"1312 1313 1213 1212 1112 1211 1212 2523" $"5887 0002 3A34 1B80 0007 0118 85B5 CED1" $"D2D1 83D2 83D3 80D4 00D3 84D4 04D5 D4D5" $"D5D4 81D5 01D4 CC83 C103 B9B7 B7B6 82B7" $"0A59 0C0D 0D0C 0D0E 0D11 1C1F 801E 801D" $"051C 1D1D 1C1D 1D80 1C0F 1D1E 1613 1213" $"1312 1313 1213 1312 1313 8112 0811 1212" $"1112 121C 2163 8700 021C 382A 8000 0401" $"137F B2CC 83D1 86D2 87D3 88D4 01CB C182" $"C000 B885 B600 5881 0C80 0D03 111C 1F1E" $"811D 851C 041B 1B1D 1E16 8C12 8511 0229" $"2340 8700 020A 433F 8100 060E 79AF CBD1" $"D1D0 81D1 01D2 D183 D288 D304 D4D3 D4D4" $"D381 D401 D3CB 83C0 00B8 85B6 0A58 0B0C" $"0D0C 0D0E 0D12 1C1F 801E 801D 021C 1D1D" $"801C 121B 1C1C 1D1E 1613 1213 1312 1313" $"1213 1312 1313 8112 0811 1212 1112 1138" $"2544 8700 030C 5318 0280 0003 0B73 ACCA" $"80D0 02D1 D1D0 83D1 85D2 04D3 D2D3 D3D2" $"88D3 00CB 80C0 03BF C0BF B780 B580 B615" $"B5B6 570B 0C0D 0C0D 0E0D 121C 1F1E 1E1D" $"1C1D 1D1C 1D1D 801C 111B 1C1C 1D1D 1513" $"1213 1312 1313 1213 1312 1382 1208 1112" $"1211 1211 2E26 4F87 0003 0A54 2109 8000" $"0308 6BA9 C880 CF84 D087 D18B D202 D3D2" $"CA83 BF02 B7B4 B483 B501 570B 800C 800D" $"0512 1C1F 1E1D 1D84 1C82 1B02 1D1D 158A" $"1287 1102 2127 5C88 0002 3E2C 1080 0003" $"0664 A6C6 80CF 02D0 D0CF 83D0 02D1 D1D0" $"84D1 05D2 D2D1 D2D2 D185 D200 CA80 BF03" $"BEBF BEB6 81B4 08B5 B5B4 B456 0B0C 0D0C" $"800D 0212 1C1F 801D 061C 1D1D 1C1D 1C1B" $"821C 0C1E 1D15 1312 1313 1213 1312 1313" $"8012 0011 8012 0811 1212 1112 112F 2839" $"8800 024D 220A 8000 0604 5CA3 C4CF CFCE" $"81CF 01D0 CF84 D002 D1D1 D089 D181 D201" $"D1CA 83BE 00B6 85B4 0156 0B80 0C80 0D02" $"121C 1F80 1D00 1C81 1D01 1C1C 811D 031C" $"1D1C 1581 1305 1213 1312 1313 8012 0011" $"8012 0811 1212 1112 103F 2A37 8800 025E" $"1910 8000 0303 54A0 C283 CE86 CF8A D002" $"D1D1 D082 D101 CABE 82BD 00B6 85B3 0255" $"0B0B 800C 040D 0D12 1C1E 811D 011E 1E80" $"1D05 1C1C 1B19 1716 8214 0013 8512 8811" $"0310 2A2B 4188 0002 3619 2480 0004 024C" $"9DC0 CD83 CE01 CFCE 84CF 02D0 D0CF 8ED0" $"00C9 83BD 00B5 85B3 0155 0B80 0C11 0D0D" $"0E13 1D20 1F1E 1E1D 1C1B 1A18 1614 1311" $"8010 100F 1011 1314 1413 1213 1312 1312" $"1112 1211 8012 0811 1212 1111 0F26 2D4B" $"8800 0240 1C34 8000 0302 449A BE80 CD02" $"CECE CD83 CE02 CFCF CE85 CF07 D0CF D0D0" $"CFD0 D0CF 82D0 00C9 80BD 03BC BDBC B580" $"B281 B304 B255 0B0C 0C80 0D0A 0E13 1C1D" $"1B19 1715 1312 1182 1003 0F10 100F 8010" $"0212 1414 8013 8012 0311 1212 1180 1208" $"1112 1211 110E 3433 1E88 0002 4E20 0E80" $"0006 013C 96BC CCCD CC81 CD01 CECD 85CE" $"04CF CECF CFCE 8BCF 00C9 83BC 03B5 B2B2" $"B182 B200 5580 0C06 0B0B 0A09 0C12 1380" $"1183 1006 0F10 100F 1010 0F81 1004 1113" $"1414 1380 1203 1112 1211 8012 0111 1280" $"1103 0D45 3723 8800 0248 2120 8000 0401" $"3592 BACB 83CC 86CD 8CCE 81CF 02D0 C9BC" $"82BB 00B4 85B1 0353 0706 0580 0403 0308" $"0F11 8210 8D0F 0510 1214 1413 1288 1105" $"1010 0F32 3D2A 8800 022B 2332 8000 0601" $"2E8F B8CA CCCB 83CC 87CD 02CE CECD 83CE" $"81CF 00D0 80CF 01C7 BD82 BB03 B6B1 B1B0" $"82B1 0450 0203 0302 8003 0208 0F11 8010" $"0D0F 1010 0F10 100F 1010 0F10 100F 1083" $"0F03 1113 1413 8112 0011 8012 8011 0510" $"1118 2244 3088 0002 3529 1D80 0004 0127" $"8BB5 C980 CB01 CCCB 84CC 01CD CC83 CD80" $"CE81 CF0B CECE CDCC CBC9 C7C5 C1BF BCBB" $"81BA 00B4 84B0 044F 0203 0302 8003 0208" $"0F11 8010 0B0F 1010 0F10 100F 1010 0F10" $"1081 0F06 0E0F 0F0E 0F10 1280 1302 1212" $"1180 1280 1105 1011 2326 4804 8800 0241" $"311E 8100 0520 86B3 C8CA CA86 CB80 CC80" $"CD82 CE12 CDCC CBCA C8C6 C4C1 C0BE BEBD" $"BEBF BFBE BBB9 BA80 B900 B383 AF00 4F82" $"0205 0303 080F 1010 8D0F 850E 010F 1180" $"1300 1282 1181 1002 2E2B 5289 0002 0E32" $"2F80 0004 011A 81B0 C780 CA01 CBCA 80CB" $"80CC 82CD 08CC CCCA C9C7 C5C3 C0BF 81BD" $"00BC 80BD 06BC BDBD BEBF BDBA 82B9 00B2" $"82AF 044F 0202 0302 8003 0108 0F81 1008" $"0F10 100F 1010 0F10 1080 0F00 0E80 0F17" $"0E0F 0F0E 0F0F 0E0F 1012 1313 1212 1111" $"1011 1110 111B 235D 8900 0211 3E30 8000" $"0401 157C ADC6 80CA 01CB CB82 CC08 CBCA" $"C9C8 C6C4 C2BF BE81 BC00 BB89 BC13 BDBE" $"BEBC B9B9 B8B9 B8B8 B1AF AFAE AE4E 0102" $"0302 8003 0108 0F81 1007 0F10 100F 1010" $"0F10 810F 000E 800F 0A0E 0F0F 0E0F 0F0E" $"0F0E 0E11 8013 0912 1110 1111 1011 1E20" $"6389 0003 154A 1702 8000 0311 78AC C680" $"CB0B CACA C9C8 C6C5 C3C0 BEBC BBBB 83BA" $"8DBB 03BC BEBD BB81 B802 B7B7 B080 AE01" $"4E01 8202 0403 080F 1010 880F 8D0E 080D" $"0E0F 1213 1212 1111 8010 022C 223E 8900" $"1208 3925 0600 0001 0D72 A8C3 C7C5 C3C1" $"BFBD BBBA 81B9 01BA B985 BA04 BBBA BBBB" $"BA88 BB04 BCBD BDBA B881 B708 B6AF ADAD" $"4E01 0203 0280 0301 080F 8110 040F 1010" $"0F10 810F 030E 0F0F 0E80 0F04 0E0F 0F0E" $"0F81 0E00 0D80 0E0A 1012 1312 1211 1010" $"3B23 488A 0002 4020 1080 0005 0966 9DB6" $"BAB9 83B8 02B9 B9B8 84B9 89BA 80BB 13BA" $"BBBB BABB BBBC BDBC B9B7 B7B6 B7B6 B5AE" $"AD4D 0180 0280 0301 080F 8110 020F 1010" $"800F 060E 0F0F 0E0F 0F0E 800F 020E 0F0F" $"800E 110D 0E0E 0D0E 0E0D 0E0F 1112 1312" $"1110 2525 558A 0002 541B 1E80 0003 055A" $"94B0 84B7 86B8 8BB9 87BA 03BB BCBB B882" $"B604 B4AD 4D01 0182 0202 080F 1084 0F8E" $"0E87 0D01 0E10 8012 0311 242A 618A 0002" $"3324 1A80 0005 0453 91AF B7B6 83B7 02B8" $"B8B7 84B8 02B9 B9B8 8DB9 07BA B9B9 BABB" $"BBBA B682 B502 B24D 0180 0204 0303 0208" $"0F81 1080 0F09 0E0F 0F0E 0F0F 0E0F 0F0E" $"800F 800E 090D 0E0E 0D0E 0E0D 0E0E 0D81" $"0E06 0F11 1212 3F31 2E8A 0009 2A35 2803" $"0000 024B 8EAD 82B6 86B7 88B8 04B9 B8B9" $"B9B8 80B9 00B8 85B9 02BB BBB9 81B5 0DB4" $"B382 0E01 0202 0303 0208 0F10 1082 0F09" $"0E0F 0F0E 0F0F 0E0F 0F0E 800F 800E 140D" $"0E0E 0D0E 0E0D 0E0E 0D0E 0E0D 0D0C 0B0F" $"333E 3F40 8A00 0908 4B19 1A00 0002 448B" $"AB80 B585 B68A B790 B803 BABA B8B5 80B4" $"03B2 915D 0A82 0204 080F 100F 0F8F 0E89" $"0D0A 0B0A 1821 2C36 3635 3758 4A8B 0008" $"5023 2800 0001 3D89 A982 B586 B680 B700" $"B687 B701 B8B7 80B8 06B7 B8B8 B7B8 B8B7" $"81B8 0FBA B9B7 B4B3 B3B2 9A6C 3206 0203" $"0302 0882 0F27 0E0F 0F0E 0F0F 0E0F 0F0E" $"0F0F 0E0F 0E0E 0D0E 0E0D 0E0E 0D0D 0C0A" $"0F25 2934 372F 252A 3342 555F 6206 8B00" $"023A 3029 8000 0436 85A8 B4B4 83B5 02B6" $"B6B5 85B6 04B7 B6B7 B7B6 91B7 0AB8 B9B8" $"B5B3 B3B1 A188 2F15 8003 0102 0882 0F0B" $"0E0F 0F0E 0F0F 0E0F 0F0E 0F0F 810E 150D" $"0E0D 0D0B 091F 2A32 3238 2928 313C 506F" $"5E4A 381D 048D 0009 1743 1914 0000 3082" $"A5B3 81B4 02B5 B5B4 83B5 80B6 00B5 8AB6" $"07B7 B7B6 B7B7 B6B7 B783 B60E B7B8 B7B4" $"B2B1 A39E 4517 3203 0202 0882 0F20 0E0F" $"0F0E 0F0F 0E0F 0F0E 0F0E 0E0D 0D0C 0B11" $"2832 363D 2527 2E39 4A5F 685B 3E2B 0293" $"0007 571C 1900 002A 7FA3 81B3 87B4 8FB5" $"82B6 85B5 0EB6 B7B8 B6B3 B0A2 A574 301F" $"2D03 0208 800F 890E 110D 0B11 2331 2F3A" $"3A26 2C36 455C 6A5A 4835 0E98 0008 3C25" $"2600 0023 7BA1 B281 B302 B4B4 B383 B480" $"B500 B49A B50C B7B7 B5B1 A3A7 7265 2E1A" $"1C03 0882 0F16 0E0F 0F0E 0E0D 0C0D 1A2F" $"3739 312B 2B33 4054 6668 4E3E 219D 0009" $"2636 1D0D 001D 779F B1B2 84B3 04B4 B3B4" $"B4B3 87B4 05B5 B5B4 B5B5 B480 B507 B4B5" $"B5B4 B5B5 B4B5 83B4 00B5 80B6 08A4 A759" $"1443 1B17 1608 800F 800E 110C 0A1A 202C" $"362F 2E27 303C 4D65 6857 4621 0CA1 0008" $"034A 1A17 0018 739D B085 B289 B392 B483" $"B31E B4B5 BAA8 A85A 000C 1F21 292C 0B0E" $"0B0E 2828 3435 2E25 2A33 4156 5C5B 4F3A" $"0EA7 0008 4A24 2300 136E 9AAF B186 B202" $"B3B3 B288 B304 B4B3 B4B4 B380 B402 B3B4" $"B486 B31D B2AE A699 8793 A9A9 6000 000E" $"642E 232C 212D 3626 2731 3C50 6F5A 4536" $"1B02 AB00 0733 3326 030F 6A98 AE81 B102" $"B2B2 B187 B208 B3B3 B2B3 B3B2 B3B3 B286" $"B311 B2B3 B3B2 B2AF A89C 8977 7677 7A8C" $"9899 A342 8000 0B2F 4630 2D30 3446 5B63" $"5839 28B1 0007 1A4D 221B 0B64 95AD 80B0" $"89B1 91B2 11AF A99E 8C7C 7574 7A86 8E81" $"7B78 7C85 8A64 0281 0006 1014 1415 141B" $"0BB5 0007 0157 1F1D 085F 93AC 81B0 02B1" $"B1B0 88B1 20B2 B1B2 B2B1 B2B2 B1B2 B2B1" $"B1AF AAA0 917E 7676 7B81 8887 7D78 787E" $"8278 5341 1C05 C300 0A3F 2829 0758 90AA" $"AFB0 B0AF 83B0 02B1 B1B0 80B1 00B0 85B1" $"14AF ABA3 957F 7876 767E 8A88 7E7A 777C" $"8A77 613F 260D C800 0619 3B2A 1051 8DA9" $"87AF 87B0 14AF ACA4 9885 7378 767D 8986" $"817A 7779 8382 6E49 320C CD00 0A07 502A" $"2D48 8AA7 AEAF AFAE 86AF 17B0 AFAF ACA5" $"9A89 7474 7376 838D 817B 7878 808F 7057" $"3214 02D2 0005 4935 3F41 87A6 84AE 17AF" $"AFAE AEAB A69C 8C7A 7171 7681 8D7F 7976" $"777F 8379 623D 23D8 0005 3543 593D 83A4" $"83AD 14AB A79E 8F7C 7373 767B 8686 7A76" $"767A 827D 5845 2009 DC00 1B12 5B55 4D7F" $"A2AC ABA7 9F92 7E74 7273 7A85 867C 7775" $"7985 7A66 442D 13E2 0016 5159 6A63 8382" $"706F 7379 8284 7F78 7577 7F83 734E 3910" $"02E6 0011 4164 6B72 737B 877D 7674 757D" $"9173 5C38 1C05 DD00 8200 5B0E 4A53 3126" $"2C2C 262D 373F 4A4C 321A 171B 2025 2A2E" $"2B20 1814 191D 2227 2A25 1E18 151B 2128" $"2E30 2A22 1918 212A 333C 4039 3026 2332" $"404E 5C64 615C 4C20 2F3A 4458 3D05 0000" $"081C 3125 211E 1E23 2930 3437 3930 0304" $"0506 0708 0909 069F 0008 063D 6036 2520" $"2E1E 0982 0A6B 0909 0D13 181D 2328 2F32" $"1A14 1A21 272E 343C 401B 181D 252C 343B" $"4343 1719 1F27 2F39 424B 4C1E 1819 1F25" $"2B31 3430 1C16 171D 242C 3651 6A64 5B71" $"584C 423B 3A3B 4148 5051 4B42 393A 4651" $"5D68 6C69 624B 323E 4955 6065 6460 4E26" $"3039 434C 5051 4F35 181F 262E 3539 3D3F" $"2E09 8200 2616 673F 2A1F 2826 0307 2075" $"7572 6A63 5B54 4E48 4440 3C39 352F 2A24" $"201D 1917 1513 1110 0F0E 0E0D 820C 860B" $"5B0E 1317 1B20 2428 290E 131C 232E 3334" $"2C31 2E29 282F 3447 3D3B 4148 4E56 5D59" $"3130 3339 3F45 4C4F 4731 2C2D 3236 3A3E" $"3E39 342E 2F34 393E 4442 3D35 2E31 383F" $"474E 4F4E 4C43 4E32 0100 000C 622E 1F2B" $"2907 0002 0735 EDF5 F6F8 F9FB FC83 FE37" $"FDFA F7F4 F1EF EDEB E9E4 DCD3 CEC7 C2BD" $"B5AB A29A 938A 7F74 695D 534A 4139 332D" $"2723 201D 1B1A 1817 1615 1513 2E33 3539" $"2B39 251F 1923 2727 8126 3025 2628 2B2D" $"3032 3538 3426 2A32 373F 434A 504C 282D" $"3339 4146 4F55 482B 2D35 3C46 4D57 5C56" $"3D35 3843 2000 000B 451F 310E 8000 3F0A" $"1325 ACC1 C4C6 C8CA CCCD CDCC CCCB CAC9" $"C8C6 C4C3 C1BE BCBA B7B5 B2AF ACA9 A7A4" $"A09D 9995 928D 8A84 7E78 726D 6863 5E59" $"544F 4A45 403B 3630 2B27 1908 100F 0F80" $"0E16 0F1A 52B2 534D 4843 3F3B 3835 3331" $"2F2D 2C2B 2A29 2928 2883 2783 2681 2781" $"2880 2918 2C39 393F 2400 000A 3A3A 0400" $"0001 0110 1E2F A8C2 C4C6 C8CA CA80 CB32" $"CAC9 C7C5 C2C0 BDBA B6B2 AEA9 A5A0 9B96" $"918C 8681 7C76 716C 6762 5D58 544D 423E" $"3B38 3532 2F29 231F 1C19 1816 1413 0E05" $"0B0C 0B80 0A16 0D1C 48CF 4F4B 4743 403D" $"3A38 3634 3230 2F2D 2C2B 2A29 2981 2801" $"2929 802A 012B 2B81 2C80 2D83 2E08 2D42" $"4126 0000 0B3E 1F80 000B 0101 1021 309E" $"BBBE BFC1 C2C3 80C4 31C3 C2C1 BFBD BBB8" $"B5B2 AEAB A7A3 9E9A 9590 8C87 827D 7974" $"6F6B 6662 5E5A 5648 3D3A 3734 312A 211E" $"1C1A 1816 1513 120E 0610 1181 1216 172C" $"57D0 5A56 534F 4C49 4744 4240 3E3C 3A39" $"3836 3534 2E81 2D8C 2E81 2D09 2E2C 4245" $"2B00 000C 3C2D 8000 0A01 010F 212D 91B3" $"B5B6 B8B9 82BA 2FB9 B8B6 B4B2 B0AD AAA7" $"A3A0 9C98 9490 8B87 827E 7A75 716D 6965" $"605D 5955 493B 3835 322F 261F 1D1B 1917" $"1514 1312 0E06 1181 1318 141A 305C CB5C" $"5956 5250 4D4B 4946 4543 4240 3F3E 3D3E" $"3F37 3281 3181 3084 2F80 2E0D 2D2E 2E2D" $"2E2B 4F47 2F00 000E 423E 8000 0B01 010E" $"212B 84AA ACAD AFB0 B080 B130 B0AF AEAD" $"ABA9 A7A4 A29F 9B98 9491 8D89 8581 7D79" $"7470 6C69 6560 5D59 5652 4638 3532 302D" $"241D 1B1A 1816 1513 1312 0D06 1180 131B" $"1414 1A31 5CC5 5B58 5552 4F4D 4B49 4745" $"4442 4140 3F3E 3F40 3732 3131 8030 012F" $"3081 2F02 2E2F 2F81 2E0E 2D2E 2E2D 2D2A" $"5A47 3500 0011 4E1B 0180 0009 010C 202A" $"78A1 A3A5 A6A7 81A8 4EA7 A7A6 A4A3 A19F" $"9C9A 9794 918D 8A86 837F 7B77 7370 6C68" $"6461 5D5A 5653 4F44 3633 302E 2B23 1C1A" $"1817 1514 1312 110D 0611 1212 1313 141A" $"315C C059 5653 504E 4C4A 4846 4443 4241" $"403F 3E3F 3F37 3131 8030 812F 842E 852D" $"172B 3A4A 3C00 000F 5323 0600 0001 010A" $"1F29 6D99 9B9C 9E9F 9F80 A030 9F9E 9D9C" $"9B99 9795 9290 8D8A 8783 807D 7976 726E" $"6B67 6460 5D5A 5653 514D 4234 312E 2C2A" $"211B 1917 1614 1312 1211 0C06 1180 1318" $"1414 1A31 5CBB 5754 524F 4D4B 4947 4544" $"4341 403F 3F3E 3F3F 3680 3180 3015 2F30" $"2F2E 2F2F 2E2F 2F2E 2D2E 2E2D 2E2E 2D2D" $"2E40 4D35 8000 0F3F 2F0C 0000 0101 091E" $"2863 9293 9596 9682 972F 9695 9493 918F" $"8D8B 8986 8380 7D7A 7774 716D 6A66 6360" $"5D59 5653 504E 4B40 322F 2D2A 2820 1918" $"1615 1313 1211 100C 0611 8013 1814 141A" $"315B B555 5350 4E4B 4948 4645 4342 4140" $"3F3E 3D3F 3F36 8031 8030 802F 122E 2F2F" $"2E2F 2E2E 2D2E 2E2D 2E2E 2D2D 314B 570D" $"8000 024D 2508 8000 0A01 081E 275A 8B8C" $"8D8E 8F8F 8090 4D8F 8F8E 8D8B 8A88 8684" $"8280 7D7A 7875 726F 6C68 6562 5F5C 5956" $"5350 4D4B 483E 302D 2B29 271F 1816 1514" $"1312 1110 0F0C 0611 1212 1313 141A 315B" $"AB54 514F 4C4A 4847 4544 4241 403F 3F3E" $"3D3F 3E35 3180 3081 2F84 2E86 2D03 3354" $"5D0F 8000 105F 180F 0000 0101 061D 2751" $"8485 8687 8888 8089 3088 8887 8685 8382" $"807E 7C7A 7775 726F 6D6A 6764 615E 5B58" $"5653 504D 4B49 463C 2E2B 2927 251E 1715" $"1413 1212 1110 0F0C 0611 8013 1E14 141B" $"315A A152 4F4D 4B49 4746 4443 4241 403F" $"3E3E 3D3F 3E35 3031 302F 3030 802F 022E" $"2F2F 812E 042D 2E2E 2D2E 802D 032E 3E64" $"1280 000F 3918 2300 0001 0105 1C26 4A7D" $"7F80 8181 8182 3081 8180 7F7E 7D7B 7A78" $"7674 726F 6D6A 6865 6260 5D5A 5855 5250" $"4D4B 4947 443A 2C2A 2826 241C 1614 1312" $"1211 100F 0E0B 0611 8113 1714 1B31 5998" $"504E 4C4A 4847 4544 4341 403F 3F3E 3D3C" $"3E3E 3480 3002 2F30 3080 2F02 2E2F 2F81" $"2E04 2D2E 2E2D 2E80 2D03 3839 6610 8000" $"1240 1B34 0000 0101 041B 2543 7779 7A7A" $"7B7B 7C7C 807B 2E7A 7978 7775 7472 706E" $"6C6A 6866 6361 5E5C 5957 5452 4F4D 4B48" $"4644 4238 2A28 2624 231B 1513 1312 1110" $"0F0F 0E0B 0611 8013 1814 141B 3158 904F" $"4C4B 4947 4644 4342 4140 3F3E 3E3D 3C3E" $"3D34 8030 012F 3081 2F02 2E2F 2F81 2E02" $"2D2E 2E80 2D04 2C2D 433B 5381 0002 4E1F" $"0E80 000C 0104 1A25 3E71 7374 7475 7576" $"7680 754C 7473 7271 706E 6D6B 6967 6563" $"615F 5D5A 5856 5351 4F4C 4A48 4644 4240" $"3728 2625 2322 1A14 1312 1110 100F 0E0D" $"0B05 1112 1213 1314 1B31 5788 4D4B 4948" $"4645 4342 4140 3F3F 3E3D 3D3C 3E3D 3330" $"3081 2F84 2E86 2D04 2C2D 4F3B 5C81 000F" $"4B20 1E00 0001 0103 1924 396B 6D6E 6F6F" $"8170 306F 6F6E 6E6D 6C6A 6968 6664 6361" $"5F5D 5B59 5754 5250 4E4C 4A48 4644 4240" $"3E35 2725 2322 2019 1312 1211 100F 0E0E" $"0D0A 0511 8113 1714 1B31 5681 4C4A 4847" $"4544 4342 4140 3F3E 3D3D 3C3C 3E3D 3380" $"3080 2F04 2E2F 2F2E 2F82 2E02 2D2E 2E80" $"2D04 2C2D 373B 6581 000D 2B20 3100 0001" $"0102 1724 3565 6869 806A 016B 6B80 6A2E" $"6968 6867 6564 6361 605E 5D5B 5957 5553" $"514F 4D4B 4947 4543 4240 3E3D 3426 2322" $"211F 1912 1211 100F 0E0E 0D0D 0A05 1181" $"1317 141B 3154 7A4A 4947 4644 4342 4140" $"3F3E 3E3D 3D3C 3C3E 3C32 8030 802F 062E" $"2F2F 2E2F 2E2D 802E 022D 2E2E 802D 042C" $"2D39 3B6A 8100 0236 261E 8000 0701 0216" $"2432 5F63 6485 6544 6463 6362 6160 5E5D" $"5C5A 5957 5553 5250 4E4C 4A48 4745 4341" $"403E 3D3B 3324 2221 201E 1812 1110 0F0F" $"0E0D 0D0C 0A05 1112 1213 1314 1B31 5374" $"4947 4645 4342 4140 403F 3E3D 3D80 3C02" $"3E3C 3282 2F84 2E85 2D80 2C03 2D44 3D42" $"8100 0F41 2D19 0000 0101 0214 232F 5A5F" $"5F60 6080 6181 6026 5F5E 5D5C 5B5A 5958" $"5655 5352 504E 4D4B 4948 4644 4341 3F3E" $"3C3B 3A32 2321 201E 1D17 1110 0F0F 0E80" $"0D03 0C0A 0511 8113 1014 1C31 526E 4846" $"4544 4342 4140 3F3E 3E3D 813C 053E 3C31" $"2F30 3080 2F02 2E2F 2F80 2E00 2D80 2E01" $"2D2E 812D 042C 2D51 3D4A 8100 0D13 322D" $"0000 0101 0212 232D 545B 5B85 5C2E 5B5B" $"5A59 5857 5655 5453 5150 4E4D 4B4A 4847" $"4544 4241 3F3E 3C3B 3A38 3122 201F 1E1D" $"1710 0F0F 0E0E 0D0D 0C0C 0A06 1181 1310" $"141C 3251 6847 4544 4342 4140 3F3F 3E3D" $"3D80 3C05 3B3E 3B31 2F30 812F 022E 2F2F" $"802E 002D 802E 0A2D 2E2D 2C2D 2D2C 2C3C" $"3E53 8100 0216 3D3D 8000 0701 0110 222C" $"4F57 5785 582E 5757 5655 5554 5352 504F" $"4E4D 4B4A 4947 4644 4341 403F 3D3C 3A39" $"3837 3021 1F1E 1D1C 160F 0F0E 0E0D 0D0C" $"0C0B 0905 1180 1212 1314 1C32 4F63 4544" $"4342 4140 403F 3E3D 3D3C 3C80 3B02 3D3B" $"3180 2F83 2E86 2D83 2C02 3A3E 5B81 0002" $"1A49 1880 0006 0101 0F21 2A4B 5380 5481" $"5580 542D 5352 5251 504F 4E4D 4C4B 4A49" $"4746 4543 4241 3F3E 3D3B 3A39 3837 362F" $"201E 1D1C 1B16 0F0E 0E0D 0D0C 0C0B 0B09" $"0511 8113 1114 1C32 4E5F 4443 4241 4140" $"3F3E 3E3D 3D3C 3C80 3B02 3D3B 3180 2F02" $"2E2F 2F80 2E03 2D2E 2E2D 802E 802D 072C" $"2D2D 2C2B 4641 2D81 000D 134A 2702 0000" $"0101 0D20 2946 5050 8451 8050 414F 4E4E" $"4D4C 4B4A 4948 4746 4544 4241 403F 3D3C" $"3B3A 3938 3636 352E 1F1D 1C1B 1A15 0E0E" $"0D0D 0C0C 0B0B 0A08 0511 1313 1213 141C" $"324D 5B44 4342 4140 3F3F 3E3D 3D3C 3C81" $"3B02 3D3A 3080 2F02 2E2F 2F80 2E03 2D2E" $"2E2D 802E 802D 072C 2D2D 2C2B 5443 3482" $"0002 4238 0480 0004 010C 2029 4280 4D82" $"4E80 4D21 4C4C 4B4B 4A49 4847 4645 4443" $"4241 403F 3E3D 3C3B 3938 3736 3534 342D" $"1E1C 1B1A 1A14 800D 080C 0C0B 0B0A 0A08" $"0511 8012 1013 131C 324C 5743 4241 403F" $"3F3E 3D3D 3C3C 803B 053A 3B3D 3A30 2F84" $"2E86 2D83 2C03 2A42 443C 8200 0A52 2304" $"0000 0101 0A1F 283F 804A 824B 804A 3F49" $"4948 4847 4646 4544 4342 4140 3F3E 3D3C" $"3B3A 3938 3736 3534 3333 2C1D 1B1A 1A19" $"140D 0D0C 0C0B 0B0A 0A09 0805 1113 1312" $"1314 1C32 4A54 4241 403F 3F3E 3E3D 3D80" $"3C80 3B08 3A3D 392F 2E2F 2F2E 2F81 2E11" $"2D2E 2E2D 2E2D 2D2C 2D2D 2C2D 2D2C 2B3C" $"4743 8200 0C63 1812 0000 0101 091E 273B" $"4747 8448 8047 2546 4645 4544 4342 4241" $"403F 3E3D 3C3B 3A39 3837 3736 3534 3332" $"322C 1D1A 1A19 1813 0D0C 0C0B 0B80 0A14" $"0908 0511 1213 1213 131D 3249 5141 4040" $"3F3E 3E3D 3D80 3C80 3B1F 3A3A 3D39 2F2E" $"2F2F 2E2F 2E2D 2E2E 2D2E 2E2D 2E2D 2D2C" $"2D2D 2C2D 2D2C 2B48 4D13 8200 0236 1724" $"8000 0501 071E 2738 4486 4580 442B 4343" $"4241 4140 3F3F 3E3D 3C3B 3B3A 3938 3736" $"3534 3433 3231 312B 1C1A 1918 1813 0C0C" $"0B0B 0A0A 0909 0808 0510 8012 0E13 131D" $"3248 4E40 403F 3E3E 3D3D 3C3C 803B 813A" $"023D 382F 822E 862D 862C 032B 5653 1582" $"000A 441B 3000 0001 0106 1D26 3680 4282" $"4381 4225 4141 4040 3F3F 3E3D 3D3C 3B3B" $"3A39 3837 3636 3534 3333 3231 3130 2A1C" $"1918 1817 130C 0B0B 0A0A 8009 1208 0805" $"1012 1312 1313 1D32 474C 403F 3F3E 3D3D" $"803C 803B 813A 053C 382F 2E2F 2F80 2E05" $"2D2E 2E2D 2E2E 812D 0A2C 2D2D 2C2D 2C2C" $"2B47 5919 8200 0A53 1E0E 0000 0101 051C" $"2633 8840 803F 143E 3E3D 3D3C 3C3B 3A3A" $"3938 3737 3635 3434 3332 3231 8030 0A2A" $"1B18 1817 1713 0B0B 0A0A 8109 0F08 0705" $"1012 1312 1313 1D32 464A 3F3F 3E80 3D80" $"3C80 3B81 3A04 3C38 2F2E 2F81 2E05 2D2E" $"2E2D 2E2E 812D 0A2C 2D2D 2C2D 2C2C 3237" $"5F1C 8200 0A48 1E20 0000 0101 041B 2531" $"883E 803D 213C 3C3B 3B3A 3A39 3938 3737" $"3635 3534 3333 3231 3130 302F 2F29 1B18" $"1717 1612 0B0A 0A81 0912 0808 0705 1012" $"1312 1313 1D32 4548 3F3E 3E3D 3D80 3C81" $"3B81 3A0F 3C37 2F2E 2F2E 2D2E 2E2D 2E2E" $"2D2E 2D2C 802D 022C 2D2D 812C 033E 3852" $"0282 0002 2F1F 3280 0004 0103 1A25 2F81" $"3C01 3D3D 833C 803B 213A 3A39 3938 3837" $"3736 3535 3434 3332 3231 3030 2F2F 2E2E" $"291A 1717 1616 120A 0A09 0981 0803 0707" $"0510 8012 0B13 131D 3244 463E 3E3D 3D3C" $"3C80 3B80 3A80 3903 3A3C 372F 802E 862D" $"862C 042B 2C4B 3959 8300 0C3B 2518 0000" $"0101 0218 242E 3A3A 833B 823A 8039 1238" $"3837 3736 3635 3534 3433 3232 3131 3030" $"2F2F 802E 0729 1A17 1716 1612 0A80 0981" $"080F 0707 0510 1213 1213 131D 3243 443E" $"3D3D 803C 803B 803A 0039 803A 023C 362F" $"802E 052D 2E2E 2D2E 2E80 2D00 2C80 2D01" $"2C2D 822C 023F 3963 8300 0244 2B1D 8000" $"0501 0217 242D 3886 3981 3880 3701 3636" $"8035 0C34 3433 3332 3131 3030 2F2F 2E2E" $"802D 0128 1A80 1601 1512 8009 8208 0E07" $"0705 1012 1312 1313 1D32 4243 3D3D 813C" $"803B 803A 0539 3A39 3A3C 3681 2E04 2D2E" $"2E2D 2E81 2D00 2C80 2D03 2C2D 2C2B 802C" $"0232 386C 8300 0218 2F2F 8000 0501 0215" $"232B 3784 3882 3780 3680 3503 3434 3333" $"8032 1231 3130 302F 2F2E 2E2D 2D2C 2D28" $"1A16 1615 1511 8108 8207 0206 0510 8112" $"0713 1E32 4142 3D3C 3C80 3B81 3A82 3903" $"3A3C 352E 862D 862C 812B 032C 3E3A 4883" $"0002 1E39 3881 0004 0213 232A 3587 3681" $"3580 3480 3301 3232 8031 0330 302F 2F80" $"2E01 2D2D 802C 0628 1916 1615 1511 8108" $"1007 0807 0706 0605 1012 1312 1313 1E32" $"4041 803C 803B 053A 3B3A 393A 3A80 3909" $"3A3B 352E 2D2E 2E2D 2E2E 802D 032C 2D2D" $"2C80 2D80 2C00 2B80 2C02 4C3B 4983 0002" $"2444 1B81 0004 0112 222A 3486 3582 3480" $"3380 3280 3101 3030 802F 012E 2E80 2D81" $"2C01 2719 8015 0514 1108 0708 0881 0703" $"0606 0510 8012 0513 131E 3240 4080 3C80" $"3B80 3A02 393A 3A80 3909 3A3B 342E 2D2E" $"2E2D 2E2E 802D 032C 2D2D 2C80 2D80 2C00" $"2B80 2C02 433C 5283 0002 1443 2B81 0004" $"0110 2129 3285 3483 3380 3280 3180 3080" $"2F80 2E01 2D2D 802C 802B 0627 1915 1514" $"1411 8207 8206 0105 1081 1204 131E 323F" $"3F80 3B82 3A81 3980 3802 3A3B 3485 2D86" $"2C84 2B02 333C 5B84 0001 463E 8100 0401" $"0E21 2831 8333 8432 8231 8030 802F 802E" $"802D 012C 2C82 2B01 2719 8015 0114 1181" $"0700 0680 0703 0606 0510 8012 0A13 131E" $"323E 3E3C 3B3B 3A3B 813A 8039 0938 3939" $"3A3B 332E 2D2E 2E80 2D13 2C2D 2D2C 2D2D" $"2C2D 2C2C 2B2C 2C2B 2C2C 2B41 3E3A 8400" $"0256 1E03 8000 0401 0D20 2830 8432 8431" $"8130 812F 802E 812D 802C 822B 0627 1914" $"1514 1411 8107 0006 8007 0306 0605 1080" $"1205 1313 1E32 3E3E 803B 803A 0239 3A3A" $"8039 0938 3939 3A3B 332E 2D2E 2E80 2D05" $"2C2D 2D2C 2D2D 812C 092B 2C2C 2B2C 2C2A" $"4E40 3684 0002 5F18 1380 0004 010B 1F27" $"2F85 3184 3081 2F81 2E80 2D80 2C81 2B81" $"2A01 2719 8014 0113 1187 0602 0510 1180" $"1205 131F 323D 3D3B 813A 8239 8238 023A" $"3A32 822D 872C 852B 032A 4941 3E84 0002" $"3B1A 2480 0004 010A 1F27 2E87 3083 2F81" $"2E82 2D81 2C80 2B82 2A01 2719 8014 0613" $"1107 0607 0706 8007 0306 0605 1080 1207" $"1313 1E32 3D3C 3B3B 813A 8039 0938 3939" $"3839 3839 3A32 2E80 2D07 2C2D 2D2C 2D2D" $"2C2D 822C 022B 2C2C 802B 0329 3642 4684" $"0002 491D 2880 0005 0108 1E27 2D2F 8030" $"862F 832E 812D 802C 012B 2C81 2B82 2A01" $"2719 8014 0813 1106 0607 0706 0707 8006" $"0105 1080 120B 1313 1E32 3C3C 3B3A 3A39" $"3A3A 8039 0238 3939 8038 0339 3A31 2E80" $"2D05 2C2D 2D2C 2D2D 802C 002B 802C 022B" $"2C2C 802B 0328 4546 2684 0002 581D 1080" $"0004 0107 1D26 2C81 2F88 2E82 2D81 2C82" $"2B81 2A80 2903 2A27 1914 8013 0011 8606" $"0305 0510 1181 1205 1E32 3C3B 3A3A 8239" $"8438 0537 393A 312D 2D87 2C86 2B05 2A2A" $"2753 4F1C 8400 0245 1C21 8000 0401 061C" $"252C 872E 012D 2E84 2D81 2C83 2B80 2A01" $"292A 8029 0626 1913 1414 1311 8106 0005" $"8006 0C05 0605 1011 1212 1313 1F32 3B3B" $"803A 0739 3A39 3839 3938 3981 380B 3939" $"302D 2C2D 2D2C 2D2D 2C2D 812C 002B 802C" $"802B 062A 2B2B 265D 5320 8400 0234 1E33" $"8000 0501 051B 252B 2D80 2E02 2D2E 2E83" $"2D02 2C2D 2D81 2C01 2B2C 812B 012A 2B81" $"2A82 290B 2619 1314 1413 1106 0506 0605" $"8006 0B05 0605 1011 1212 1313 1F32 3B81" $"3A80 3902 3839 3980 380C 3738 3839 3930" $"2D2C 2D2D 2C2D 2D80 2C03 2B2C 2C2B 802C" $"802B 062A 2B2B 2C36 5825 8400 0242 2313" $"8000 0401 041A 242B 872D 022C 2D2D 842C" $"802B 022A 2B2B 802A 0229 2A2A 8229 0B26" $"1913 1413 1311 0605 0606 0580 060B 0506" $"0510 1112 1213 131F 323B 803A 8039 8238" $"0737 3736 3635 3636 2E81 2D02 2C2D 2D80" $"2C03 2B2C 2C2B 802C 802B 062A 2B2B 3738" $"5918 8400 0245 281E 8100 0303 1924 2A8B" $"2C84 2B83 2A83 2980 2802 2926 1980 1301" $"1211 8805 0210 1111 8012 171F 3139 3837" $"3736 3535 3433 3231 302F 2E2C 2B2A 2928" $"292A 2B83 2C87 2B81 2A03 2B42 3A5B 8500" $"021F 2B30 8000 0401 0218 232A 872C 042B" $"2C2C 2B2C 822B 022A 2B2B 802A 0229 2A2A" $"8029 0028 8129 0126 1A80 1306 1211 0605" $"0606 0580 0603 0506 050E 820F 0B19 282D" $"2D2B 2A28 2726 2524 2480 2384 2205 2325" $"2729 2A2B 812C 0F2B 2C2C 2B2C 2B2B 2A2B" $"2B2A 2B2B 4D3B 6485 0002 2733 3380 0005" $"0102 1623 292B 802C 052B 2C2C 2B2C 2C83" $"2B00 2A80 2B81 2A83 2901 2828 8027 0A26" $"2623 1714 1313 1213 0B06 8505 0004 8305" $"020F 1B21 8A22 0321 2222 2180 2207 2122" $"2224 2628 292A 802B 002C 812B 082A 2B2B" $"2A2B 2B2D 386E 8500 022E 3D1C 8100 0301" $"1422 298A 2B80 2A80 291C 2828 2727 2626" $"2524 2423 2221 201E 1D1C 1A19 1613 1414" $"1313 1212 0F09 0584 0400 0280 0305 0404" $"0F1B 2122 9621 0522 2426 282A 2A82 2B82" $"2A02 3938 6485 0002 143B 2C80 0005 0101" $"1222 282B 812A 1929 2928 2827 2726 2525" $"2423 2221 201E 1D1B 1A19 1716 1514 1312" $"1182 1003 0F10 1112 8213 0312 1210 0A80" $"0503 0405 0402 8003 0704 040E 1B20 2122" $"228E 2106 2021 2120 2121 2080 2108 2325" $"2729 292A 2A2B 2B80 2A02 453A 4786 0002" $"492A 0F80 0014 010F 1D22 2424 2222 201F" $"1E1C 1B19 1817 1615 1413 1280 1183 1008" $"0F10 100F 1010 0F10 1082 0F01 1012 8313" $"0712 110B 0504 0504 0281 0303 040E 1A20" $"8121 0820 2121 2021 2120 2121 8020 801F" $"0820 2021 2120 2121 2021 8220 0521 2326" $"2729 2980 2A02 4741 5386 0002 621D 1E81" $"0006 0610 1213 1312 1281 1189 108D 0F81" $"0E03 0F0F 1012 8113 8012 0511 0C06 0402" $"0280 0303 040E 1A1F 8120 071F 1F1E 1E1D" $"1D1C 1C81 1B80 1A02 1B1D 1F83 2081 1F02" $"1E1E 1D80 1C80 1D03 284A 455F 8600 0333" $"2316 1180 0002 020A 0E87 1006 0F10 100F" $"1010 0F80 1089 0F00 0E80 0F03 0E0F 0F0E" $"810F 0110 1282 1380 1203 0D13 0001 8002" $"020C 161A 841B 071A 1B1B 1A1B 1B1A 1B83" $"1A17 1919 1A1B 1B1A 1918 1614 1211 1011" $"2136 1C2F 3430 4439 4B48 8600 0A09 401B" $"2204 0000 0109 0D0F 8010 050F 1010 0F10" $"108A 0F08 0E0F 0F0E 0F0F 0E0F 0F8C 0E07" $"0D0C 0B0A 0807 0604 8200 0401 0A14 191A" $"801B 831A 2219 1918 1817 1615 1412 110F" $"0D0B 0908 0605 1749 2B2E 462F 4545 2924" $"2929 2E3A 3E55 6A11 8700 082C 2F16 1C00" $"0001 090D 890F 890E 0E0D 0D0C 0B0A 0908" $"0807 0605 0504 060B 830D 040A 0807 0505" $"8204 8102 1900 0007 1317 1918 1717 1615" $"1412 110F 0D0C 0A08 0705 0403 0301 0184" $"000F 0F29 3537 2E3B 4C62 728A A141 4034" $"1F0B 8800 0926 4F26 270A 0001 080D 0E80" $"0F04 0E0F 0F0E 0F80 0E09 0D0D 0C0B 0A09" $"0808 0706 8105 0604 0505 0405 0504 8005" $"0904 0505 080C 0E0D 0E0D 0780 0801 0605" $"8004 1103 0203 0302 0302 0207 0C0C 0A08" $"0706 0404 0383 020D 0302 0203 0301 0001" $"0100 0101 0001 8000 0B0F 2E55 7888 9DAB" $"B6BB 9450 1288 0013 3051 2C21 1824 0000" $"070B 0D0C 0C0B 0A09 0807 0706 8005 0304" $"0505 0480 050E 0405 0504 0505 0405 0504" $"0505 0405 0583 0405 080C 0C0B 0403 8004" $"0003 8001 9703 1C02 0303 0100 0101 0001" $"0104 090C 1920 2B3E 4668 96AB ACA9 ACB2" $"BABD 9A4B 8600 0B55 2C28 2917 2900 0001" $"0304 059A 0481 0380 0280 010E 0001 041B" $"0508 0B11 2540 5A5E 340D 0495 0310 040D" $"1016 242A 3F4B 5B6D 7584 8B92 9A9B 9C81" $"9D08 A0AE B5C0 C5CD D4D9 8B85 000A 5328" $"2A01 0202 0100 0103 0480 0505 0405 0504" $"0505 8704 8103 8002 8001 8200 8001 8300" $"0D2B 181B 1E20 2539 566F 7D65 310C 0588" $"040F 0506 0914 1627 2F3E 545B 747C 8A96" $"979E 8CA1 0AA2 A3A3 A4AB C2D4 DADA C40E" $"8400 0351 2A1F 0280 0302 0101 0285 0481" $"0381 0280 0182 0080 0180 0280 0381 0400" $"0384 001E 010E 1C1F 2224 2C42 5F76 8166" $"3012 0808 0A14 1A23 353C 525E 7082 8896" $"9CA1 A682 A702 A8A8 A684 A513 A6A6 A7AA" $"ADB2 B7BD C3CA D0D6 DDE2 E4E3 D9D2 CA1C" $"8400 034D 2321 0280 0402 0300 0181 0282" $"0181 0080 0103 0202 0303 8104 0805 0504" $"0505 0405 0504 8105 0104 0185 0014 0417" $"2123 2528 334C 677D 888A 8282 8993 9FA2" $"A7A9 A982 AA84 AB10 ACAD ADAB ACAE B2B7" $"BDC2 C9CF D5DA DFE2 E380 E50A E4E3 E2E0" $"DEDC DDCD CDC4 1D84 0003 5419 0901 8104" $"0303 0100 0080 0103 0202 0303 8104 9505" $"1A04 0100 0001 0204 0606 0A0B 0F19 2225" $"2729 2D3A 556F 8393 A1AA ACAC 81AD 81AE" $"26AF AFB0 B2B6 BABF C5CC D4DA DADE E2E4" $"E6E7 E8E7 E7E6 E5E3 E1DE DBD8 D5D1 CDCA" $"C7C4 C2C1 B7CA BE1D 8400 0448 1B1D 0003" $"8205 0004 8A05 0206 0605 8006 1A05 0606" $"0506 0605 0606 0506 0708 0A0C 0E12 1312" $"1516 191B 1C1E 1B1B 801C 341D 2126 282B" $"2D31 425E 7789 99A7 AEB1 B2B4 B8BD C3C9" $"CFD6 DDE3 E8EC EEF0 F2F3 F7F5 ECEA E8E6" $"E3E0 DCD8 D4D0 CDC9 C6C4 C3C1 C0C0 BFBF" $"81BE 03B4 BCBB 1D84 000A 351D 2E00 0205" $"0606 0506 0591 0611 0709 0A0D 0E11 1517" $"1B1D 1F21 2224 2425 2421 831F 2E1C 1C1D" $"1D1E 1F20 2227 2A2C 2E30 364A 667D 8FA7" $"D3E6 EAEE F1F3 F5F7 F8FA FAFB FCFA F8F4" $"EEEC E4D5 CFCC C8C6 C4C3 C2C2 80C1 81C0" $"80BF 80BE 05BD BEB6 BAAE 0F84 0005 4221" $"2100 0104 8A06 8007 0C0A 0A0C 1011 1517" $"1B1E 1F22 2324 8225 8526 0B22 2122 2325" $"2627 2324 2425 2581 261F 272B 2D2F 3133" $"3C52 70AD F1FD FDFE FEFD FAF6 F1EB E5DF" $"D9D5 D2D0 CED0 CEC3 C2C2 82C1 82C0 80BF" $"80BE 80BD 04BC BEBB BAA5 8500 0651 2619" $"0000 0306 8107 0D08 090B 0C0F 1114 1819" $"1E1F 2123 2480 2586 260C 2727 282A 2B2D" $"3032 3437 3830 2D82 2E00 2682 2518 2424" $"2323 2B2D 2E30 3234 3750 9FD7 EFE5 DFDA" $"D5D1 CFCE CECD CE82 CD02 D0CD C283 C182" $"C080 BF81 BE80 BD04 BCBE BCB9 A885 000F" $"2924 2A00 0001 060D 151A 1D1F 2023 2424" $"8125 8526 1C27 2829 2B2C 2E31 3336 383A" $"3C3D 3F40 4041 4243 4135 2F2F 2E2E 2D2D" $"2222 8021 8120 0B21 2B2C 2E30 3133 3549" $"96B7 CC82 CE83 CD06 CCCD CCCC CFCC C280" $"C183 C080 BF81 BE80 BD80 BC03 BEB0 B8AB" $"8500 0929 2B34 0000 0109 1720 2480 2583" $"2620 2728 2A2B 2D30 3234 3739 3B3D 3E3F" $"4041 4244 494D 4F4E 4D4A 4846 4544 4032" $"2B2A 2A80 2903 1F1F 1E1E 821F 0B21 2A2C" $"2E30 3133 3449 96B7 CC83 CD86 CC02 CECB" $"C182 C081 BF82 BE80 BD80 BC05 BBBB BEB3" $"B796 8500 2A33 3417 0000 0105 141D 2327" $"292A 2C2E 3133 3538 3A3C 3D3F 4040 4144" $"4B5F 7381 8E87 7D74 6A60 564C 4541 403F" $"813E 013B 2F80 2902 2829 2980 1F00 1E82" $"1F10 202A 2C2E 2F31 3234 4996 B7CB CDCD" $"CCCD CD83 CC06 CBCC CBCB CECA C180 C083" $"BF80 BE81 BD80 BC06 BBBB BABD B7B6 7785" $"0002 1D39 2880 001B 020E 1B2D 3A3D 3E3F" $"4041 4349 526F 7C95 A3B2 ABAB A59C 806F" $"5345 413F 853E 823D 073B 2F28 2929 2829" $"2980 1F00 1E82 1F0B 202A 2C2D 2F30 3234" $"4996 B7CB 85CC 84CB 04CD C9C0 BFC0 81BF" $"80BE 01BD BE80 BD80 BC01 BBBB 80BA 03BD" $"B5B6 7B85 0002 0243 3A80 0012 0107 2039" $"4E80 93A4 B0B5 ADB4 9C8E 7064 4941 3F81" $"3E8C 3D04 3C3C 3D3B 3083 2800 1F83 1E0E" $"1F1F 2029 2B2D 2E30 3233 4996 B6CA CC86" $"CB82 CA01 CDC8 80BF 82BE 81BD 81BC 80BB" $"80BA 04B9 BDAD B47E 8500 1003 531B 0100" $"0001 0323 384C 6B60 4C41 3F3F 833E 033D" $"3E3E 3D80 3E07 3D3E 3E3D 3E3E 3D3E 813D" $"003C 813D 073B 3028 2929 2829 2980 1F00" $"1E80 1F0D 1E1F 2029 2B2C 2E30 3133 4A96" $"B7C9 85CB 84CA 02CC C7BF 83BE 80BD 82BC" $"01BB BB80 BA80 B903 BCB0 B35F 8500 0A03" $"5B1C 0B00 0001 031F 333C 803E 0C3D 3E3E" $"3D3E 3E3D 3E3E 3D3E 3E3D 803E 053D 3E3E" $"3D3E 3E80 3D03 3C3D 3D3C 813D 073B 3028" $"2929 2829 2880 1F00 1E80 1F11 1E1F 2028" $"2A2C 2E2F 3133 4A96 B6C9 CBCB CACB 84CA" $"81C9 01CC C681 BE82 BD81 BC80 BB80 BA80" $"B904 B8BB B5B2 4C86 0009 3C24 1500 0001" $"021C 323B 973D 863C 023D 3B30 8328 001F" $"851E 0B1F 282A 2C2D 2F31 324B 96B6 C882" $"CA85 C904 C8C9 CBC6 BE81 BD82 BC80 BB81" $"BA80 B980 B803 BAB3 B150 8600 1B4B 2817" $"0000 0101 1A31 3B3D 3E3E 3D3E 3E3D 3E3E" $"3D3E 3E3D 3E3E 3D3E 3E84 3D06 3C3D 3D3C" $"3D3D 3C81 3D04 3B30 2829 2980 2803 1F1E" $"1F1E 801F 0F1E 1E1F 2729 2B2D 2F30 324B" $"96B6 C8CA CA86 C981 C801 CBC5 81BD 82BC" $"81BB 80BA 80B9 80B8 04B7 B8AE B054 8600" $"155B 1A0F 0000 0101 1830 3A3D 3E3E 3D3E" $"3E3D 3E3E 3D3E 3E84 3D14 3C3D 3D3C 3D3D" $"3C3D 3D3C 3D3D 3C3D 3D3C 3C3B 3028 2981" $"2800 1F80 1E80 1F0D 1E1E 1F27 292B 2C2E" $"3031 4B96 B6C7 82C9 02C8 C9C9 84C8 02CA" $"C4BD 82BC 81BB 80BA 81B9 80B8 80B7 03B5" $"B4B0 2D86 000F 4619 1F00 0001 0115 2F3A" $"3D3E 3E3D 3E3E 863D 003C 803D 0B3C 3D3D" $"3C3D 3D3C 3D3D 3C3D 3D82 3C08 3B31 2829" $"2827 2828 1F81 1E11 1F1F 1E1E 1F27 292A" $"2C2E 2F31 4B96 B6C7 C9C9 83C8 01C7 C882" $"C701 C9C3 81BC 80BB 82BA 80B9 80B8 01B7" $"B780 B603 B1BB B022 8600 0238 1B32 8000" $"0301 122E 3986 3D94 3C80 3B04 3C3B 3128" $"2881 2702 1F1D 1D84 1E0A 2628 2A2C 2D2F" $"314C 96B5 C680 C885 C780 C602 C7C9 C181" $"BB82 BA81 B980 B880 B781 B603 ADBB B124" $"8600 1946 1F10 0000 0101 102D 393C 3D3D" $"3C3D 3D3C 3D3D 3C3D 3D3C 3D3D 3C80 3D05" $"3C3D 3D3C 3D3D 833C 003B 813C 013B 3180" $"2806 2728 281F 1E1E 1D83 1E0B 2628 292B" $"2D2F 304C 96B5 C6C8 84C7 08C6 C7C6 C6C5" $"C5C6 C8C1 80BB 81BA 82B9 80B8 01B7 B780" $"B606 B5B5 B6AE B3B2 2786 0019 4823 1D00" $"0001 010E 2C38 3C3D 3D3C 3D3D 3C3D 3D3C" $"3D3D 3C3D 3D3C 803D 023C 3D3D 833C 033B" $"3C3C 3B81 3C01 3B31 8028 0627 2828 1F1E" $"1E1D 831E 0A26 2729 2B2D 2E30 4C96 B5C5" $"82C7 80C6 80C5 80C4 03C6 C7C0 BB80 BA01" $"B9BA 80B9 81B8 80B7 80B6 07B5 B5B4 B5B1" $"B2A9 0B86 0002 2625 2F80 0003 010C 2B37" $"953C 883B 033C 3B31 2882 2700 1F83 1D80" $"1E0A 2527 292A 2C2E 2F4D 96B5 C580 C681" $"C583 C404 C3C5 C7BF BA82 B981 B880 B780" $"B680 B580 B403 B5B4 B2A7 8700 0230 2C30" $"8000 1201 0A2A 373C 3D3D 3C3D 3D3C 3D3D" $"3C3D 3D3C 3D3D 843C 0F3B 3C3C 3B3C 3C3B" $"3C3C 3B3C 3C3B 3B3A 3280 2806 2728 281F" $"1E1E 1D80 1E12 1D1E 1E25 2728 2A2C 2D2F" $"4D96 B4C4 C5C5 C4C5 C583 C480 C302 C4C6" $"BE81 B982 B880 B780 B680 B507 B4B4 B3B3" $"B5AE B1AA 8700 023A 341B 8000 0C01 0828" $"363C 3D3D 3C3D 3D3C 3D3D 873C 0B3B 3C3C" $"3B3C 3C3B 3C3C 3B3C 3C82 3B01 3A32 8028" $"0627 2828 1F1E 1E1D 801E 0D1D 1E1D 2426" $"282A 2B2D 2F4D 96B4 C382 C402 C3C4 C482" $"C304 C2C4 C5BD B982 B881 B780 B681 B508" $"B4B4 B3B3 B2B5 AAB0 AD87 0002 1C38 2A80" $"0004 0107 2735 3B87 3C93 3B05 3A3A 3B3A" $"3228 8227 001F 861D 0924 2627 292B 2D2F" $"4D96 B486 C383 C204 C3C4 BCB8 B882 B780" $"B681 B580 B480 B305 B2B2 B5AC AF80 8700" $"020A 433F 8100 1205 2534 3B3C 3C3B 3C3C" $"3B3C 3C3B 3C3C 3B3C 3C3B 803C 053B 3C3C" $"3B3C 3C83 3B00 3A81 3B01 3A32 8028 8027" $"031F 1D1E 1D80 1E80 1D0A 2325 2729 2A2C" $"2E4E 96B4 C282 C301 C2C3 81C2 06C1 C2C1" $"C2C3 BBB8 82B7 81B6 80B5 80B4 01B3 B380" $"B204 B1B5 B1AF 7C87 0003 0C53 1802 8000" $"1204 2333 3B3C 3C3B 3C3C 3B3C 3C3B 3C3C" $"3B3C 3C3B 803C 043B 3C3C 3B3C 813B 033A" $"3B3B 3A81 3B01 3A32 8028 8027 001F 801D" $"801E 0F1D 1D1C 2325 2728 2A2C 2E4E 96B4" $"C2C3 C383 C283 C102 C2C2 BA80 B781 B680" $"B580 B481 B380 B205 B1B1 B4AC AE80 8700" $"030A 5421 0980 0003 0321 323A 943B 883A" $"033B 3A32 2880 2703 2626 1F1C 841D 0D1C" $"2224 2628 2A2B 2D4F 96B3 C1C2 C284 C182" $"C002 C1C2 B981 B681 B580 B480 B380 B280" $"B105 B0B0 B4A6 AD86 8800 023E 2C10 8000" $"1102 1F32 3A3C 3C3B 3C3C 3B3C 3C3B 3C3C" $"3B3C 3C84 3B0B 3A3B 3B3A 3B3B 3A3B 3B3A" $"3B3B 803A 0732 2828 2726 2727 1F82 1D0F" $"1E1D 1D1C 2224 2627 292B 2D4F 96B3 C1C2" $"84C1 83C0 05C2 C1B9 B6B5 B680 B581 B480" $"B380 B280 B106 B0B0 AFB3 AAAC 5C88 0002" $"4D22 0A80 000D 011D 313A 3C3C 3B3C 3C3B" $"3C3C 3B3C 853B 0B3A 3B3B 3A3B 3B3A 3B3B" $"3A3B 3B83 3A0A 3228 2727 2627 271F 1D1D" $"1C82 1D10 1C21 2425 2729 2A2C 4F96 B3C0" $"C1C1 C0C1 C181 C000 C182 C002 BFB9 B680" $"B580 B481 B380 B280 B101 B0B0 80AF 03B2" $"B0AB 5488 0002 5E19 1080 0003 011A 3039" $"883B 913A 8039 043A 3A32 2827 8126 001F" $"821C 801D 0B1C 2123 2526 282A 2C4F 96B3" $"C084 C10B C0C0 BFBE BCBA B8B7 B6B7 B7B6" $"80B4 80B3 81B2 80B1 01B0 B080 AF05 AEAE" $"B0A8 AA58 8800 0236 1924 8000 1201 182F" $"393B 3B3A 3B3B 3A3B 3B3A 3B3B 3A3B 3B3A" $"803B 053A 3B3B 3A3B 3B83 3A00 3981 3A01" $"3932 8027 0626 2727 1F1D 1D1C 821D 0A1B" $"2023 2426 2829 2C50 97B4 80C1 08C0 BFBE" $"BDBB B9B7 B5B3 80B2 06B1 B1B3 B5B6 B6B4" $"80B3 80B2 80B1 80B0 80AF 81AE 02A7 A85C" $"8800 0240 1C34 8000 1201 152E 383B 3B3A" $"3B3B 3A3B 3B3A 3B3B 3A3B 3B3A 803B 023A" $"3B3B 833A 0339 3A3A 3981 3A01 3933 8027" $"0626 2727 201D 1D1C 801D 121C 1D1B 2022" $"2526 282A 2C51 96B1 BCBB B9B7 B5B4 80B2" $"85B1 05B0 B1B3 B5B5 B480 B280 B181 B001" $"AFAF 80AE 05AD ADAC ACA8 2988 0002 4E20" $"0E80 0014 0113 2D37 3B3B 3A3B 3B3A 3B3B" $"3A3B 3B3A 3B3B 3A3B 3B84 3A06 393A 3A39" $"3A3A 3980 3A02 3939 3380 2706 2627 271F" $"1D1D 1C80 1D0E 1C1D 1B20 2223 2526 2728" $"4B8C A6B2 B287 B184 B001 AFB1 80B4 00B2" $"80B1 80B0 01AF AF80 AE07 ADAD ACAC A8B4" $"A82B 8800 0248 2120 8000 0301 112C 378F" $"3A8D 3903 3A3A 3327 8226 001F 851C 0A19" $"1D1E 1E1F 2021 2348 88A3 8AB0 83AF 08AE" $"AEAF B1B3 B3B2 B0B0 80AF 80AE 09AD ADAC" $"ACAB ACA5 AFA8 2E88 0002 2B23 3280 000A" $"010E 2B36 3A3B 3A3B 3B3A 3B84 3A00 3980" $"3A06 393A 3A39 3A3A 3988 3A03 3228 2727" $"8026 0022 811C 0E1D 1D1C 1C17 191A 1C1E" $"1F21 2348 89A3 86B0 01AF B083 AF83 AE00" $"AF80 B204 B0AF AFAE AE80 AD08 ACAC ABAB" $"ACA7 A9AA 3288 0002 3529 1D80 0003 010C" $"2A35 883A 0339 3A3A 3980 3A00 3981 3A82" $"3B0B 3A3A 3938 3634 3230 2D2B 2827 8026" $"0325 201C 1B82 1C0F 1718 1A1C 1D1F 2022" $"4888 A3AF B0B0 AFB0 84AF 84AE 81AD 06AC" $"ADAF B1B1 B0AE 80AD 01AC AC80 AB05 AAAB" $"A9AA A704 8800 0241 311E 8100 020A 2835" $"8A39 813A 823B 0A3A 3A39 3836 3532 302E" $"2C2B 802A 052B 2C2B 2726 2680 2500 1F80" $"1B80 1C0B 1718 1A1B 1D1E 2022 4888 A2AE" $"81AF 86AE 82AD 82AC 06AB ABAD B0B0 AFAE" $"80AC 08AB ABAA AAA9 ABAB ACA9 8900 020E" $"322F 8000 0901 0827 3439 3A39 3A3A 3982" $"3A82 3B0A 3A3A 3938 3635 3230 2E2C 2B80" $"2A00 2980 2A05 292A 2A2B 2B2A 8026 0325" $"2625 1F82 1C0A 1617 191B 1D1E 2021 4988" $"A286 AE02 ADAE AE80 AD01 ACAD 82AC 80AB" $"11AA AAAB ADAF AFAE ACAB ABAA AAA9 A9AB" $"A2A9 AD89 0002 113E 3080 0004 0107 2633" $"3981 3A83 3B09 3A39 3836 3532 302E 2C2B" $"802A 0629 2A2A 292A 2A29 802A 0029 802A" $"1D2B 2B29 2626 2526 2625 1E1C 1C1B 1C16" $"1719 1A1C 1E1F 2149 88A2 ADAE AEAD AE84" $"AD84 AC80 AB82 AA07 A9A9 ABAD AEAD ABAA" $"80A9 04A8 ABA1 A7AB 8900 0315 4A17 0280" $"0003 0525 343A 803B 0C3A 3A39 3836 3532" $"302E 2C2B 2A2A 9229 042A 2B2B 2826 8125" $"0F24 1E1B 1B1C 1616 181A 1B1D 1F20 4988" $"A283 AD85 AC82 AB82 AA80 A980 A80C A9AB" $"ADAC ABA9 A8A8 A7AA A5A6 7C89 0018 0839" $"2506 0000 0104 2332 3838 3635 3230 2E2C" $"2B2A 2A29 2A2A 2980 2A0C 292A 2A29 2A2A" $"292A 2A29 2A2A 2980 2A0A 292A 2A29 2A2A" $"2B2B 2826 2680 2511 241D 1B1B 1616 1819" $"1B1D 1E20 4987 A1AC ADAD 86AC 83AB 81AA" $"80A9 80A8 81A7 0AA9 ABAB AAA9 A7A7 AAAA" $"A67F 8A00 0240 2010 8000 1102 1C29 2D2C" $"2B2A 2A29 2A2A 292A 2A29 2A2A 2980 2A0C" $"292A 2A29 2A2A 292A 2A29 2A2A 2980 2A83" $"2917 2A2B 2A27 2525 2425 2524 1D1B 1515" $"1719 1A1C 1E20 4A87 A1AB 82AC 85AB 82AA" $"81A9 81A8 80A7 0CA6 A6A5 A6A9 AAAA A8A6" $"AAA0 A685 8A00 0254 1B1E 8100 0215 2228" $"A029 8128 0529 2A2B 2A26 2581 240C 231C" $"1515 1718 1A1C 1D1F 4A88 A185 AB83 AA82" $"A981 A881 A780 A680 A509 A4A4 A6A8 A9A8" $"AB9E A489 8A00 0233 241A 8100 0F13 2128" $"2A29 2A2A 292A 2A29 2A2A 292A 2A8D 2900" $"2880 290C 2829 2928 2929 2829 2A2A 2926" $"2480 2511 2422 1414 1618 191B 1D1F 4A87" $"A0AA ABAB AAAB 84AA 82A9 82A8 80A7 80A6" $"80A5 01A4 A480 A306 A4A6 A7AD A7A4 538A" $"0003 2A35 2803 8000 0211 2127 8E29 0C28" $"2929 2829 2928 2929 2829 2928 8029 0B28" $"2929 2829 2928 2929 2A2A 2981 250C 2423" $"3F1D 1517 191B 1C1E 4B87 A083 AA01 A9AA" $"81A9 01A8 A982 A880 A781 A680 A501 A4A4" $"80A3 08A2 9F98 8B7C 8CA2 A65C 8A00 0308" $"4B19 1A80 0002 1020 27A7 2804 292A 2A28" $"2580 240B 2334 431A 1719 1A1C 1E4B 87A0" $"85A9 83A8 82A7 82A6 80A5 0FA4 A4A3 A19C" $"917E 746E 727A 848F 92A4 558B 0002 5023" $"2880 0010 0E1F 2729 2829 2928 2929 2829" $"2928 2929 2880 290C 2829 2928 2929 2829" $"2928 2929 2880 291C 2829 2928 2929 2829" $"2828 292A 2A27 2524 2423 352E 3618 181A" $"1B1D 4B87 A083 A983 A882 A781 A680 A512" $"A4A3 9F96 8674 7271 7880 827B 7674 767E" $"7C6F 068B 0002 3A30 2980 0010 0C1F 2629" $"2829 2928 2929 2829 2928 2929 2880 290C" $"2829 2928 2929 2829 2928 2929 2880 2902" $"2829 2983 2813 2728 292A 2A27 2423 2235" $"2F2C 2616 191B 1D4C 879F 86A8 82A7 82A6" $"15A5 A4A1 9A8D 7872 7376 7B88 7F78 7573" $"7A8C 6F52 3B1E 048D 0016 1743 1914 0000" $"0A1E 2628 2829 2928 2929 2829 2928 2929" $"2880 290E 2829 2928 2929 2829 2928 2929" $"2829 2984 2819 2728 2827 2828 292A 2926" $"2422 3430 3428 4017 1A1C 4C87 9FA7 A8A8" $"83A7 01A6 A781 A614 A5A3 9D92 816F 7376" $"7A87 807A 7675 787F 7C66 432C 0293 0007" $"571C 1900 0009 1D25 9E28 8927 1028 292A" $"2925 2234 3053 3D30 3C18 1C4C 879E 80A7" $"84A6 14A5 A49F 9686 7672 7576 828A 7C78" $"7678 8182 674F 360E 9800 153C 2526 0000" $"081C 2528 2829 2928 2929 2829 2928 2929" $"2880 2901 2829 8728 0027 8028 1C27 2828" $"2728 2827 2828 2728 2827 2829 2928 2335" $"324B 6E3D 2C2D 1A4C 869E 83A6 13A4 A199" $"8C7A 7175 797F 8281 7A77 777E 8178 5641" $"229D 0007 2636 1D0D 0006 1B24 9428 0627" $"2828 2728 2827 8028 3227 2828 2728 2827" $"2828 2728 2827 2728 2929 2637 3833 154E" $"2C2E 2E4B 869E A6A5 A29C 917E 756F 737C" $"8083 7A78 777B 857C 624A 220C A100 0703" $"4A1A 1700 051B 24AD 271E 2829 2845 3F37" $"000E 2C37 5657 6F8B 8572 7471 7980 837C" $"7674 747C 7568 553C 0EA7 0014 4A24 2300" $"0319 2327 2728 2827 2828 2728 2827 2828" $"2780 280C 2728 2827 2828 2728 2827 2828" $"2780 2807 2728 2827 2828 2728 8127 1D26" $"2624 211E 4249 4843 0000 1074 5D68 6964" $"7487 7E78 7573 798B 6C4E 391B 02AB 0014" $"3333 2603 0219 2327 2728 2827 2828 2728" $"2827 2828 2780 280C 2728 2827 2828 2728" $"2827 2828 2780 2802 2728 2881 270D 2626" $"2422 1F22 3238 3848 4344 5F39 8000 0B33" $"6061 6366 6A74 7C77 633E 28B1 0006 1A4D" $"211B 0117 22A1 2711 2625 221F 222E 323B" $"4546 3236 3D4B 5E6E 5801 8100 0611 1717" $"1817 1D0B B500 1401 571F 1B00 1622 2727" $"2828 2728 2827 2828 2728 2827 8028 0A27" $"2828 2728 2827 2828 2728 8127 1325 2320" $"1F2D 353E 4040 3B35 3B47 5869 684A 3E1B" $"05C3 0013 3F27 2400 1421 2627 2828 2728" $"2827 2828 2728 2827 8028 0527 2828 2728" $"2881 2713 2624 201C 2C36 363E 463D 343A" $"4354 6E65 573A 250D C800 0619 3A20 0A12" $"2026 9227 1326 2421 1D22 3938 4148 3937" $"3941 4E64 6F62 4331 0CCD 0006 0750 1E23" $"1020 268C 2715 2626 2422 1F1E 3234 3743" $"4636 383F 4B5F 7964 5130 1402 D200 0E49" $"2828 0D1E 2526 2727 2627 2726 2727 8026" $"1225 231F 202A 3139 444A 3134 3A48 5C6B" $"6B5A 3A22 D800 8035 020E 1D25 8426 1325" $"2320 1E29 343B 3C43 3D33 3944 5467 6C4E" $"411F 08DC 001B 124C 251E 1C25 2626 2523" $"201C 2833 363D 4640 3439 4151 6866 5B3E" $"2C12 E200 1645 2938 1C1E 1D1F 2C37 3F44" $"3D38 373E 4C60 6E66 4837 1002 E600 113B" $"3B2C 3343 4345 3333 3B48 5A7A 6555 351B" $"05DD 006C 386D 6B00 0004 0800 1DA0 C8C2" $"BBB4 ADA6 A099 928B 847D 766E 2729 4B4E" $"4841 3A33 2C26 1F18 1108 000C F0EC E8E9" $"E9EA EAEA EAEA EAEA F4F6 FBFC FAF6 F1F0" $"F1F1 F2F3 F5F4 F3F2 F1EB 0D08 FAEA E0E1" $"E1E1 E1E1 E0E0 DFDF F0F7 FDFE F7EF E4E1" $"E1E1 E1E5 EDED EDEE EEED 0800 F1EC DEDF" $"E0E0 DFDF DFDF DEDE EFF7 FDFE F7EF E4E1" $"E1E1 E1E5 EDED EDEE EEE7 0000 DFEE DDDE" $"DEDE DEDE DEDE DDDD EEF6 FDFD F7EF E3E0" $"E0E1 E1E5 ECEC EDED EDDA 0000 CEF0 DCDD" $"DDDD DDDD DDDD DDDD EEF6 FDFE F7EF E3E0" $"E1E1 E1E6 EDED EDEE EECC 0000 BDF2 DCDC" $"DCDC DCDD DDDD DCDC EDF6 FDFE F7EF E2E0" $"E1E1 E1E6 EDED EDEE EEBE 0000 ACF3 DCDC" $"DCDC DCDC DCDC DCDC EDF6 FDFE F7EF E2E0" $"E1E1 E1E7 EDED EDEE EEB0 0000 9AF5 DCDB" $"DBDB DBDB DBDC DCDC EDF5 FDFD F7EF E2E0" $"E0E1 E1E7 ECED EDED EDA2 0000 89F6 DCDB" $"DBDB DBDC DCDC DCDC ECF5 FDFE F7EF E1E0" $"E1E1 E1E8 EDED EDEE EE94 0000 78F8 DDDB" $"DBDB DBDC DCDC DCDC ECF5 FDFE F7EF E1E0" $"E1E1 E1E8 EDED EDEE EE87 0000 66F9 DEDB" $"DBDB DBDC DCDC DCDC ECF5 FDFE F7EF E1E0" $"E1E2 E2E9 EDED EDEE EE79 0000 55FA DFDA" $"DBDB DCDC DCDE DFE0 EDF4 FDFD FAF6 F0F1" $"F2F4 F5F5 F2F0 EEED EE6B 0000 28F8 ECEB" $"EDEF F0F2 F4F5 F6F6 F6F3 F3F7 FAFC F9FA" $"FAFB FBFB FAF9 F8F0 D843 0000 0091 F8F7" $"F8F8 F9FA FAFB FBFC FAF8 FCFD FAFA FCFC" $"FBFB FAFA FBF2 9B36 0000 0000 25E5 FDFE" $"FEFD FDFC FBFB FAF9 FBF6 F8F2 F2F5 F6F6" $"F6F6 F6F7 F9F8 F7F6 D665 0000 2BF7 F6F7" $"F6F5 F5F5 F5F5 F5F5 F9FA FDFA F2EF EFED" $"EBE9 E8E9 EEEE EEEE EEAE 0000 19F9 F4F3" $"F1EF EDEB E9E7 E4E2 EEF3 FDFE F6F0 E8E2" $"E2E3 E3E8 EEEE EEEF EFA0 0000 08FA EAE0" $"E0DF DFDE DDDD DEDE ECF3 FDFE F6F0 E8E2" $"E2E3 E3E8 EEEE EEEF EF92 0000 00F1 E9DD" $"DDDD DDDE DEDE DEDE ECF3 FDFE F6F0 E8E2" $"E3E3 E3E9 EEEE EEEF EF83 0000 00E0 EBDD" $"DDDD DDDD DEDE DEDF ECF3 FDFD F6F0 E8E2" $"E3E3 E4E9 EEEE EEEF EF75 0000 00CF EDDD" $"DEDE DEDE DFDF DFDF EBF3 FDFE F6F1 E8E2" $"E3E4 E4EA EEEF EEEF F066 0000 00BE EFDE" $"DEDE DEDF DFDF DFE0 EBF3 FDFE F6F1 E8E3" $"E4E4 E4EA EEEF EFF0 F058 0000 00AC F1DE" $"DEDF DEDF DFE0 E0E0 EBF3 FDFE F6F1 EAE7" $"EAED EFEF EDEE EFF0 F049 0000 009B F3DF" $"DEDF DFDF DFE0 E2E4 ECF3 FBFD FAF7 F3F1" $"F1F1 F1F1 F1EE EFEF F03A 0000 0089 F5DF" $"E0E3 E6E9 ECEF EFF0 EFF1 F4FC FAF8 F3F1" $"F2F2 F2F2 F3F2 F0EF F02C 0000 005D FAEE" $"EFEF EFF0 F0F0 EFF0 F0EF F2F5 F4F8 F3F1" $"F2F2 F2F3 F3F3 F3F3 EC18 0000 0016 F9F0" $"EFF0 EFF0 F0F0 EFF0 F0F1 F0F3 77D6 F4F2" $"F2F2 F2F3 DEAB 7743 1000 0000 0000 C6F0" $"EFEF EFEF EFF0 F0F0 F0F0 F0F0 5B20 DAEA" $"BC88 541F 0000 0000 0000 0000 0000 7DF1" $"F0F0 EFF0 F0F0 F0F1 EBBF 8C5A 0C00 0C05" $"0000 0000 0000 0000 0000 0000 0000 34F2" $"F0F0 F0EF CB98 6633 0700 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 01B3" $"A471 3F0E 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0073 386D 6B00" $"0001 0823 CFD4 CDC6 C0BB B9A3 979E 9792" $"8B83 403E E5E0 E0E0 DFE7 FAFA E9E1 E1E9" $"EDEE 7735 E6DE DEDD DDE5 FAFA E9E0 E1E9" $"EDEE 692D E7DC DCDC DCE5 FAFA E9E0 E1E9" $"EDEE 5B24 E9DB DBDC DCE4 F9FA E8E0 E1EA" $"EDEE 4D1B EBDB DBDC DCE4 F9FA E8E0 E1EA" $"EDEE 400F EFE3 E6E8 EAEE F6FA F6F6 F8F7" $"F4E9 2B09 DBFA FBFB FBFB F8F7 F8F9 F8F9" $"DF81 1911 F7F4 F2F0 EDEF FAF8 EDE7 E6EB" $"EEEE 5302 EFDE DEDE DEE5 F8FA ECE2 E3EB" $"EEEF 4500 E2DD DDDE DFE5 F8FA ECE3 E4EC" $"EEEF 3600 D3DE DEDF DFE5 F8FA EDE6 E9ED" $"EFF0 2800 C3DF E2E5 E8EC F5FB F5F1 F2F2" $"F0F0 1900 99EF EFF0 F0F0 F0D5 EDF2 F2EE" $"C28C 0600 51F0 EFF0 F0EF CB6C 416A 3708" $"0000 0000 0DCE A472 3F0E 0000 0000 0000" $"0000 0074 386D 6B00 0040 0800 0000 0000" $"0000 0000 0006 3136 2F26 2118 140D 0A08" $"0706 0403 0201 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0003 52D7 FDFD FDFD FDFD FEFE FAF4" $"EEE9 E2DD D6D3 CDC7 BFB8 B2AB A59C 978F" $"8982 7B75 6D66 5F5A 524C 453E 3830 2921" $"1D15 1310 0E0B 0906 0402 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 32BA FCFD FCFD FDFD FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" $"FDFD F9F4 F0EB E7E2 DEDA D5CF C6C0 B472" $"0600 0000 0000 010F 2848 4D48 403A 322B" $"261F 1C18 1411 0E09 0502 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"1996 F6FD FCFC FBFC FDFD FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" $"FDFD FCFC FCFC FCFC FCFC FCFC FCFC FCFC" $"FCFC FCFC FCFC FBFB FAF9 F8F8 F7F7 F6F7" $"9529 4970 92B8 D8EF FCFD FDFD FDFD FDFD" $"FDFD FAF6 F3F0 EDEA E6E4 DFDA D1CC C3BE" $"B6AF AAA3 9C94 8F87 8279 726D 6660 5852" $"4A44 3C36 3020 0000 0000 0000 0000 0060" $"EAFC FCFB F5F0 EFF2 F3F4 F4F4 F5F5 F5F6" $"F6F6 F7F7 F7F8 F8F8 F8F8 F9F9 F9F9 F9FA" $"FAFA FAFA FAFB FBFB FBFB FBFB FBFB FBFB" $"FAF9 F9F8 F7F6 F6F5 F5F5 F6F7 F9FA FBFD" $"FCFB FEFE FDFE FDFD FDFC FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FCFC FCFC FCFC FCFC" $"FCFC FCFC FCFD FDFD FDFC FCFC FBFB FAFA" $"F9F8 F8F7 F7F2 A005 0000 0000 0000 2EF8" $"FBFA FAF9 EFE4 E0E6 E7E7 E8E8 E8E8 E8E9" $"E9E9 E9E9 E9E9 EAEA EAEA EAEA EAEA EAEA" $"EAEA EAEA EAEA EBEB EBEB EBEC ECEC EFF5" $"F5F4 F4F4 F3F3 F8FB FCFD FDFE FEFE FDFE" $"FEFB FAFB FAFB FBFA F8F8 FAF9 F9FA FAFA" $"FAFA FBFB FBFB FBFB FBFB FBFB FBFB FBFA" $"FAF9 F9F8 F7F6 F5F4 F4F3 F2F2 F2F1 F1F1" $"F0F0 F0F0 F0F0 F240 0000 0000 0000 57FC" $"FBFA F9F8 EEE0 DBE1 E3E3 E3E3 E3E3 E3E3" $"E3E3 E3E3 E3E3 E3E3 E3E3 E3E3 E3E3 E3E3" $"E3E2 E2E2 E2E2 E2E2 E2E2 E1E2 E2E1 E1EC" $"F3F2 F2F2 F2F7 FDFD FDFD FDFD FDFD FDFD" $"FDF4 F3F2 F2F2 F2F0 E8E6 ECE8 E9E9 E9E9" $"E9E9 EAEA EAEB EBEB ECEC EDED EDF1 F1F1" $"F0F0 F0EF EFEF EFEE EEEE EEEE EEEE EEEE" $"EDED EDED EDED EF4F 0000 0000 0000 46FC" $"FBFA F9F9 EFE1 DBE0 E2E2 E2E3 E3E3 E2E3" $"E3E2 E3E3 E2E3 E3E2 E3E2 E2E2 E2E2 E1E2" $"E1E1 E1E1 E0E1 E0E0 E0E0 DFE0 DFDF DFE8" $"F2F2 F3F3 F2F9 FEFD FEFE FDFE FEFE FDFE" $"FDF2 F0F0 F0EF EFEC E2E0 E7E2 E2E2 E2E2" $"E2E2 E2E2 E2E2 E3E3 E3E3 E3E2 E1E9 EDED" $"EDED EDED EDED EDEC EDEE EDEE EEEE EDEE" $"EEED EEEE EDEE F040 0000 0000 0000 36FC" $"FBFA F9F9 F0E1 DBDF E2E2 E2E2 E2E2 E2E2" $"E2E2 E2E2 E2E2 E2E2 E2E2 E1E2 E2E1 E1E1" $"E1E0 E1E1 E0E0 E0DF E0E0 DFDF DFDE DFE8" $"F2F2 F3F3 F2F9 FEFD FEFE FDFE FEFE FDFE" $"FDF2 F0F0 EFEF EFEC E1DF E6E2 E1E1 E1E1" $"E1E1 E1E2 E1E2 E2E1 E2E2 E1E0 DFE7 ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE F033 0000 0000 0000 27FB" $"FBFA F9F9 F1E2 DCDE E1E1 E1E1 E1E1 E1E1" $"E1E1 E1E1 E1E1 E1E1 E1E1 E1E1 E1E1 E0E0" $"E0E0 E0E0 DFDF DFDF DFDF DFDE DEDE DFE7" $"F2F2 F2F2 F2F9 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEF EEEC E1DF E5E1 E0E0 E0E0" $"E0E0 E1E1 E1E1 E1E1 E1E1 E1E0 DFE7 ECEC" $"ECEC ECEC ECEC ECEC ECED EDED EDED EDED" $"EDED EDED EDED EF26 0000 0000 0000 1AF6" $"FBFA FAF9 F2E2 DCDE E1E1 E1E1 E1E1 E1E1" $"E1E1 E1E1 E1E1 E1E1 E1E1 E0E1 E1E1 E0E0" $"E0E0 E0E0 DFE0 E0DF DFDF DEDF DFDE DFE7" $"F2F2 F3F3 F2F9 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEC E1DF E5E1 E1E1 E0E1" $"E1E0 E1E1 E1E2 E2E1 E2E2 E1E0 DFE8 ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE EB1B 0000 0000 0000 0CF1" $"FBFA FAF9 F3E3 DCDD E0E1 E0E1 E1E1 E0E1" $"E1E0 E1E1 E0E1 E1E0 E1E1 E0E1 E0E0 E0E0" $"E0DF E0E0 DFDF DFDE DFDF DEDF DFDE DEE6" $"F2F2 F3F3 F2F9 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEC E1DF E4E1 E1E1 E0E1" $"E1E0 E1E1 E1E2 E2E1 E2E2 E1E0 DFE8 ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE E810 0000 0000 0000 02EB" $"FBFA F9F9 F4E3 DCDD DFE0 E0E0 E0E0 E0E0" $"E0E0 E0E0 E0E0 E0E0 E0E0 E0E0 DFDF DFDF" $"DFDF DFDF DFDE DEDE DEDE DEDE DEDE DEE6" $"F2F2 F2F2 F2F9 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEF EEEC E1DF E4E0 E0E0 E0E0" $"E0E0 E0E0 E1E1 E1E1 E1E1 E1E0 E0E8 ECEC" $"ECEC ECEC ECEC ECEC ECED EDED EDED EDED" $"EDED EDED EDEE E506 0000 0000 0000 00DD" $"FCFA FAF9 F5E4 DDDC E0E0 DFE0 E0E0 DFE0" $"E0E0 E0E0 E0E0 E0DF E0E0 DFE0 E0E0 DFDF" $"DFDF DFDF DEDF DFDE DFDF DEDE DEDD DEE6" $"F2F2 F3F3 F2F8 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEC E1DF E3E1 E1E1 E0E1" $"E1E0 E1E1 E0E1 E2E1 E2E2 E1DF E0E9 ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE DD00 0000 0000 0000 00CA" $"FCFA FAF9 F6E5 DDDC DFDF DFDF E0E0 DFE0" $"E0DF E0E0 DFE0 E0DF E0E0 DFDF DFDF DFDF" $"DFDE DFDF DEDF DFDE DEDE DEDE DEDD DEE5" $"F1F2 F3F3 F2F8 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E1DF E3E1 E1E1 E0E1" $"E1E0 E1E1 E0E1 E2E1 E2E2 E1DF E0E9 ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE CF00 0000 0000 0000 00B9" $"FCFA FAF9 F7E6 DDDB DFDF DEDF DFDF DFDF" $"DFDF DFDF DFDF DFDF DFDF DFDF DFDF DEDF" $"DFDE DFDF DEDE DEDE DEDE DDDE DEDD DEE5" $"F1F2 F2F3 F2F8 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E1DF E3E1 E1E1 E0E1" $"E1E0 E1E1 E0E1 E2E1 E2E2 E1DF E0E9 ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE C200 0000 0000 0000 00A8" $"FCFB FAF9 F7E6 DEDB DEDE DEDE DEDE DEDE" $"DEDE DEDE DEDE DEDE DEDE DEDE DEDE DEDE" $"DEDE DEDE DEDE DDDD DDDD DDDD DDDD DDE5" $"F1F1 F2F2 F2F8 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEE EEEB E0DF E2E0 E0E0 E0E0" $"E0E0 E0E0 E0E0 E1E1 E1E1 E1DF E0EA ECEC" $"ECEC ECEC ECEC ECEC ECED EDED EDED EDED" $"EDED EDED EDEE B400 0000 0000 0000 0096" $"FCFB FAF9 F8E8 DEDB DEDE DEDE DEDF DEDF" $"DFDE DFDF DEDF DFDE DFDF DEDF DFDE DEDE" $"DEDE DEDE DDDE DEDD DEDE DDDE DEDD DDE5" $"F1F1 F2F2 F2F8 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DF E2E1 E1E1 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E0EA ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE A600 0000 0000 0000 0083" $"FCFB FAF9 F8E9 DFDB DDDE DDDE DEDE DEDE" $"DEDE DEDE DEDE DEDE DEDE DEDE DEDE DDDE" $"DEDD DEDE DDDE DEDD DEDE DDDE DEDD DDE4" $"F1F1 F2F2 F2F8 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DF E2E1 E1E1 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E0EA ECED" $"EDEC EDED ECED EDEC EDED EDEE EEEE EDEE" $"EEED EEEE EDEE 9700 0000 0000 0000 0074" $"FCFB FAF9 F8EA DFDB DDDD DDDD DDDD DDDD" $"DDDD DDDD DDDD DDDD DDDD DDDD DDDD DDDD" $"DDDD DDDD DDDD DDDD DDDD DDDD DDDD DDE4" $"F1F1 F1F2 F2F8 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEE EEEB E0DE E1E0 E0E0 E0E0" $"E0E0 E0E0 E0E0 E1E1 E1E1 E1DF E0EA ECEC" $"ECEC ECEC ECEC ECEC ECED EDED EDED EDED" $"EDED EDED EDEE 8A00 0000 0000 0000 0063" $"FCFB FAF9 F8EB DFDB DDDD DDDE DEDE DDDE" $"DEDD DEDE DDDE DEDD DEDE DDDE DEDE DDDE" $"DEDD DEDE DDDE DEDD DEDE DDDE DEDD DDE4" $"F1F1 F2F2 F2F8 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DE E1E0 E1E1 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E1EB ECED" $"EDEC EDED ECED EDEC EDEE EDEE EEEE EDEE" $"EEED EEEE EDEE 7C00 0000 0000 0000 0050" $"FCFB FAF9 F8ED E0DB DCDD DDDD DDDD DDDE" $"DEDD DEDE DDDE DEDD DEDE DDDE DEDE DDDE" $"DEDD DEDE DDDD DDDD DDDD DDDD DDDD DDE3" $"F1F1 F2F2 F2F7 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DE E1E0 E1E1 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E1EB ECED" $"EDEC EDED ECED EDEC EDEE EDEE EEEE EDEE" $"EEED EEEE EDEF 6D00 0000 0000 0000 003E" $"FCFB FAF9 F8EE E0DB DCDC DCDC DCDC DCDD" $"DDDD DDDD DDDD DDDD DDDD DDDD DDDD DDDD" $"DDDD DDDD DCDC DCDC DCDC DCDC DCDC DCE3" $"F0F1 F1F1 F1F7 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEE EEEB E0DE E0DF E0E0 E0E0" $"E0E0 E0E0 E0E0 E1E1 E1E1 E1DF E1EB ECEC" $"ECEC ECEC ECEC ECEC EDED EDED EDED EDED" $"EDED EDED EDEF 5F00 0000 0000 0000 002E" $"FCFB FAFA F9EF E1DB DCDD DCDD DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DCDD DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DCDD DDDD DCE3" $"F1F1 F2F2 F1F7 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DE E0E0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E1EB ECED" $"EDEC EDED ECED EDEC EDEE EDEE EEEE EDEE" $"EEED EEEE EDEF 5200 0000 0000 0000 001E" $"FAFB FAFA F9F0 E1DB DCDD DCDD DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DCDD DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DCDD DDDD DCE2" $"F0F1 F2F2 F1F7 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DE E0E0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E1EC ECED" $"EDEC EDED ECED EDEC EDEE EDEE EEEE EDEE" $"EEED EEEE EDF0 4300 0000 0000 0000 000E" $"F8FB FAF9 F9F1 E2DC DBDC DCDC DCDC DCDC" $"DCDC DCDC DCDC DCDC DCDC DCDC DCDC DCDC" $"DCDC DCDC DCDC DCDC DCDC DCDC DCDC DCE2" $"F0F1 F1F1 F1F7 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEE EEEB E0DE E0DF DFE0 E0E0" $"E0E0 E0E0 E0E0 E1E1 E1E1 E1DE E2EC ECEC" $"ECEC ECEC ECEC ECEC EDED EDED EDED EDED" $"EDED EDED EDF0 3500 0000 0000 0000 0002" $"F5FB FAFA F9F3 E2DC DBDC DBDC DCDC DCDC" $"DCDC DDDD DCDD DDDC DDDD DCDD DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DCDD DDDD DCE2" $"F0F1 F2F2 F1F7 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DE E0E0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DE E2EC ECED" $"EDEC EDED ECED EDEC EDEE EDEE EEEE EDEE" $"EEED EEEE EDEF 2700 0000 0000 0000 0000" $"E4FC FAFA F9F4 E3DC DBDC DBDC DCDC DBDC" $"DCDC DCDC DCDC DDDC DDDD DCDD DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DCDD DDDD DCE2" $"F0F1 F2F2 F1F6 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEB E0DE E0E0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E2EC ECED" $"EDEC EDED ECED EDEC EDEE EDEE EEEE EDEE" $"EEED EEEE EDEE 1B00 0000 0000 0000 0000" $"D2FC FAFA F9F5 E4DC DBDB DBDB DBDB DBDB" $"DBDB DBDB DBDB DCDC DCDC DCDC DCDC DCDC" $"DCDC DCDC DCDC DCDC DCDC DCDC DCDC DCE1" $"F0F1 F1F1 F1F6 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEE EEEA E0DE DFDF DFDF E0E0" $"E0E0 E0E0 E0E0 E1E1 E1E1 E1DF E3EC ECEC" $"ECEC ECEC ECEC ECEC EDED EDED EDED EDED" $"EDED EDED EDEE 0D00 0000 0000 0000 0000" $"C2FC FBFA F9F6 E4DD DBDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DCDB DCDC DBDC DCDC DCDC" $"DDDC DDDD DCDD DDDC DDDD DCDD DDDD DCE1" $"EFF1 F2F2 F1F6 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEA E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E3EC ECED" $"EDEC EDED ECED EDED EEEE EDEE EEEE EDEE" $"EEED EEEE EDEA 0200 0000 0000 0000 0000" $"B0FC FBFA F9F6 E5DD DBDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDC DDDD DCDD DDDC DDDD DCDD DDDD DCE1" $"EFF1 F2F2 F1F6 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEA E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E3EC ECED" $"EDEC EDED ECED EDED EEEE EDEE EEEE EDEE" $"EEED EEEE EDDF 0000 0000 0000 0000 0000" $"9EFC FBFA F9F7 E6DD DBDB DBDC DCDC DBDC" $"DCDB DCDC DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DCDD DDDC DDDD DCDD DDDD DCE1" $"EFF1 F2F2 F1F6 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEA E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E1E1 E2E2 E1DF E4EC ECED" $"EDEC EDED ECED EDED EEEE EDEE EEEE EDEE" $"EEED EEEE EDD2 0000 0000 0000 0000 0000" $"8CFC FBFA F9F8 E7DE DBDB DBDB DBDB DBDB" $"DBDB DBDB DBDB DBDB DBDB DBDB DBDB DBDB" $"DBDB DBDC DCDC DCDC DCDC DCDC DCDC DCE1" $"EFF1 F1F1 F1F6 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEF EEEA E0DE DFDF DFDF E0E0" $"E0E0 E0E0 E0E1 E1E1 E1E1 E1DF E4EC ECEC" $"ECEC ECEC ECEC ECED EDED EDED EDED EDED" $"EDED EDED EEC3 0000 0000 0000 0000 0000" $"7DFC FBFA F9F8 E8DE DBDB DADB DBDB DBDC" $"DCDB DCDC DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DCDC DDDC DDDD DCDD DDDD DCE1" $"EFF1 F2F2 F1F5 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEA E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E2E1 E2E2 E1DF E5EC ECED" $"EDEC EDED ECED EDED EEEE EDEE EEEE EDEE" $"EEED EEEE EEB5 0000 0000 0000 0000 0000" $"6AFC FBFA F9F8 E9DF DBDB DADB DBDB DBDB" $"DCDB DCDC DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DDDC DDDD DCDD DDDD DCE0" $"EFF1 F2F2 F1F5 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEA E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E2E1 E2E2 E1DF E5EC ECED" $"EDEC EDED ECED EDED EEEE EDEE EEEE EDEE" $"EEED EEEE EEA8 0000 0000 0000 0000 0000" $"57FC FBFA F9F8 EADF DBDA DADA DADA DADB" $"DBDB DBDB DBDB DBDB DBDB DBDB DBDB DBDB" $"DBDB DBDB DBDC DCDC DCDC DCDC DCDC DCE0" $"EEF1 F1F1 F1F5 FDFD FDFD FDFD FDFD FDFD" $"FDF1 EFEF EFEF EEEA E0DE DFDF DFE0 E0E0" $"E0E0 E0E0 E0E1 E1E1 E1E1 E1DF E5EC ECEC" $"ECEC ECEC ECEC EDED EDED EDED EDED EDED" $"EDED EDED EE99 0000 0000 0000 0000 0000" $"47FD FBFA F9F9 EBE0 DBDB DADB DBDB DADB" $"DBDB DCDC DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DCDC DDDD DCDD DDDD DCE0" $"EEF1 F2F2 F1F5 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFEA E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E2E1 E2E2 E1DF E6ED ECED" $"EDEC EDED ECED EDED EEEE EDEE EEEE EDEE" $"EEED EEEE EF8A 0000 0000 0000 0000 0000" $"35FD FBFA F9F9 EDE0 DBDB DADB DBDB DADB" $"DBDA DBDC DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DCDC DDDD DCDD DDDD DCE0" $"EEF1 F2F2 F1F5 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFE9 E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E0E1 E2E1 E2E2 E1DF E6ED ECED" $"EDEC EDED ECED EDED EEEE EDEE EEEE EDEE" $"EEED EEEE EF7D 0000 0000 0000 0000 0000" $"24FD FBFA F9F9 EEE0 DBDA DADA DADA DADA" $"DADA DADB DBDB DBDB DBDB DBDB DBDB DBDB" $"DBDB DBDB DBDB DCDC DCDC DCDC DCDC DCE0" $"EEF1 F1F1 F1F5 FDFD FDFD FDFD FDFD FDFD" $"FDF1 F0EF EFEF EEE9 E0DE DFDF DFE0 E0E0" $"E0E0 E0E0 E0E1 E1E1 E1E1 E0DF E6EC ECEC" $"ECEC ECEC ECED EDED EDED EDED EDED EDED" $"EDED EDEE EF6F 0000 0000 0000 0000 0000" $"12FD FCFA F9F9 EFE1 DCDB DADB DBDB DADB" $"DBDA DBDB DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DCDC DDDD DCDD DDDD DCE0" $"EEF1 F2F2 F1F5 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFE9 E0DE DFE0 E0E0 E0E1" $"E1E0 E1E1 E1E2 E2E1 E2E2 E0DF E7ED ECED" $"EDEC EDED ECED EEED EEEE EDEE EEEE EDEE" $"EEED EEEE EF61 0000 0000 0000 0000 0000" $"05F9 FCFB FAF9 F1E1 DCDB DADB DBDB DADB" $"DBDA DBDB DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DCDC DDDD DCDD DDDD DCE0" $"EDF1 F2F2 F1F4 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFE9 E0DE DFE0 E0E1 E0E1" $"E1E0 E1E1 E1E2 E2E1 E2E2 E0DF E7ED ECED" $"EDEC EDED ECED EEED EEEE EDEE EEEE EDEE" $"EEED EEEE F051 0000 0000 0000 0000 0000" $"03E9 FCFA FAF9 F2E2 DCDA DADA DADA DADA" $"DADA DADA DADB DBDB DBDB DBDB DBDB DBDB" $"DBDB DBDB DBDB DCDC DCDC DCDC DCDC DCDF" $"EDF1 F1F1 F1F4 FDFD FDFD FDFD FDFD FDFD" $"FDF1 F0EF EFEF EEE9 E0DE DFDF E0E0 E0E0" $"E0E0 E0E0 E1E1 E1E1 E1E1 E0DF E7EC ECEC" $"ECEC ECEC ECED EDED EDED EDED EDED EDED" $"EDED EEEE F043 0000 0000 0000 0000 0000" $"01D9 FCFB FAF9 F3E3 DCDB DADB DBDB DADB" $"DBDA DBDB DADB DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DDDC DDDD DCDD DDDD DCDF" $"EDF1 F2F2 F1F4 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFE9 E0DE DFE0 E0E1 E0E1" $"E1E0 E1E1 E1E2 E2E1 E2E2 E0E0 E8ED ECED" $"EDEC EDED ECED EEED EEEE EDEE EEEE EDEE" $"EEED EEEF F036 0000 0000 0000 0000 0000" $"00C9 FCFB FAF9 F4E3 DDDB DADB DBDB DADB" $"DBDA DBDB DADB DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DBDC DDDC DDDD DCDD DDDD DCDF" $"EDF1 F2F2 F1F4 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFEF EFE9 E0DE DFE0 E0E1 E0E1" $"E1E0 E1E1 E1E2 E2E1 E2E2 E0E0 E8ED ECED" $"EDEC EDED EDEE EEED EEEE EDEE EEEE EDEE" $"EEED EEEF F127 0000 0000 0000 0000 0000" $"00B8 FCFB FAF9 F5E4 DDDA DADA DADA DADA" $"DADA DADA DADB DBDB DBDB DBDB DBDB DBDB" $"DBDB DBDB DBDC DCDC DCDC DCDC DCDC DCDF" $"EDF1 F1F1 F1F4 FDFD FDFD FDFD FDFD FDFD" $"FDF1 F0EF EFEF EFE9 E0DE DFE0 E0E0 E0E0" $"E0E0 E0E1 E1E1 E1E1 E1E1 E0E0 E9EC ECEC" $"ECEC ECEC EDED EDED EDED EDED EDED EDED" $"EDEE EEEE F219 0000 0000 0000 0000 0000" $"00A7 FCFB FAF9 F6E5 DDDB DADB DBDB DADB" $"DBDA DBDB DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DCDC DDDC DDDD DCDD DDDD DCDF" $"ECF1 F2F2 F1F4 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFF0 EFE9 E0DE DFE0 E1E1 E0E1" $"E1E0 E1E1 E1E2 E2E1 E2E2 E0E0 E9ED ECED" $"EDEC EDED EDEE EEED EEEE EDEE EEEE EDEE" $"EEEE EFEF F20A 0000 0000 0000 0000 0000" $"0095 FCFB FAF9 F6E5 DEDB DADB DBDB DADB" $"DBDA DBDB DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DCDD DDDC DDDD DCDD DDDD DCDF" $"ECF1 F2F2 F1F4 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFF0 EFE9 E0DE DFE0 E1E1 E0E1" $"E1E0 E1E2 E1E2 E2E1 E2E2 E0E0 E9ED ECED" $"EDEC EDED EDEE EEED EEEE EDEE EEEE EDEE" $"EEEE EFEF EB03 0000 0000 0000 0000 0000" $"0085 FCFB FAF9 F7E6 DEDB DADB DBDB DADB" $"DBDA DBDB DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DCDD DDDC DDDD DCDD DDDD DCDF" $"ECF1 F2F2 F1F4 FEFD FEFE FDFE FEFE FDFE" $"FDF1 F0F0 EFF0 EFE9 E0DE DFE0 E0E1 E0E1" $"E1E1 E1E2 E2E2 E3E3 E4E4 E3E4 EBED ECED" $"EDEC EDED EDEE EEED EEEE EDEE EEEE EDEE" $"EEEE EFEF DE02 0000 0000 0000 0000 0000" $"0072 FCFB FAF9 F8E7 DEDB DADA DADA DADA" $"DADA DADB DBDB DBDB DBDB DBDB DBDB DBDB" $"DBDB DBDC DCDC DCDC DCDC DCDC DCDC DCDF" $"EBF1 F1F1 F1F4 FDFD FDFD FDFD FDFD FDFD" $"FDF1 F0F0 F0F0 EFE9 E1DF E1E2 E3E3 E4E5" $"E5E6 E7E8 E9EA ECED EEEF F0F1 F1EF EEED" $"EDEC ECED EDED EDED EDED EDED EDED EDED" $"EEEE EEEE D101 0000 0000 0000 0000 0000" $"0060 FDFB FAFA F8E8 DFDB DADB DBDB DADB" $"DBDA DBDB DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDB DCDC DCDD DDDC DDDD DCDD DDDD DCDF" $"EBF1 F2F2 F1F3 FDFD FEFE FDFE FEFE FDFE" $"FDF3 F2F2 F2F3 F3EF EAEB EDEE F0F1 F2F3" $"F4F5 F6F6 F7F7 F7F7 F7F7 F7F8 F7F6 F4F2" $"F0EF EEED EDED EDED EEEE EDEE EEEE EDEE" $"EEEE EFEF C400 0000 0000 0000 0000 0000" $"004F FDFB FAFA F9EA DFDB DADB DBDB DADB" $"DBDA DBDC DBDC DCDB DCDC DBDC DCDC DBDC" $"DCDC DCDC DCDC DDDD DDDD DEDE DFDF DFE2" $"EEF1 F1F2 F1F2 F9FD FEFE FDFE FEFE FDFE" $"FDF9 F9FA FAFA FAF9 F7F7 F7F8 F8F8 F7F8" $"F8F7 F8F8 F7F8 F8F7 F8F8 F7F8 F8F8 F7F8" $"F7F5 F3F1 EFEE EEED EDEE EDEE EEEE EDEE" $"EFEE EFEF B700 0000 0000 0000 0000 0000" $"003E FDFB FAFA F9EB E0DB DADA DADA DADA" $"DADB DBDB DBDB DCDC DCDC DCDD DDDD DEDE" $"DFDF E0E0 E1E2 E2E3 E4E5 E7E8 E9EB ECEF" $"F2F1 F1F1 F1F2 F3F5 FAFD FDFD FDFD FDFD" $"FDFB FBFB FAFA FAF9 F7F7 F7F7 F7F7 F7F7" $"F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 F7F8" $"F8F8 F8F8 F7F5 F2F0 EFEE EEEE EDED EDEE" $"EEEE EEEF A800 0000 0000 0000 0000 0000" $"002C FDFC FAFA F9EC E0DC DBDB DCDC DCDD" $"DDDD DEDF DFE0 E0E1 E2E3 E4E5 E6E7 E9EA" $"EBED EEEF F1F2 F3F4 F4F5 F5F6 F6F6 F6F6" $"F5F3 F2F1 F1F1 F2F2 F3F5 FAFD FEFE FDFE" $"FDFC FCFB FBFB FBF9 F8F8 F7F8 F8F8 F7F8" $"F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 F8F8 F8F8" $"F9F8 F9F9 F8F9 F8F8 F6F4 F2F0 EFEE EEEE" $"EEEE EEEF 9B00 0000 0000 0000 0000 0000" $"000C E7FC FBFA F9F0 E5E1 E1E2 E3E4 E5E7" $"E8E9 EBEC EEEF F0F1 F2F3 F4F5 F5F6 F6F6" $"F6F6 F6F6 F6F6 F7F6 F7F7 F6F7 F7F7 F6F7" $"F7F6 F5F3 F2F1 F1F1 F2F3 F2F4 F9FD FDFE" $"FDFC FCFC FBFC FBFA F8F8 F8F8 F8F8 F8F8" $"F8F8 F9F9 F8F9 F9F9 F9F9 FAFA FAF9 F8F9" $"F9F8 F9F9 F8F9 F9F8 F9F9 F8F7 F5F3 F1F0" $"EFEE EEEF 8400 0000 0000 0000 0000 0000" $"0000 68FD FCFC FCF7 F2F1 F2F3 F4F5 F5F5" $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6" $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6" $"F6F6 F6F6 F5F3 F2F1 F1F2 F2F2 F2F3 F8FD" $"FDFC FBFB FBFB FBFA F8F8 F8F8 F9F9 F9FA" $"FAFB FBFC FCFC FDFD FDFD FDFD FDFD FCFA" $"F9F8 F8F8 F8F8 F8F8 F9F9 F9F9 F9F9 F8F7" $"F5F4 F3E6 3100 0000 0000 0000 0000 0000" $"0000 05C6 FDFD FDFB F8F6 F6F7 F7F7 F6F7" $"F7F6 F7F7 F6F7 F7F6 F7F7 F6F7 F7F7 F6F7" $"F7F6 F7F7 F6F7 F7F6 F7F7 F6F7 F7F7 F6F7" $"F7F6 F7F7 F6F6 F5F3 F2F2 F1F2 F2F3 F3F3" $"F6EA FCFC FCFC FDFC FCFC FDFD FDFD FDFE" $"FEFD FEFE FDFE FEFD FEFE FDFE FEFE FDFE" $"FDFC FAFA F9FA FAFA FAFA FAF9 F5E0 CBB1" $"9A84 681F 0000 0000 0000 0000 0000 0000" $"0000 0037 F8FE FDFB F8F7 F6F7 F7F7 F6F7" $"F7F6 F7F7 F6F7 F7F6 F7F7 F6F7 F7F7 F6F7" $"F7F6 F7F7 F6F7 F7F6 F7F7 F7F7 F7F7 F8F7" $"F7F7 F7F7 F7F8 F8F7 F7F7 F8F9 FAFB FCFD" $"FDFA FBFD FDFE FEFD FEFE FDFE FEFE FDFE" $"FEFD FEFE FDFE FEFD FEFE FDFE FEFE FDFE" $"FEFD FDFD FCE9 9771 5A43 2C15 0300 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 97FD FDFB F8F7 F6F6 F6F6 F6F6" $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F7 F7F7" $"F7F7 F8F8 F9FA FAFB FBFC FCFD FDFD FDFD" $"F9F7 F7F7 F7F7 F7FC FDFD FDFD FDFD FDFD" $"FDF8 F8F8 F9FC FDFD FDFD FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFC FBFB FAFB FBFB" $"FBFB FAFA FBFB ECA8 520F 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 15E7 FDFC F8F7 F6F7 F7F7 F6F7" $"F7F6 F7F7 F7F7 F8F8 F9F9 FAFB FBFC FCFD" $"FDFD FEFE FDFE FEFD FEFE FDFE FEFE FDFE" $"FEFC F8F8 F7F8 F8FD FEFE FDFE FEFE FDFE" $"FCF8 F8F8 F7F8 F9FB FDFE FDFD FDFD FCFC" $"FBFA FAF9 F9F8 F8F8 F8F8 F7F7 F7F9 FAFA" $"FAFA FAFA FAFA FAFA FBEC A853 1000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0063 FDFC F9F8 F8F8 F9F9 FAFB" $"FBFC FCFD FDFD FEFD FEFE FDFE FEFE FDFE" $"FEFD FEFE FDFE FEFD FEFE FDFE FEFE FDFE" $"FEFD FDFB F8F8 F9FD FEFE FDFE FEFE FDFD" $"F8F7 F7F7 F7F7 F7F7 F7F8 F8F7 F7F7 F7F7" $"F7F7 F7F7 F7F7 F7F7 F7F7 F7F7 F7F9 F9FA" $"FAF9 FAFA F9FA FAF9 FAFA FAFB ECA8 540E" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0567 A1B8 FDFD FDFD FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" $"FDFD FDFD FDFD FDFD FDFD FDFD FDFD FDFD" $"FDFD FDFD FDFA E3FB FBFA F8F7 F5F4 F4F4" $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6" $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F8 F9F9" $"F9F9 F9F9 F9F9 F9F9 F9F9 F9F9 FAFA FAEE" $"A856 0D00 0000 0000 0000 0000 0000 0000" $"0000 90F9 F8F8 F9FD FEFE FDFE FEFE FDFE" $"FEFD FEFE FDFE FEFD FEFE FDFE FEFE FDFE" $"FEFD FEFE FDFE FEFD FEFD FDFD FCFC FBFB" $"FCFC FCFC FCFC B6F3 F4F4 F3F2 F2F1 F0F1" $"F2F4 F5F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F6" $"F6F6 F6F6 F6F6 F6F6 F6F6 F6F6 F6F8 F9F9" $"F9F9 F9FA F9FA FAF9 FAFA F9FA FAFA F9FA" $"FAFA F1AA 5402 0000 0000 0000 0000 0000" $"0004 DDF8 F7F7 F7FB FEFE FDFE FEFE FDFE" $"FEFD FEFE FDFE FEFD FEFE FDFE FEFE FDFD" $"FDFC FCFB FAFA F9F8 F8F7 F7F6 F6F6 F6F7" $"FAFB FCFC FBFC FCFD F8F4 F3F3 F3F2 F1F0" $"F0F0 F1F4 F5F6 F6F5 F6F6 F5F6 F6F6 F5F6" $"F6F5 F6F6 F5F6 F6F5 F6F6 F5F5 F5F8 F8F9" $"F9F8 F9F9 F8F9 F9F9 F9F8 F8F7 F7F6 F5F4" $"F3F2 F2F2 F494 0000 0000 0000 0000 0000" $"0002 D6F8 F6F6 F7F7 FDFE FDFE FEFE FDFE" $"FEFD FEFE FDFD FCFC FBFA F9F9 F8F7 F7F6" $"F6F5 F6F6 F5F6 F6F5 F6F6 F5F6 F6F6 F5F6" $"FAFB FBFB FBFB FCFD FEFC F6F3 F3F2 F1F1" $"F0EF EFF0 F1F3 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F6F6 F5F5 F5F8 F8F8" $"F8F7 F6F6 F5F4 F3F3 F2F1 F1F0 F0F0 EFEF" $"EFEF EFEF EFEC 0800 0000 0000 0000 0000" $"0000 C9F9 F6F6 F6F6 F7FB FDFC FCFB FAFA" $"F9F8 F7F7 F6F6 F6F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F6" $"F9FA FAFA FAFA FBFD FDFD FDFA F4F2 F1F1" $"F1F0 EFEF EFEF F1F3 F4F4 F4F4 F4F4 F4F4" $"F4F4 F4F4 F4F4 F4F3 F2F1 F0ED EDF2 F2F1" $"F1F0 F0EF EFEF EEEE EEEE EEEE EEEE EEEE" $"EEEE EEEE EEED 0500 0000 0000 0000 0000" $"0000 B5FB F7F6 F5F5 F6F6 F6F6 F6F6 F5F6" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5 F5F5" $"F9FA FBFB FAFB FBFD FEFE FDFE FDF7 F2F2" $"F1F0 F0F0 EFEE EEEF F1F3 F4F4 F4F3 F2F1" $"F0EF EEEC EBEA E9E8 E7E7 E6E3 E4ED EEEE" $"EDED EDEE EDEE EEED EEEE EEEE EEEF EEEF" $"EFEE EFEF EEE4 0000 0000 0000 0000 0000" $"0000 A4FC F8F6 F5F5 F5F5 F5F5 F5F5 F5F5" $"F5F4 F5F5 F4F5 F5F4 F5F5 F4F5 F5F5 F4F5" $"F5F4 F5F5 F4F5 F5F4 F5F5 F4F5 F5F5 F4F5" $"F9FA FBFB FAFB FBFD FEFE FDFE FEFE FBF4" $"F1F0 F1F1 F0EF EEEE EEEE EAEA E9E8 E7E6" $"E5E5 E5E4 E4E4 E4E4 E3E3 E3E0 E2EC EDED" $"EDED EEEE EDEE EEED EEEE EEEF EFEF EEEF" $"EFEE EFEF EED6 0000 0000 0000 0000 0000" $"0000 94FC F9F6 F5F4 F4F4 F4F4 F4F4 F4F4" $"F4F4 F4F4 F4F4 F4F4 F4F4 F4F4 F4F4 F4F4" $"F4F4 F4F4 F4F4 F4F4 F4F4 F4F4 F4F4 F3F4" $"F8FA FAF9 F9F8 F8FD FDFD FDFD FDFD FDFD" $"F4F1 F0F0 F0EF EFEE EDE6 E5E7 E4E4 E4E4" $"E3E3 E3E2 E2E2 E2E2 E2E3 E3E0 E3EC EDED" $"EDED EDED EDED EDED EDEE EEEE EEEE EEEE" $"EEEE EEEE EEC7 0000 0000 0000 0000 0000" $"0000 81FC FAF7 F5F4 F4F4 F4F4 F4F4 F4F4" $"F4F4 F4F4 F3F4 F4F3 F4F4 F3F4 F4F4 F3F4" $"F4F3 F4F4 F3F3 F3F2 F2F1 F0EE EDEB E9E9" $"F1F5 F5F4 F4F4 F4FD FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF EDE3 E1E5 E2E2 E1E2" $"E2E2 E2E3 E2E3 E3E2 E3E4 E3E0 E3ED EDEE" $"EEED EEEE EDEE EEED EEEF EEEF EFEF EEEF" $"EFEE EFEF EFB9 0000 0000 0000 0000 0000" $"0000 70FC FBF9 F5F4 F4F4 F3F4 F4F4 F3F4" $"F4F3 F4F4 F3F4 F4F3 F4F4 F3F3 F3F3 F2F1" $"F0EF EDEC EAE8 E7E6 E4E4 E3E2 E1E1 E0E2" $"EDF3 F3F3 F3F3 F3FD FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF EDE3 DFE1 E2E2 E1E2" $"E2E2 E3E3 E2E3 E3E2 E3E4 E3E0 E3ED EDEE" $"EEED EEEE EDEE EEED EEEF EEEF EFEF EEEF" $"EFEE EFEF EFAA 0000 0000 0000 0000 0000" $"0000 5DFC FBFA F6F4 F3F3 F3F3 F3F3 F3F3" $"F3F3 F3F3 F2F1 F0EF EEEC EBE9 E7E6 E4E4" $"E3E2 E1E1 E0E0 E0DF DFDF DEDE DEDE DDDF" $"ECF2 F2F2 F2F2 F3FD FDFD FDFD FDFD FDFD" $"F8F1 F0F0 F0EF EFEF EDE3 DFE0 E1E1 E1E2" $"E2E2 E2E2 E2E2 E2E3 E3E3 E3E0 E4ED EDED" $"EDED EDED EDED EDEE EEEE EEEE EEEE EEEE" $"EEEE EEEE EF9C 0000 0000 0000 0000 0000" $"0000 4CFC FBFA F8F5 F3F3 F2F1 F1EF EEED" $"EBE9 E8E6 E5E4 E3E2 E1E0 E0E0 E0E1 E2E2" $"E1E0 E0DF DEDE DDDD DDDD DDDE DEDE DEE0" $"ECF2 F3F3 F2F3 F3FD FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF EDE3 E0E1 E2E2 E1E2" $"E3E2 E3E3 E2E3 E3E3 E4E4 E3E1 E4ED EDEE" $"EEED EEEE EDEE EEEE EFEF EEEF EFEF EEEF" $"EFEE EFEF EF8D 0000 0000 0000 0000 0000" $"0000 3AFC FBFA F9F6 F3EC E6E4 E3E2 E1E0" $"E0DF E0E1 E3E5 E6E6 E5E5 E4E2 E1DF DDDD" $"DDDD DDDD DDDE DEDD DEDE DEDE DFDF DEE0" $"ECF2 F3F3 F2F3 F3FD FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF EDE3 E0E1 E2E2 E2E2" $"E3E2 E3E3 E2E3 E3E3 E4E4 E3E1 E4ED EDEE" $"EEED EEEE EDEE EEEE EFEF EEEF EFEF EEEF" $"EFEE EFEF F07F 0000 0000 0000 0000 0000" $"0000 28FC FBFA F9F7 EEE1 DFE2 E4E6 E6E6" $"E6E6 E5E3 E0DE DCDC DCDC DCDC DCDD DDDD" $"DDDD DDDD DDDD DDDD DDDD DEDE DEDE DEE0" $"EBF2 F2F2 F2F2 F3FD FDFD FDFD FDFD FDFD" $"F8F1 F0F0 F0F0 EFEF EDE3 E0E1 E1E1 E2E2" $"E2E2 E2E2 E2E2 E3E3 E3E3 E3E1 E5ED EDED" $"EDED EDED EDED EEEE EEEE EEEE EEEE EEEE" $"EEEE EEEF F070 0000 0000 0000 0000 0000" $"0000 1AFB FBFA F9F8 EADF DDDF DEDC DCDC" $"DCDC DCDD DCDD DDDC DDDD DCDD DDDD DDDE" $"DEDD DEDE DDDE DEDD DEDE DEDF DFDF DEE0" $"EBF2 F3F3 F2F3 F4FD FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF EDE3 E0E1 E2E2 E2E3" $"E3E2 E3E3 E2E3 E4E3 E4E4 E3E1 E5ED EDEE" $"EEED EEEE EDEE EFEE EFEF EEEF EFEF EEEF" $"EFEE EFEF F061 0000 0000 0000 0000 0000" $"0000 11F1 FBFA F9F8 EBE1 DDDC DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DCDD DEDE DDDE" $"DEDD DEDE DDDE DEDD DEDF DEDF DFDF DEE0" $"EBF2 F3F3 F2F3 F4FC FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF EDE3 E0E1 E2E2 E2E3" $"E3E2 E3E3 E2E3 E4E3 E4E4 E3E1 E6ED EDEE" $"EEED EEEE EDEE EFEE EFEF EEEF EFEF EEEF" $"EFEE EFF0 F052 0000 0000 0000 0000 0000" $"0000 09E7 FBFA F9F8 ECE1 DDDC DCDC DCDC" $"DCDC DCDC DCDC DCDC DCDD DDDD DDDD DDDD" $"DDDD DDDD DDDD DDDE DEDE DEDE DEDE DEE0" $"EBF2 F2F2 F2F3 F3FC FDFD FDFD FDFD FDFD" $"F8F1 F1F0 F0F0 EFEF EDE3 E0E1 E2E2 E2E2" $"E2E2 E2E2 E3E3 E3E3 E3E3 E3E1 E6ED EDED" $"EDED EDED EDEE EEEE EEEE EEEE EEEE EEEE" $"EEEF EFEF F143 0000 0000 0000 0000 0000" $"0000 02DE FBFA FAF8 EDE2 DDDD DDDD DCDD" $"DDDC DDDD DCDD DDDC DDDD DDDE DEDE DDDE" $"DEDD DEDE DDDE DEDE DFDF DEDF DFDF DEE0" $"EBF2 F3F3 F2F3 F4FC FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF ECE3 E0E1 E2E3 E2E3" $"E3E2 E3E3 E3E4 E4E3 E4E4 E3E1 E6ED EDEE" $"EEED EEEE EEEF EFEE EFEF EEEF EFEF EEEF" $"EFEF F0F0 F134 0000 0000 0000 0000 0000" $"0000 00CD FCFB FAF9 EEE2 DDDD DDDD DCDD" $"DDDC DDDD DCDD DDDD DDDE DDDE DEDE DDDE" $"DEDD DEDE DDDE DFDE DFDF DEDF DFDF DEE0" $"EAF2 F3F3 F2F3 F4FC FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F0 F0EF ECE3 E0E1 E3E3 E2E3" $"E3E2 E3E3 E3E4 E4E3 E4E4 E3E1 E7EE EDEE" $"EEED EEEE EEEF EFEE EFEF EEEF EFEF EEEF" $"EFEF F0F0 F226 0000 0000 0000 0000 0000" $"0000 00BD FCFB FAF9 F0E3 DDDD DDDD DCDD" $"DDDC DDDD DCDD DDDD DEDE DDDE DEDE DDDE" $"DEDD DEDE DEDF DFDE DFDF DEDF DFDF DEE0" $"EAF2 F3F3 F2F3 F4FC FEFE FDFE FEFE FDFE" $"F8F1 F1F1 F0F1 F0EF ECE3 E0E1 E3E3 E2E3" $"E3E2 E3E3 E3E4 E4E3 E4E4 E3E1 E7EE EDEE" $"EEED EEEE EEEF EFEE EFEF EEEF EFEF EEEF" $"EFEF F0F0 F316 0000 0000 0000 0000 0000" $"0000 00AB FCFB FAF9 F1E3 DDDC DCDC DCDC" $"DCDC DCDD DDDD DDDD DDDD DDDD DDDD DDDD" $"DDDD DDDE DEDE DEDE DEDE DEDE DEDE DEE0" $"EAF2 F2F2 F2F3 F3FC FDFD FDFD FDFD FDFD" $"F8F1 F1F0 F0F0 F0EF ECE3 E0E1 E2E2 E2E2" $"E2E2 E3E3 E3E3 E3E3 E3E4 E3E1 E8ED EDED" $"EDED EEEE EEEE EEEE EEEE EEEE EEEE EEEF" $"EFEF EFEF F109 0000 0000 0000 0000 0000" $"0000 009A FCFB FAF9 F2E4 DEDD DDDD DCDD" $"DDDC DDDD DDDE DEDD DEDE DDDE DEDE DDDE" $"DEDD DEDF DEDF DFDE DFDF DEDF DFDF DFE0" $"EAF2 F3F3 F3F4 F4FC FEFE FDFE FEFE FDFE" $"F8F1 F2F1 F0F1 F0EF ECE3 E0E2 E3E3 E2E3" $"E3E3 E4E4 E3E4 E4E3 E4E4 E3E1 E8EE EDEE" $"EEED EEEF EEEF EFEE EFEF EEEF EFEF EFEF" $"F0EF F0F0 E703 0000 0000 0000 0000 0000" $"0000 0088 FCFB FAF9 F3E4 DEDD DDDD DCDD" $"DDDD DEDE DDDE DEDD DEDE DDDE DEDE DDDE" $"DEDE DFDF DEDF DFDE DFDF DEDF DFDF DFE0" $"EAF2 F3F3 F3F4 F4FC FEFE FDFE FEFE FDFE" $"F8F1 F2F1 F0F1 F0EF ECE3 E0E2 E3E3 E2E3" $"E3E3 E4E4 E3E4 E4E3 E4E5 E3E2 E9EE EDEE" $"EEEE EEEF EEEF EFEE EFEF EEEF EFEF EFF0" $"F0EF F0F0 DA02 0000 0000 0000 0000 0000" $"0000 0076 FCFB FAF9 F4E5 DEDD DCDC DDDD" $"DDDD DDDD DDDD DDDD DDDD DDDD DDDD DDDE" $"DEDE DEDE DEDE DEDE DEDE DEDF DFDF DFE0" $"E9F2 F2F2 F3F3 F3FB FDFD FDFD FDFD FDFD" $"F8F1 F1F1 F0F0 F0EF ECE3 E0E2 E2E2 E2E2" $"E3E3 E3E3 E3E3 E3E3 E4E4 E3E2 E9ED EDED" $"EDEE EEEE EEEE EEEE EEEE EEEE EEEF EFEF" $"EFEF EFEF CD01 0000 0000 0000 0000 0000" $"0000 0065 FCFB FAF9 F5E5 DFDD DDDD DDDE" $"DEDD DEDE DDDE DEDD DEDE DDDE DEDE DEDE" $"DFDE DFDF DEDF DFDE DFDF DFDF E0E0 DFE0" $"E9F2 F3F3 F3F4 F4FC FEFE FDFE FEFE FDFE" $"F8F1 F2F1 F0F1 F1F0 ECE3 E0E2 E3E3 E2E3" $"E4E3 E4E4 E3E4 E4E4 E5E5 E3E2 E9EE EDEE" $"EEEE EFEF EEEF EFEE EFEF EEEF EFEF EFF0" $"F0EF F0F0 C000 0000 0000 0000 0000 0000" $"0000 0053 FCFB FAF9 F6E6 DFDD DEDE DDDE" $"DEDD DEDE DDDE DEDD DEDE DDDE DEDE DEDF" $"DFDE DFDF DEDF DFDE DFDF DFE0 E0E0 DFE0" $"E9F2 F3F3 F3F4 F4FB FEFE FDFE FEFE FDFE" $"F8F1 F2F1 F0F1 F1F0 ECE3 E0E2 E3E3 E3E3" $"E4E3 E4E4 E3E4 E4E4 E5E5 E3E2 EAEE EDEE" $"EEEE EFEF EEEF EFEE EFEF EEEF EFF0 EFF0" $"F0EF F0F0 B100 0000 0000 0000 0000 0000" $"0000 0042 FDFB FAF9 F6E7 E0DD DDDD DDDD" $"DDDD DDDD DDDD DDDD DDDD DDDE DEDE DEDE" $"DEDE DEDE DEDE DEDE DFDF DFDF DFDF DFE0" $"E8F2 F2F2 F3F3 F3FB FDFD FDFD FDFD FDFD" $"F8F1 F1F1 F0F0 F0F0 ECE3 E0E2 E2E2 E3E3" $"E3E3 E3E3 E3E4 E4E4 E4E4 E3E2 EAED EDEE" $"EEEE EEEE EEEE EEEE EEEE EEEF EFEF EFEF" $"EFEF EFF0 A400 0000 0000 0000 0000 0000" $"0000 002F FDFB FAF9 F7E8 E0DE DEDE DDDE" $"DEDD DEDE DDDE DEDD DEDE DEDF DFDF DEDF" $"DFDE DFDF DEDF DFDF DFE0 DFE0 E0E0 DFE0" $"E8F2 F3F3 F3F4 F4FB FEFE FDFE FEFE FDFE" $"F8F1 F2F2 F1F1 F1F0 ECE3 E1E2 E3E3 E3E4" $"E4E3 E4E4 E3E4 E5E4 E5E5 E3E3 EAEE EDEE" $"EFEE EFEF EEEF EFEE EFEF EEEF F0F0 EFF0" $"F0EF F0F0 9400 0000 0000 0000 0000 0000" $"0000 0021 FAFB FBF9 F8E9 E1DE DEDE DDDE" $"DEDD DEDE DDDE DEDD DEDE DEDF DFDF DEDF" $"DFDE DFDF DEDF DFDF E0E0 DFE0 E0E0 DFE0" $"E8F2 F3F3 F3F4 F4FB FEFE FDFE FEFE FDFE" $"F8F2 F2F2 F1F1 F1F0 ECE3 E1E2 E3E3 E3E4" $"E4E3 E4E4 E4E4 E5E4 E5E5 E3E3 EBEE EDEE" $"EFEE EFEF EEEF EFEE EFEF EFEF F0F0 EFF0" $"F0EF F0F0 8500 0000 0000 0000 0000 0000" $"0000 0015 F3FC FAF9 F8EA E1DE DDDD DDDD" $"DDDD DDDD DDDD DEDE DEDE DEDE DEDE DEDE" $"DEDE DEDE DEDF DFDF DFDF DFDF DFDF DFE0" $"E8F2 F2F3 F3F3 F3FB FDFD FDFD FDFD FDFD" $"F8F2 F1F1 F1F0 F0F0 ECE3 E1E2 E3E3 E3E3" $"E3E3 E3E3 E4E4 E4E4 E4E4 E3E3 EBED EEEE" $"EEEE EEEE EEEE EEEE EEEE EFEF EFEF EFEF" $"EFEF EFF0 7600 0000 0000 0000 0000 0000" $"0000 000A ECFC FBFA F9EB E2DE DEDE DDDE" $"DEDD DEDE DEDE DEDE DFDF DEDF DFDF DEDF" $"DFDE DFDF DFE0 E0DF E0E0 DFE0 E0E0 DFE0" $"E8F2 F3F3 F3F4 F4FB FEFE FDFE FEFE FDFE" $"F8F2 F2F2 F1F1 F1F0 ECE3 E1E3 E4E4 E3E4" $"E4E3 E4E4 E4E5 E5E4 E4E4 E2E3 EBEE EEEF" $"EFEE EFEF EEEF EFEE EFEF EFF0 F0F0 EFF0" $"F0EF F0F0 6800 0000 0000 0000 0000 0000" $"0000 0001 E5FC FBFA F9EC E2DE DEDE DDDE" $"DEDD DEDE DEDF DFDE DFDF DEDF DFDF DEDF" $"DFDE DFDF DFE0 E0DF E0E0 DFE0 E0E0 E0E0" $"E8F2 F3F3 F3F4 F4FB FEFE FDFE FEFE FDFE" $"F8F2 F2F2 F1F1 F1F0 ECE3 E1E3 E4E4 E3E4" $"E4E3 E3E4 E4E3 E3E3 E3E4 E3E4 EBED EEEF" $"EFEE EFEF EEEF EFEE EFEF EFF0 F0F0 EFF0" $"F0EF F0F0 5800 0000 0000 0000 0000 0000" $"0000 0000 D6FC FBFA F9ED E2DE DDDD DDDD" $"DEDE DEDE DEDE DEDE DEDE DEDE DEDE DEDE" $"DEDF DFDF DFDF DFDF DFDF DFDF E0E0 E0E0" $"E7F2 F2F3 F3F3 F3FB FDFD FDFD FDFD FDFD" $"F8F2 F1F1 F1F1 F0F0 ECE3 E1E3 E3E3 E3E2" $"E2E3 E3E3 E4E4 E5E7 E9EB ECED ECEC ECEE" $"EEEE EEEE EEEE EEEE EFEF EFEF EFEF EFEF" $"EFEF EFF1 4900 0000 0000 0000 0000 0000" $"0000 0000 C3FC FBFA F9EE E3DE DEDE DEDE" $"DEDE DFDF DEDF DFDE DFDF DEDF DFDF DEDF" $"DFDF E0E0 DFE0 E0DF E0E0 DFE0 E0E1 E0E0" $"E7F2 F3F3 F3F4 F4FB FEFE FDFE FEFE FDFE" $"F8F2 F2F2 F1F1 F0F0 EBE2 E0E1 E2E2 E3E4" $"E5E6 E8EA ECEE EFF1 F1F1 F1F1 F0ED ECEC" $"EEEE EFEF EEEF EFEF EFF0 EFF0 F0F0 EFF0" $"F0EF F0F2 3B00 0000 0000 0000 0000 0000" $"0000 0000 B2FC FBFA F9EF E3DF DEDE DEDF" $"DFDE DFDF DEDF DFDE DFDF DEDF DFDF DFDF" $"E0DF E0E0 DFE0 E0DF E0E0 E0E0 E1E1 E0E0" $"E7F2 F3F3 F3F4 F4FA FEFE FDFE FEFE FDFE" $"F8F2 F1F1 F1F0 F0F0 EBE3 E2E5 E7E9 ECED" $"EFF0 F0F1 F1F1 F2F1 F2F2 F1F2 F2F1 EEEC" $"ECED EEEF EEEF EFEF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F2 2D00 0000 0000 0000 0000 0000" $"0000 0000 A1FC FBFA F9F1 E4DF DEDF DEDF" $"DFDE DFDF DEDF DFDE DFDF DEDF DFDF DFE0" $"E0DF E0E0 DFE0 E0DF E0E0 E0E1 E1E1 E0E0" $"E7F2 F3F3 F3F4 F4FA FEFE FDFE FEFE FDFE" $"F8F2 F2F2 F2F2 F3F3 F1ED EDF0 F0F1 F0F1" $"F1F0 F1F1 F1F2 F2F1 F2F2 F1F2 F2F2 F1F0" $"EDEC ECEE EEEF EFEF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F3 1D00 0000 0000 0000 0000 0000" $"0000 0000 8EFC FBFA F9F2 E4DF DEDE DEDE" $"DEDE DEDE DEDE DEDE DEDE DEDF DFDF DFDF" $"DFDF DFDF DFDF DFDF E0E0 E0E0 E0E0 E0DF" $"E6F2 F3F3 F3F3 F3FA FDFD FDFD FDFD FDFD" $"F9F5 F5F6 F6F7 F7F7 F5F0 EFF0 F0F0 F0F0" $"F1F1 F1F1 F1F1 F1F1 F1F1 F1F1 F1F1 F1F1" $"F1EE ECEC EDEE EFEF EFEF EFEF EFEF EFEF" $"EFEF F0F1 1000 0000 0000 0000 0000 0000" $"0000 0000 7DFD FBFA FAF3 E5DF DFDF DEDF" $"DFDE DFDF DEDF DFDE DFDF DFE0 E0E0 DFE0" $"E0DF E0E0 DFE0 DFDF E0DF DFDF DFDF E0E0" $"E8F1 F3F4 F3F4 F4F8 FEFE FDFE FEFE FDFE" $"FBF8 F8F8 F7F8 F8F7 F5F1 F0F1 F1F1 F1F1" $"F1F1 F2F2 F1F2 F2F1 F2F2 F1F2 F2F2 F1F2" $"F2F1 F0ED ECED EEEF F0F0 EFF0 F0F0 EFF0" $"F0F0 F1E8 0B00 0000 0000 0000 0000 0000" $"0000 0000 6CFD FCFA FAF4 E6E0 DFDF DEDF" $"DFDE DFDF DEDF DFDF DFE0 DFE0 E0E0 DFDF" $"DFDF DFDE DEDE DEDF DFE0 E1E2 E3E5 E7E9" $"EDEE F2F4 F3F4 F4F4 FAFE FDFE FEFE FDFE" $"FBF8 F9F8 F7F8 F8F7 F5F1 F0F1 F1F1 F1F2" $"F2F1 F2F2 F1F2 F2F1 F2F2 F1F2 F2F2 F1F2" $"F2F2 F3F1 EFED EDEE EFF0 EFF0 F0F0 EFF0" $"F0F0 F1DD 0700 0000 0000 0000 0000 0000" $"0000 0000 59FD FCFA FAF5 E6E0 DEDE DEDE" $"DEDE DEDE DEDF DFDF DFDF DFDF DFDE DEDE" $"DEDE DFDF E0E1 E3E4 E7E9 EBED EEEF EFEF" $"EEED EFF2 F3F3 F3F3 F4FA FDFD FDFD FDFD" $"FBF8 F8F8 F7F7 F7F7 F5F1 F0F1 F1F1 F1F1" $"F1F1 F1F1 F1F1 F1F1 F1F1 F1F1 F1F1 F1F2" $"F2F2 F2F2 F2F0 EDEC EDEF EFEF EFEF EFEF" $"F0F0 F0D2 0300 0000 0000 0000 0000 0000" $"0000 0000 47FD FCFB FAF6 E7E0 DFDF DEDF" $"DFDE DFDF DFDF DEDE DEDE DEDE DEDF E0E1" $"E2E4 E6E9 EBED EEEF F0F0 EFF0 F0F0 EFF0" $"EFEE EEEF F3F4 F4F3 F4F4 FBFE FEFE FDFE" $"FBF8 F9F8 F7F8 F8F7 F5F1 F0F1 F2F2 F1F2" $"F2F1 F2F2 F1F2 F2F1 F2F2 F1F2 F2F2 F2F3" $"F3F2 F3F3 F2F3 F1EF EDED EEEF F0F0 EFF0" $"F1F0 F1C6 0000 0000 0000 0000 0000 0000" $"0000 0000 36FD FCFB FAF7 E8E1 DFDE DEDE" $"DEDE DDDD DDDE DEDF E0E1 E2E4 E6E9 EBEC" $"EEEF EFF0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF EEEE F0F3 F4F3 F4F4 F4FB FEFE FDFE" $"FBF8 F9F9 F8F8 F8F7 F5F1 F0F1 F2F2 F1F2" $"F2F1 F2F2 F1F2 F2F1 F2F2 F1F2 F2F3 F2F3" $"F3F2 F3F3 F2F3 F3F2 F0EE EDED EFF0 F0F1" $"F1F0 F1B9 0000 0000 0000 0000 0000 0000" $"0000 0000 27FB FCFB FAF7 E7E0 DDDD DDDD" $"DEDF E0E1 E2E4 E6E8 EAEC EDEE EEEF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" $"EFEF EFEE EEF1 F3F3 F3F3 F3F5 FCFD FDFD" $"FBF8 F8F8 F8F7 F7F7 F5F1 F0F1 F1F1 F1F1" $"F1F1 F1F1 F1F1 F1F1 F1F1 F2F2 F2F2 F2F2" $"F2F2 F2F2 F2F2 F2F2 F2F1 EFED EDEE F0F0" $"F0F0 F1AB 0000 0000 0000 0000 0000 0000" $"0000 0000 18F7 FCFB FAF8 E8E1 DFE0 E2E4" $"E6E8 EAEC EDEE EFEE EFEF EEEF EFEF EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0EF EEEE F1F3 F4F4 F4F5 F5FC FDFE" $"FBF8 F9F9 F8F8 F8F7 F5F1 F0F1 F2F2 F1F2" $"F2F1 F2F2 F1F2 F2F1 F2F2 F2F3 F3F3 F2F3" $"F3F2 F3F3 F2F3 F3F2 F3F3 F2F0 EEED EEEF" $"F0F0 F19C 0000 0000 0000 0000 0000 0000" $"0000 0000 03E5 FCFB FBF9 EFEA EAEC EDEE" $"EEEE EFEF EEEF EFEE EFEF EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFEE EFF2 F4F4 F4F5 F5F6 FCFE" $"FBF8 F9F9 F8F8 F8F7 F5F1 F0F1 F2F2 F1F2" $"F2F1 F2F2 F1F2 F2F1 F2F3 F2F3 F3F3 F2F3" $"F3F2 F3F3 F2F3 F3F2 F3F3 F3F3 F2EF EEEE" $"EFF0 F18D 0000 0000 0000 0000 0000 0000" $"0000 0000 009C FDFC FCFB F5F0 EFEE EEEE" $"EEEE EEEE EEEE EFEF EFEF EFEF EFEF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" $"EFEF EFEF F0EF EEEF F2F3 F4F4 F4F4 F6FD" $"FBF8 F8F8 F8F8 F7F7 F5F1 F0F1 F1F1 F1F1" $"F1F1 F1F1 F1F1 F2F2 F2F2 F2F2 F2F2 F2F2" $"F2F2 F2F2 F2F2 F2F2 F3F3 F3F3 F3F3 F0EE" $"EDEE F07E 0000 0000 0000 0000 0000 0000" $"0000 0000 0055 FDFC FDFC F5F1 EFEF EEEF" $"EFEE EFEF EFEF F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 F0F0 EEEE EFF3 F4F5 F5F5 F4F7" $"FBF9 F9F9 F8F8 F8F7 F5F1 F1F2 F2F2 F1F2" $"F2F1 F2F2 F1F2 F2F2 F3F3 F2F3 F3F3 F2F3" $"F3F2 F3F3 F2F3 F3F3 F4F4 F3F4 F4F4 F3F2" $"EFEE EF62 0000 0000 0000 0000 0000 0000" $"0000 0000 000F F9FD FDFC F6F1 EFEF EEEF" $"EFEF EFF0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0F0 F0F1 F0F1 F0EE EEF0 F4F5 F5F5 F4F6" $"B9EB F9F9 F8F8 F8F7 F5F1 F1F2 F2F2 F1F2" $"F2F1 F2F2 F2F2 F3F2 F3F3 F2F3 F3F3 F2F3" $"F3F2 F3F3 F2F3 F3F3 F4F4 F3F4 F4F4 F4F4" $"F4F0 B812 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 BEFD FCFC F6F1 EFEF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFF0" $"F0F0 F0F0 F0F0 F0F0 EEEE F1F4 F4F4 F4F5" $"8545 EFF8 F8F8 F8F7 F5F1 F1F1 F1F1 F1F1" $"F1F1 F1F2 F2F2 F2F2 F2F2 F2F2 F2F2 F2F2" $"F2F2 F2F2 F2F3 F3F3 F3F4 F4F4 F5E6 BF8B" $"5624 0200 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 76FD FDFC F7F1 EFEF EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 F0F1" $"F1F0 F1F1 F0F1 F1F0 F0EE EFF1 F4F5 F4F6" $"8500 54F4 F8F9 F8F7 F5F1 F1F2 F2F2 F1F2" $"F2F1 F2F3 F2F3 F3F2 F3F3 F2F3 F3F3 F2F3" $"F3F2 F3F3 F3F4 F4F5 F0CF 9C66 320D 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 2EFD FDFC F8F2 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 F0F1" $"F1F0 F1F1 F0F1 F1F0 F1EF EEEF F2F4 F4F6" $"8500 0060 F8F9 F8F7 F5F1 F1F2 F2F2 F1F2" $"F2F2 F3F3 F2F3 F3F2 F3F3 F2F3 F3F3 F2F3" $"F3F3 F4F6 DFAC 7942 1302 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 03DC FDFC F8F2 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 F0F0 F1F1 F0F1" $"F1F0 F1F1 F0F1 F1F0 F1F0 EFEF EFF2 F4F6" $"8500 0000 6DF8 F8F7 F5F1 F1F2 F2F2 F1F2" $"F2F2 F3F3 F2F3 F3F2 F3F3 F3F3 F3F4 F3EB" $"BD89 551F 0200 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0094 FDFC F8F2 F0EF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" $"EFEF EFEF EFEF EFEF EFF0 F0F0 F0F0 F0F0" $"F0F0 F0F0 F0F0 F0F0 F0F0 F0EF EEF0 F3F5" $"8500 0000 007C F8F7 F5F1 F1F1 F1F1 F1F2" $"F2F2 F2F2 F2F2 F3F3 F3F4 EDCD 9B65 3008" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 004D FDFC F9F2 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0F0 F0F1 F0F1 F1F1 F0F1" $"F1F0 F1F1 F0F1 F1F0 F1F1 F0F0 EFEF F0F5" $"8500 0000 0002 8CF8 F5F1 F1F2 F2F2 F2F3" $"F3F3 F3F3 F4F2 DAAB 7741 1500 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 000F EFFD FAF3 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 EFF0 F0F0 F1F1 F0F1 F1F1 F0F1" $"F1F0 F1F1 F0F1 F1F0 F1F1 F0F1 F0EF EFF2" $"8400 0000 0000 039C F5F1 F1F2 F2F2 F3F4" $"F5E4 BC87 5222 0500 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 B7FD FAF3 F0EF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFEF" $"EFEF EFEF F0F0 F0F0 F0F0 F0F0 F0F0 F0F0" $"F0F0 F0F0 F0F0 F0F0 F0F0 F0F0 F0F0 EEF1" $"6100 0000 0000 0004 A7F3 F2F4 F0CC 9963" $"300B 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 6EFD FBF3 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0EF F0F0 F0F1 F1F0 F1F1 F0F1 F1F1 F0F1" $"F1F0 F1F1 F0F1 F1F0 F1F1 F1F1 F2F3 F2B3" $"0D00 0000 0000 0000 0259 6E41 1002 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 25FA FBF4 F0F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 EFF0" $"F0F0 F0F1 F0F1 F1F0 F1F1 F0F1 F1F1 F0F1" $"F1F0 F1F1 F0F1 F1F1 F2F2 EAC3 8F5C 2800" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 02D2 FBF4 F0EF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFEF EFEF EFF0" $"F0F0 F0F0 F0F0 F0F0 F0F0 F0F0 F0F0 F0F0" $"F1F1 F1F2 F3EB CE9C 6834 0C00 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 008E FCF5 F1F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 F0F0" $"F1F0 F1F1 F0F1 F1F0 F1F1 F0F1 F1F1 F2F3" $"EFD7 A874 4015 0100 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0043 FCF5 F1F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 EFF0 F0F0 F0F1" $"F1F0 F1F1 F0F1 F1F1 F1F1 F2F4 DFB4 804D" $"1D05 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 000A EBF6 F1EF EFEF" $"EFEF EFEF EFEF EFEF EFEF EFF0 F0F0 F0F0" $"F0F0 F0F1 F1F2 F3EA C18C 5926 0700 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 AEF7 F2F0 EFF0" $"F0EF F0F0 EFF0 F0EF F0F0 F0F1 F1F1 F1F1" $"F2F3 EFCD 9966 3108 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 64F8 F2F0 EFF0" $"F0EF F0F0 EFF0 F0F0 F0F1 F1F2 F3EE D7A6" $"723E 1000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 1DF6 F3F0 EFEF" $"EFEF EFF0 F0F0 F1F2 F1DE B17E 4A1B 0200" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 00CB F4F0 F0F0" $"F0F1 F2F3 E4BE 8957 2507 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0049 EEF3 F3ED" $"C996 6330 0C00 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 215A 3A10" $"0100 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 0000 0000 0000" $"0000 0000 0000 0000 0000 00" }; stimfit-0.16.7/dist/macosx/stimfit.icns0000664000175000017500000030541514750344764013567 icns TOC His32zs8mkil32l8mkit32*t8mk@ic08RAic09-is32z ,101, 00/0/ 00 /00$"/ 0/ /0/%/,/ 0/ /0.$35,/H0/ /0- /6*.0/0/ /3'11-"1/0/ 1%&1/2%210 )(1./1'(', .02/ 1 &11/0 2341 ,1/1,  +* + GNLMMLMNG QPOPO PQOOQ/"PON OOOOQ"2SNXOOOPM C CRNNOOOPHP;OONOOOV<RS&'SNOOQ?2RPO;TRPB5QNNS6CBIIFSN OR(9RRO RPPQ GQORH  Bfb fB½ ®&€ &$pMÀ %$M:ẁX%$ŽHJ%$Ư?ƏF%$֑=YZ%$˘"x.%)'σ*&&π ]/0+&ʂ &DŽɰ&$&s8mk]||||||||]33Z[Y[YZYZYZYZYZYZYZ\\IIgg  il32(54 5(2/ 21/ 11/0/ 11/-0/ 11/0)./ 11/1&"5)&0/ 11/1$#5:++0/ 11/0"$-:;*./ 11/ $/0=4(0/ 11/ .$0.5;(*0/ 11/ 0-$1/.90!-0/ 11/ 1(&1//17"0/ 11/ 3+0//.4.#1/11/01% 1/.5+0/111/ ,1/1/2/12+53./4(21013!80./0,(')113/5./3 31/2./.5/%"#$(21/.16 311/. /12/ 2&212&   ?TR T? RN RRN RRNRRON RRNP*!JPN RRNQB OON RRNR4-RN RRNR+B#ARN RRNR#JEOON RRNPKS10RN RRN ONPONARN RRN PH RNRAMPN RRN R>+RNNR2 #RN RRN W+9QNNOP!3RNRRNPQ= KONQJ FQNRRPO4RNS8SNRRH>RNRATQPRV("RRNR=BCB@DRRJ3PONS! URORNOP3# !"0SRNORT RRRN RRON OR >R=   >BAB>ё љ:‘ ;@‘ @?‚ĉ @?dMƈ @?€ǠAÇ @?€|Ij͇ @?€fQ'Ɇ @?€Q"1FÅ @?€>,w%rͅ@?,8I&ʄ@?ıJɡ'6Ń@?ɗ dwR‚@?eK y͂@?ǒĀƶ"ǁ@?D{̂φEρ@?̰.0˃3р@?^L̅˓,@?˶|ćK ,@?ˆ{OJKMq@?‹́ @@‘ @:Ñ ;ˑ˖:@?@:l8mk%nzyyyyyyyyyyyyyyyyyyzn&,, [[ ,ss, +@KLLLLLLLLLLLLLLLLLLK@+  it32*%)-13431.)%)-6<<:<<6-**.860.-.068.)*+51--./.--15,*$)01./.10*%*+0../..0+*+,../..,++,./-,,,-./.-,--./.-,--./.-,--./.-,--./.-,--./.-,--./.-,--./.-,--./.-,--./-++,./.-,--./+!%,/.-,--./0,*/.-,--./ 0)/.-,--./0*+/.-,--./1 !-/.-,--./0#$%%$!!./.-,--./0-"&'))(&"&0/.-,--./0*!$'*++,+'#*0/.-,--./1&"&',9.-.,(# -/.-,--./1!$&'+U<,/0-)#%/.-,--./0 $&',AV4.11/)!*0/.-,--./0!$'%.1AP.142.' ".0/.-,--./0.!%&$.2,MB.453.''/.-,--./0-"%&#.1-1U61663-$ +/.-,--./0*#&%#00/,=P05862,"#./.-,--./1'#%%"1/ ,KD17971(!(/.-,--./1$$%$"1/ .1T74::5/&!,0/.-,--./1!$%$$2/ ,?O38;94,#$./.-,--./ 1 $%#%3./ -NB4;;82)!(/.-,--./ 0 #%!'2./ -4T77;;6/$!,/.-,--./ #$ (2/ ,BM4:;93+!$./.-,--./ 0- ##+2/ -P@4;:60'(/.-,--./ 0+ ""-1/ -6S66:93," ,0/.-,--./ 1( !!.0/ ,EK27950'#./.-,--./ 1$!!00/ ..Q=2773,$'/.-,--./1 ! 2/ -6S44640( +0/.-,--./ 1 !3./ ,EK0441,$ -/.-,--./ 0#3./ ..S=/32/(!$/.-,--./ 0.&3/ -6U1/00+$(0/.-,--./ 0+*1/ ,CL+./,'",0/.-,--./ 1&.1/ -P?)-,*$ ./.-,--./ 2 10/ -3V1(,+'"$/.-,--./14/ ,=R((*'$(0/.-,--./6./ ,KE$''$!,0/.-,--./ 0*&5./ ..T6!%$!./.-,--./ 1# -2/ -5V*!#"#/.-,--./1 50/ ,@P! !(0/.-,--./ 0- 9./ +LB-0/.-,--./ 2 '8./ ..U1/.-,--./ 0- 62/ -5V$&0/.-,--./ 0/ @./ ,AM-0/.-,--./ .--  /;-/ +L< 1/.-,--./ +   E0/ ./T( (0/.-,--./)  5A-/ -8O 00/.-,--./ ( P/ ,G: %1/.-,--./.%  S8-/ ..P  /.-,--./.  UD,/-:F $1/.-,--./- )]G+/ ,J(  /0/.-,--./,-Rc@,/ .3G "1/.-,--./+8fcM2,/,D) /0/.-,--./+ EZ;1,./.2F   1/.-,--.//0*QT.-./ -C*  -0/.-,--.//1YK,./.1F 00//0/.-,--.//08 _C+./ -B* -/.-, --.//-JL &_<+/.1I/.-,--./ ,MG-`8,/-A3 00/.-,--./.,P@1^5,/.O1//.-,--./.-OXX2-/-8P  /0/.-,--././I2-/,DO .0/.-,--./.-./,JX  /0/.-,--./,EcM,   /0/.-,--./,5Pbd]WRQMORVXP1./.-,--./-,1:CILNQOMLJKD/.-,--./.--,-/.-,--./.-,--./.-,--./.-,--./.-,--./.-,--./.-,--./.-,,-./.-,,,-/-,,+,./.,+*+-./.-+*$+,../..,*$**-../..-**++-.-++**+,-,+**$*+,,-,,+*$ *-* QN MU? CPNMIH0.IIMN PJ LON U-  KONMIH0.IIMN R1 SN PS  ,PONMIH0.IIMN PK 6SN QK   =QNMIH0.IIMNO + LPNMU=  LPNMIH0.IIMNONLKI1 &TN V+ -RNMIH0.IIMNONG4+ FQNPR   CQNMIH0.IIMNOOC)VN MSD !QONMIH0.IIMNONAQPNMV,  ;=?@DCENMIH0.IIMNMNPSUVWVUSNMIH0.IIMNMNMIH0.IIMNMIH0.IIMNMIH0.IIMNMIH0.IIMNMIH0.IIMNMIH0.IIMNMIH0.IIMNMIH0-HJMNMJH/-GJLNLJG-'GHLNLHG'DFJMNMJFD 9FILMNMLIE: EFILMNMLIFF,GFIKLLMLLKIFF-,FIIJIJIIFEE-9DGHHIHHGD: '--.--' 8`jjkjj`8 FͽH  mǾnmſѼįn DF47\]jlkqlrlqlqlqlqlplpløpl»¶pl ´~OC]µpl ĶM \´pl ` EôplƩEijplo !Ròpl@ #&$!n±plĸ%#&)*&#°plɟ!%(*),-,($3Űpl̃"&(,D,..-*$Xïplg#''-S(00.*"®plO %'&3Ļ6-22/*3Ůpl:"&'"B֎*143/)Zíplý,"&'P`)463.% ǭplů "&&aɿ $&:Á ʲ96<;7/EĨpl ÿ. $%G‚ Ӏ.9<93*p§pl ŵ# #$Ȳ Q1;:70#(Ƨpl Ǧ ##j̈́ ̭66:93-Dæpl ʓ ""~̅ z-8960(l¥pl }"!ˆ K.983-!#ƥpl f!dž ͩ33740*8Ĥpl N (ć z*453-&\ãpl 84È N*33/*¢pl ļ&Eˆ ̱2.20,&)Ƣpl ƨ\͊ Ն&.0.)"Aġpl ˍv͋ Y$..*&bàpl o ˋ 9&,*'"Ÿpl K ƌ ў&'*(%&şpl + .Í s('%!?Ğpl ƩH̏ L&%"`Ýpl } mϏ ˽/$"œpl Iː Ә""Ɯpl Ŵ "đ o >ěpl w  Hϓ F hšpl Ż* ϓ ˼)ǚpl f  Ĕ Ֆ3ęplv [ӿ ej˜pl­}e> Ǘ 6 ǘpl¦9 bտ ϧI—pl*  *ę h  ɗpl¿ Ϳ *  8Öplýz վ я  ʖpl¹f  Cտ ? 2ÕplµRJϾ ̢ ˕plðDiÿ G /Ĕpl«; ¿ ˦ |˔plĩ1¿ J &œplA$ٿ ʩ a€Á‡€plǔ6Ӿ L~p lٛ CϾɲ>]lpvromc`qpl ܌ Pʿe"pl|[ǿ($plҪſͭplÿ֟plײ3plؓJ"   !plлplׂ؁πplplplplplplplplpkqilX[25@Agѽj g͵i @Ͳ@2XkljY3t8mk@     &kl&    "#      67  wz   "#   &--%  *46* #/;GPX_dhkmnoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooonmkhd_XPG>4)   '08?FLPTWXYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZYXWTPLF?80(   #*05;>ACDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCA>;50*#  #'+.1345666666666666666666666666666666666666666666666666666666666666666666666666665431.+'#  !"$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$"!     ic08RAPNG  IHDR\rfiCCPICC ProfilexTkPe:g >hndStCkWZ6!Hm\$~ًo:w> كo{ a"L"4M'S9'^qZ/USO^C+hMJ&G@Ӳylto߫c՚  5"Yi\t։15LsX g8ocግ#f45@ B:K@8i ΁'&.)@ry[:Vͦ#wQ?HBd(B acĪL"JitTy8;(Gx_^[%׎ŷQ麲uan7m QH^eOQu6Su 2%vX ^*l O—ޭˀq,>S%LdB1CZ$M9P 'w\/].r#E|!3>_oa۾d1Zӑz'=~V+cjJtO%mN |-bWO+ o ^ IH.;S]i_s9*p.7U^s.3u |^,<;c=ma>Vt.[՟Ϫ x# ¡_2 IDATx}gdUf+׮{NLL42fF FE H rpkweq-,,# BHˑCH q=7U~ߍw3#_gVUf2Yue/^}ݸqåj3c0 lL 7fF)` Q`SVt1F Lc[э60loE7 :`0?(` Q`SVt1F Lc[э60loE7 :`0?(T+wMgna[v ٭:#$/L"ʂ((Z/uxM1f1~~5`X dU qݽ 4nLh1QS j_ z#)>Rm4 65kVʹr~SK(@d+`U3LCpM#uH0L/+NխB678iGGF2;0z{*;4e] xb?r5 ͈ޝ*Z9_('N_?OsS_* y:N֪ ާ~y?|shX+ɼ!H^̆atFTF<-[xKe3Z葠4i$&V? rP]s)B3*]TS?u'wW?PRgLK0M/:tGo},Ph`p xİݻ_ٲ?*|)Jg\65ANҰ.O1 ~FWa\Rp*zk-̵/Osӗ/ .1''#0cX- ^]LXs,># Yiꓗ\?<6KKvG( eaVW{~;{ϻ(۲==&ۂJ!q5\ ԌQ`) ЃFRT*)qZpҴPo `%i*Kßga\͊g |q7;tGg vB2d ~.o_̠.-?D ep *KK:ufM_#HYH9tWBy&!jQڸjyŧ3'H% LTmVyT7,x42L/e;>ݵM;|/enx#CndpTD\RH_P$a?FU%WS2eР!]uW.c0M1鋏^/^VSg4b&B$ DO[d;n_ʍ컟Z~V? 0"Ԑ+TZ|*,IJ|>(|k#\F`?j|`]J^tWYimvaTnaC+y/rPC0+vfcJӦ >$33m6ǫuםnQALAlAGX.0 8fC0`T .PYP %`8wۮ~#W r>nbCCi@MO:5юBd:S"5y1x~Oq2hT P@e]ff&Ƞs`Tq37]M1IzbW+iԎR~eaa&Vӯ-?mdx+Pi?W8釩׌Q(%Vuuuu#\2Lv#[GQp)_B&o2& (3I7/-,=MpT5~z@|I]g}0ȦFvu(bE?kL|A& /^lnhS•atn =+D~?Luwۥ޳FF}8ށ*VVc m ń3yڂM{nm\D-%"M/gk+z K)L2fBMebUfMu h0ctkծ3 }d6[y`T/]|I{dMSQ/Όdn:xaYA1F[n.b4cLCݚiO/(6GM((Ja?*$KNŒ  Lh:/( @w 7S+JO1 k Dc@I:3̍nm4=Pz3LSXLKh3a}REŇF4a҄nbFEVy-Q-@ 3Dkx 1‹hRj+6yoIO8̔Hhد$HM(gu`&ЯZr/t0NcHyjKbEmbI#p`xAw7 @ 3 ]Q:a5i 'N3ڐ$HŭGmhB= Mե͂i|862b]v?>g bD0iE$LP.Q 6OvW@WkBk>kQ`cS@aM$AC&n.~A}DZϚm0 x !N'Ĕkl*z\3n]!mBw"K4 MQuN}21  X[b' 㽸]sf ioȈk'%b):;m۽T3xncQ(LQfeO 9 sY mXX#1 za^*a5Q`#R[luL^@xKq(nZ'B@Q|~nnQ`q t5odLj3 Wۃg=rt jWKW]W Jnۑp9C4oE2,4%StK&"Ҭ+M(KOS짟na8A9Pf!^Ф`_Lcq$YZ,Q 1I*Y,p>^@ x+@4dP S2~\쐫``'0pL`L$>FJ@_;{W]8)@p  ){f A48P8,LϹFY0dCu)\S>|8=^g#+L!` RB)EpU0ċ]fW01 ,&,LD’sǁPA iI*`6綸̰zKHAtDv %c-~T?@SI-1D?>W pQZi>º0xfd7vp3 z<!)H70I45W@t}'f KW0}">";P\r00;'E0 >T`lAŲ"U@V\߻ JisyS@{t~:b^'ؗ(]Q46Mab϶mw[Ò%Q 1P@&?t(\ Cs u:~ cI~t u>?i=NI x{8wͯbhh Qzrt>qDM VCǙ{Qk0/@',: 6 = @F߀[Ɋɘted@>0"̡+݈h1+[i% BV0Њ*݆U/?Ȕ3+) ]/^sGU*O;aW3* `8[:&}U@u}?g V9vkk8 lTɧ$N:s&y U n,Aa$ AtdTtf/ L7$|@Dc Ur o}¾ [zo.TfuG|BC2R&Y ,_Tpe(%+1h"U1:)zuة EL¸ q_Eo #` 7Bn9ft*tt1a ^7&BW]yqn[~ h!{ݓՏ2dv͇~m' mA0BGdd@:;@F  F$Jb] NRfu G(" =zOOqol7A&p]k >c8CpFTrJl`K8.~J_x64&$ 2Fx'Y *shnDPq3 s 壱+). GGsv`VfrT]_vg0MLČQ0X=.:0O޷9;v,@xv(#)Hؼ^6pd_?a#)s0X!&)1PǦ"OPPEKKakcUt 1~DZ`n`~ DTT fκҕϻfZW 7X1$>8&shk 歍xuw?Xxi l=.W憣5 "?:* ! Q|37F\F*cͰWL_sPjpے!g8?n9}n`-%(*ta2"2]vb`v,Ntluc |y,eKN-nhG]ca4+ }k/]0o 9&Qiµ8xa !~u@"8 ER@[>*I@x\0JRc)d+^'Rt8I `0>C.+0UzG}Mc|>0: DH wT )L>~`SNC{ WH=$*S Ha(Ra[+6m /u }v49یN=@&0効Qw𶷸 97@#/Réiy TeA tAc |<\ONz/d:}/sRXP_3Uk+]/Z7>R ) D v R|E07I@\ίoZ@Ez037i5ӿ[bÊ2\r) Af2Ӻ}@ߎ$ R xZda ۈҕ ~3^x Hwo|I  殀-A즡AǴʼh5["{JXOh铀4V6?b H܋A[vH6a\ H BP:#)t9#ffS@8 b79@WT<=2lWy"5l~Vt6,0# FRvYH я`E1fU$VӰ^y[Z%Db.@\BF~22ف< QUե@ŠHW1Akl!kc~Z~@cܽ)Iȏ Gx@Io2:i@A )2(2hh+sK̮$d3U{UӀnr=vJc$NJҰeeTfB8/HGB@?v (`U1wn̮09\ık+s0 p9̙Ҹr$:U2vC AzL2+\G#__zlAy0 }GQC὘F d]9$NsK[ވcӪ3Qz$bȗR^/|ڕCvX7c-?c  IDAT0W)[HЗ >~偠ZC&p2Ӆ*0NJ<Wst@1.+aXpN=jb/(` ee Q%EQw]MwT&G?){n~V D'l 0SH$A9fwi"CXD澷 VI^CDe(e4+PۂӅY"$jaCz_HgE)` rc@e2Zr.zsaOsVB]YwÁGIHP>/ÂǼ@47`(ϝ <`d64}5G@8vV*(pHg6Ӆ2#ܭ; 2\}rO*:1}|O@4PFts[[/F JfN@w8K<x 0œb 'I4 /U(?NCyd$0g}(` Kc]W>qڞz`Y,ӭ<2C9ZcTM ,&>#8bN o((y<l,ND$(^_4>@Շ?hF CbR QH{訏_ee7i+g*1™@>ML0qARQs =2{ J氍XSsEܥ槣,-6Aa< D>|(ZMێ"3 |Vy!eS!HF 1+̩@r+!x1@e[L@ނ%PezOv< <8\hh2b"LO{]7{.C_Wݽc%hKGfm9 x5|[Z}C_ ]n`PhAJŨYe9p#WSJok]9]K9e\i&a\"'F NY! 1o0ï:8 }t(P &œ`wY:@` hGn qa9/@FyMj BZ184x<8 N%%^4AF K\ѧOjǏ17 i6'<tmQ=  Q à—=/͜CA>wjH&@l>Uifyl" L`1Ui#G` 95fU٨{- ïk1 /97` kb}Ztsn˗N(Cn@*7yE'Q1^ fλ)@q7P1%*]9b́Fp 2R۾~3>} ˙ԐVs at ]y0v0bC!Vm `Q17{ V2lO`dY,]EsZgp~3SOu,v<W{ Lb$)9`$+Nc-Y}q.5Ȗ4$$jѷ>O=ƿ84S/bz370˖v,}݉h\߅>(uNf0DOfǠ 7}kTo"k.1nޠb/!]/[~6[f!z|[#l-~ۣy+w/},;QI x$FAi0͙06H3Dч%-7~8رv N԰I讝/t+wۆoî% ]?v2(X!md3n?9c2,O?7ݲ+b8w֝7INFo<2Vv 8opMazn"[`{YM; j/乏A/ss/0(1DzP`}3\tR^ןpBf7)+o+#չ1X(,sJGm=}:o : ȡ7ݻ^A.#l}ߠq= a%7}fa"n!s$E5=W3'Ԕp7'L]Gwucmr5_o D >,; ;C6Wy'DW]jL:e%KPiLvw0&a@_+]i%^QAmJ \)o+^e(//OZ s4涌Mb Ӝ!YPGẋf'LuPjo?`+wK?m!U-`WW.s|]lRŸj'GGn[A*hM<,+_Kattqz%_G jWq.dB53TQ0R$L h0-xܷnEukܳF=[JΗ~VR 1~ ܰcg{a֍d!ȣq/F[ո?Nʀ4r/AJ:UVwʥH4?Fr\#˟J\>yT3I}D-Jq?n-Unp{ſ^v=n @=?8Z~sH+_9nr݀,|jA-\@5 Ygj|_(˅IY'Qه-)ܦу/}wqWp*Ҥ{} 02Zɀ.yyp]pC[nbHsbAN :$F|0 uL2JW0p^x7z  {+sW^pBO-Ao}Od)\R-߉ YP->#y*Hx@M=f}>{7fwG` žRd9qK1!sn 'MwKڱFp?^࿓ ;aB&H$Cs9y@ ؃杻 +ku*6=ܭf[O@.=D;CF@XGyXk@x kEw{?,}:eFG_wuO}g_j@*O@Zpwc;6t h.6dIS9u}B(pZ8ׅO8滣 Ņ.y)?8˽wt]_k oŽ wnI\y|xƻ/#$uxs碽koNsg'nӷl6HJ U[]zhWĀKyY Nisgu۶ -;p蟸<}`o[4<݋AeV74m+pnƹB3je!Fy ^8gZے&V ] 5 ǐ&hwp?׽cO7Ė7m}ȆnǞo{迺mGc{'r{Jg{tO)n M;+qن\;dLvp+8l@Z*Zny?E]v̍0֏g69!k (_'`<>v((B0|` yrnv :#WBR{i,zwO!]0͢#U^Z1<|H+5(؍b~迸-;%7h< nW=nbL C> )>V4 Q.x{2#\"䐈w7>KW%hYаm^8T.bq[7&0r~O߀ߊe뗺w D&y/ x{Ń}LŔ#w&s5LӯUs8`4Fq/V2gD _k]@H|]SP͸ew]CLlՕwM?rrK;.?aWsVFOfM/)L @!=C: -3X04cck3Ea%n9y_%󈧷@ֺ.UIL깊fa$Z|Cr"_N Ng|® 5 =Y:z?Vڐrl4{^>wޗb($+7l\DɦL32"@Ps#W?! ݾ378؈bb>NO:G~<Vy`677/u}sxF݂>iYV LRswd8Qh#rcI7PP[6(h @U,4Sx[&;}qa.}MMu1zPžU k%CbJ7XYI㬂,'1زLXg1 I`dg [܎8hhw7a9WwY -`w { c`% .bbf T+ W)CԴ־B-lڼbU KatS'nkemؖ@7 ㆱod˨ [s)0{n#-;hoja%*U[x>YdƱryo*j%4owH P?`"FrXsG؜_D"}D3U+ "QZxyo ϐY$Ų"%R`5N? A.[Nx pGc}eKh(TCE|mWy q ˠ5,En&" ꦝ8OEg^ ;PBYg/u[%^sM< ֱ8R[1~zצ[b xFO;rJc \uQG$ФDѷmX`]uX$\ƟgxT~ǩADE[aNǤ]7 Jl3ǟϏW F&8-t'&>\('υ3cXm H;U- le *DY7u_{xXQ!Gnfě/1ͬZ !wscCC[< IE)J7  V3%Vtէ hCW>yqG>Ƅih^- 4Cqw1-Dhׯ vJ>\[.N\?=çp)C;d |K%ҁ`_mhzL@ vjpdۮ^tQ<SH$o(:h>ǣi( n?}eG> r'WKԦ[ͲKEҦ+P-;gͯy#!}0ESj`P`ůV'0g@ z|+?O}x+fE1Ȗ_ $&=JN7yÛv

jyv8Jq~i^qVk˯ g_#vK^*&C@q3^x)c;= [m805[6 tJ[ F% j‡LnJ}?4xш  00a1O3 %qV6/%4Z-22Ǵݭw(2:-6Aq覭1ËiqAOw&I`Tb0 SӭW3‡৛ϪЦa4j{ߍ~ÌQº'W;$ Vn VKA20MS/8we`̔M3Ȍ0 E~5V2>m^LGMیQ u4tkU*!խW[*Mb+2IFݴihB0GO;|V﫭Dl|&0,4qxF8>kx6[C@'W7mzO[h6 hwdB4 G7A&)觛3l ?!#@:c7cZOib= WЭ_Al$9f0gBe<^0t4駭L lLD0XGը[mhnkA xx<C1g~B7]^3˙I%b ׌k7N8/~# eYDZoi+@ ;Cښ AMF}Z! faԄqF? ʼV$2n @pi>5 $CU~+H7 O|lzeL6(4,Q`ӯf\#Й7>d|/ޣQ%~ R@Y&@KuZV+vL4--$W%a&@Y0,pXJ$#WݴR+Cњ1 JxfzZCuUֺYkz ӴିL F /0jA | @6E?ښڼ7caVwhk۬8̣ny&-ɝh0cf`eaO[Pg/Q70yO/k1 $ASihk @.1<`0U~bZ܌nYMfMWW[Z4^Kw8j{fQ`([talM+5n{9fR zO㪭 m c q{7 ,a=?~5^^'J0͠8L7ta[ ( Shn}Ivi,9|%f*,b@ ab;6 ,'u2/彝_JK X6 4uz:kzj3DVl/2=@.~'qJ'{ -AQ`U)ůjFFShX30f>e(2w`IENDB`ic09-PNG  IHDRxiCCPICC ProfilexTkPe:g >hndStCkWZ6!Hm\$~ًo:w> كo{ a"L"4M'S9'^qZ/USO^C+hMJ&G@Ӳylto߫c՚  5"Yi\t։15LsX g8ocግ#f45@ B:K@8i ΁'&.)@ry[:Vͦ#wQ?HBd(B acĪL"JitTy8;(Gx_^[%׎ŷQ麲uan7m QH^eOQu6Su 2%vX ^*l O—ޭˀq,>S%LdB1CZ$M9P 'w\/].r#E|!3>_oa۾d1Zӑz'=~V+cjJtO%mN |-bWO+ o ^ IH.;S]i_s9*p.7U^s.3u |^,<;c=ma>Vt.[՟Ϫ x# ¡_2 IDATxy-UVwzcOR_{=Ir $!9`1gĎ_p?8 $d<{w0MwAG]GtvdtxpT)B@_Aqϊ C!!0ʻYFeT偪ol?ޫQiB@fvީ;u+ 4MƸnVJqW! &qwӻv\eO:Mt+l"QYTlJRB@ w( 4O"G)'elYi [ج|3TfʐB`F3 țiY[-csLD~6қe 7^Ga! n P'Aﯺ^Zzڠ2<3_]8JaND~4x6 pSQx.i@HLcˀSA4 `/!TwP7uu *;G&?=OSz*یnOa! f ٍ0L?eu:ȕx*Kiaa5ȯ9Hoq{m`TKqVGIk|Ҙz'A]*B@#K wYfEKTzˡq O){ TaxGz*cro$gz# W/#񛦥r{-0!zpAyS9r:4_=s+o0SAaG72O6(?M>dp,Z:e{&Leixݯ!NO4pȓ껰t8Siu'* Mh0a>0߬XFݯWOGdpMiz*WX!0iʺ4t>ryx0ttěd8_s1_SϳcI600SzZG=X&ÌӇ.HS&_!08Ӻ4 Ƈi83M^];HƲS'!XA&T~S ӧ.<ɘμi< #=>*igw9-}`fngffof-^sWdyB@@ܙ2psÇK CqSiE8p̛3ản]I\ 4ac~feInwכes,'HފI} yV*eB@L os̍L03V^ȋZ6X?!dMAKA4apGO[K-Zl<& Sq唥T0d?4|};pֺ;;[ we*PүB`:Y΍ȹ;t,n!`\nn|pO/ 1(a?1Nit Ӈ< S/7JOuU7%kٲ!)<%urf| S'[_෼ɇcn;Ѝ'yU8tM]!@B`#P=3B{g>ża,xʧ ~JCAq0O $CbZFh7R9u~5H҃.uA'S٨&#e{cwso)0p^@'  !  k3l6j7Z9doi!1xdP; l#P?/7!Gwd?$A7SYG8;t;j~@3$e>gsn̘~@Q3 sB`/#1g 0zǻݎ 7|W]Α#2iqʠڔ9559Ք6P6mY x ;z ׉efo=~=!h[f9'AnDOgB@L#$o!whg]𻭬m4sc 3z_LdvJi̸+:Ї Kt@mIVA:C.1@uξţ#a͉&3_٬"ns&nȏCsӂ@JfUc/ N7ȿkgkf 25px}O \{).d08f&K)f % 3.a0L9FCso/ ~kٚ7XNGkoQ9;uF:*f\B`#Peֲ{φ@mg Nwݍ`eC 0l`G Q$>\*k279) aǴ&?!@)N}/,]?-{w?_}7xI.*Gj|! ~FD񾄏xwg4Yޞ0z07fǪ-FB7 ;'Y]V 1 R0QVSMOD;``x. 9b 3>e|w> w;flrZ{a`tc|Bp;f ]R&`<(}ZN!0]ho/nڟ*_hcR zZmkz{ީSVw! W'ruL?506C~)/ 4o1 #S蘭{?[8{'yn ?-?;+7R*F`Gd88Hs$G813~?CvS@ >dܢLOG⩜䩎S7)-$uQ8d u)O7~;x 'lZ?&j<.HM*ɞ:?b儀ӌoK gvޝ+`qU>>lP(Fڍ ?g,3 ?q0@F|8Ƒrå>ÑRVh qr e4V+0F:ɇ,=ϜsOb||t-Z?cF.~T- yxH(DtWB`hz7 ]wk4߽xc޼n; 5x%\.8qW|ՉA|%>+3NTVOή:\Ny7Jc:p~[8 vv{1 f)b?0ZxMtJHR[!!  i}6c>1S .ɿ򖿽]oyU|nv?j5"7x2OqQiC 7,mP-q! f>ԏo AaD8v;YL(M=,1$NNjaUrB@!0N߯ɻbP-px;xۻx;;LA8dL_S))Iwd8u7͞?,@xQ4 Ϲ8kV$ohBVV)B@#P}&$m;vD@:d8(gɊ>HH qGy8 c}CP49?ae'yǖ @P,]>L/ہ@[FopCݎ!^({f#g|GO[Q@]u MB*k S#Fi n{'n|1qYǾ,;V2TB@!T߽{#K-rh= ',,< KpLK&T I})I֗q\N\u77TƸ?x@?-D3a6RtΛPObV&t73 (a D_}LYN! vwcxQ#p9>v$yf F4N}h0 ? G]ݍ7s RySo/Z9GVqo|y"'\B@x'c?MY3MeD?\IQ8H|qʡ0]rÇ+ʷ=i4\i7|U0R apfq҆ǏEJ>Ku-k0e襕UrB@!0 4c2`Ǎ ;57\fgH$<,X)4:"e~q!R`z4B >oo0d;DXJ(,{}.'ﶫLeb7>@ wrINQ.:Q/3LOY|s G7À$P=9! w4Wks L)v˴'Pb~d>\=RISy ! D W9ys G K &#pO]Oéζs$MݢKa2B@haKrͽʹJL_JH p\C9eYVS7i3OGn@<4i`%! ^F}!È79r} m*A~Q &A'5n82B`O"@}Il@(s©zdKdLvm?gzS8yPn*!4 ݆^ŅB`{h3C143!>n ,#q\ o7> ! hBJ)0S $cpRQTμLO=?o*~B` 0O| e|t>/hOR=7Q&~SON! @3MĽKRNIM9uI5m .ayycN*\N! (GpS'=dp#˿m/@ơ<%z3iXfŅB`H9aԒatM2QN=i^vMrL IDAT iZ .!PϧB@L;rI곐TpӆQgG}^̎tRRR93~*c~=/#QB@!02:h 'zӥav͟$`0”]X'B@=x<04 \:v(!(~=M}B@!04/1! tT/$/u(.0EׁCTFpiO:B@! #@\tQ?O$h4FLSGB@M sRnIÃʡNNanayL񦋣N(TdB@!  wЧy0m[SnQ.zN]8ey^B@! FA : ?әV/.;MBG:FYi< 7G2! !@!z^P24dM4;m4] 44N}B@! !rGf3z4 X}pTB@La4UIM QE.t26҅B@Hz@8é'&`#hpÈSAXN! (G菒:uJ *k<;v.j+AyYAH.Ӊ@4ɀ 9K0wn` JHM7ɛdMeJ&B`u>AIQOOv=<) 6o0lɅB@l@4QYiVeTx ť7L! G菂 gTQν)I06xozH&B`T'2h-ۄCM࢈z&v# KDfv:z7s 7Ğ\lտNox"( # Apzvt)54gme?I0F9=bF>Ģݧ ,!0j@{vE˟-w$(5Qà`XB/nv2$ #`&-! vT-"6ń/N1"V;[ --|P gXʧ-CeB`{7Kٕ>V}P{-%s0~SyʋށY[nbM^ ! ۇJf|;ǵ~^I^I(#v }l6y2gO՞,\:!_! # `j?fW_V^C/$يɗC+Va|!)8 J:?@N!0i;ſv9dZp$xh0)[0J x/AiXP` +ze#%d:! y|3W?cFp!d=7kq'9hF@]y뿐Ei@i8 .ekLrB@ @@Uast\mk4?[jďhi-iNnx/A!GPzh@H~gpDR8V퉵Z /.# `oNy6n-Dy_˃sr! $vdl;: gQՋ2_farapKa0GH!C^l/NO儀; @Y @NX _CA ">\gnp|/+N8"?5Խ,/;7 los8[j\[ K:|B` 7&_ 0t4/R&3GNeM\QN^`dI#N ,?QPMxB@l'2]=>d_K;كtѪG:lob((g˥?5гӿ(ksVZZ%@C! ہ;zY~($r%EBs1O}zya$~c"oILn딧P*ȞQκm^z:jj]SL" `xmBk J^jω4bjxa@vhPv`nQ>  +[\G:乁DPa\[hs* (P@" `xmB+a˒I8檔&C/J/lav!;28;qdv|xvxH6?;:#4E]7 =|LCۃ U3Qhс`-$cӂ`]Z')f{Rk);4w *4W+#` |"!\K`SGI?B@FTN{ſH oIaoW-f^ td>>TYnrr2˿ u7H,̶>iqO}XCM`K&M#&bU׋AtieeU?=\;s:Xо 80{ AdE<9[0A9' z ] /qֶ 髀AB@42nB!F"G0Y*\}N@JHG^: R eN![3C$(=4%= Ip? Ń_.0@\W~2ƅ `w1"$q%4 چÚ|u[ a~^lֆM~V ԇzVC#yѣ3^0 X{EBB`$`RYYY=s6ܯ4S#+F@iu쯕 h`%B@l[ENvh]{NrOǻN$3o[- {b8 F3|[2ۧ ^B9D ֿ{8^Hq́Ɂʯ|`[HN!dl51 y҂Psԯ)`a#aql%1PuW@gߕ-<+.؄@ ^<YW0&!dC.JZ׳>&j(B! 6 %FsZ7 `j&Wdu>v\y.kSOm}7mzْ}hHRH"4n|8 b8t2 _lb,,',26wN_ 7ȼNVd8Xy 0?7zms^%儀A@fВ#бyiihXwA@g>nPj6ruw Wt2 #=ƀIкcO# 0]ضTPN!0*2FEJz;c@do4X8j݁a`# кGq/؄\ {|>ju00@ևf J#F#OW lm_lB%3fF"B@L-2O6jLڬ־{@VՋ'J`+_CCeOE<m7g u1ok(/ !0Qn"`]yR47FZہm׆LkžH? flAJi7Vhq=l̻ύ70 \xɫصw[>z+. 2Ckl *o\qu>?$o@.UϞ{w<4z%m*?r#0 ϻ#-Y]WE (P@A从T̀Hq"`٢NsTÕ?4bNiP s3 <\ :"ݾȗ5| >Dc`_! " `(|s?pn P?WZ # SWi - ? #Pmb(7d붓!`48\5{c(pqR'< hBH2!ee&@)g#@opH$~p߃ ج'w9 A }' @aDfH~ ЎKB!  z &_v凄k޵-}zM.PwG>@mpS$ʷk9& S ~c>@n.۳ܯi'@! ! @"P_`#wě1pІƴ^:ppl>ela7 W4=0 y s s;F@dkl.B6 B@HPxbu _ *`DXp/|Pzixx?>'Qރ0f c8^+i5^$8ީxðg$l_?/?78B<@ύ#~_ 01`i ?.v 7ڨJB`# `={uԝ Ll 컲|q`= _ 8G?=~?=1Cs IDAT`p /~L;HB@82 LvU7?,[6OWws`NLGk' V?d1`]Ȑڎ ?+vX* T! `nX,PTɫڕ$ ǎ;5+A d{ԛ~o٪~hw- Z/>0d>Ҝz@9]~.k;Q7 T"B`0w}¯gnjY%jlkE%k C?lfpY0] @7?|A< xʡ t$S ){2h-8ʜ(.-nSm ;U}軽 {,;d@`sA sR77cnjmP/ת (S ]bP'?ym R_A㕿`-t(GV'ACnA" o' N p#X2^1P;dS | zMe٥_c./{Cn߱>^*sc(`{;ߍvRGz0LCrtXe;86_B`0]{O\m7!ɨp~o\x.+6ZO{]88h y{ۧppe/FC~+Pa=F@*F|!0={gc{vYJjL-`bO[}[/6`:U{`7%wʇP{Ŏ h(h A@=q6~ImPzȫ>1V?XX8]wWs l`8Hq>2 Cp>$>ߍK(0/W4 `ƞR]Z &ŲhG ?v*0={L-2 (~nC\;>ŵk(B!o@,~$DTd"Cu}Kw <{?;[OOďaiD=@HGTO^-}O4P! `n_nZƽd+`7Jv^8@ǏXY4nA h-e6@>AG/@ϑ3+t=B`J0%7z/]fk%&vq.&z837l^_TnV?۱' :({h8Eː:'ɌIhi(P A@qՋyEm""sy+OA%$H0Sgm[|(`~vɜ׌+/*)\ M$(-h60 l?P@B`# `=u\ߦ? KAtUcӈk_,ل[ VğRӺKH!>)^7 bNSb>F|ԥ)ZԚj~1]dZ5 v xEN?;}_?WfsOx8FZN1+Ǐ0 8 l/?;N8ʚMFCg;@st{S6XAq=QB. hI椏tDZ zfK@V-eNj6^*cyjMm _8u&  ;|(`m1/M!Oh;/YԍU!/-2݃f־~Vu bC?k}3Mp}Ze"]݉w V'|ٌ!k}nơ=P{H=uN>-}u .q'~{%](Z@{{c -Ropnrݹ 3He(S78@*iO@0 Ÿ@P xŰ@U\ q?Y>R+T,_Yٺ;}P0v= zS,s?7`$^XU{ӏ{{Y'-]FhE,OqMy;^{|( C%@t{[>oF +V/ uwBCUl{{:?Q\^7'Rj I FceZܩo,]0?Ojա󡀘яx>|\!F[.NY _OZk60a(n $mF][ [gmLA t*~WwVL+P@e@ ?0 1)JnD O\tֺ- Lcz 0LRvY^~4))lUߩo.ZM&Kw PWW3lvm0hV껨j bno@=^jK7.{{&MC} -uۮKk"[{{=aCes|>0sʡɀAN^tW> l (k]d* @@MPIXZP'$*E`BRvdىcU&>E*C~?_\0$2&"\IZ]8{zlGiV^'o1;v_ֱcU}}#dhp@E~' oc/Do \VUf_s\ҧ E@ޛYϾg׼20ɚ~?,EǺހy#t( ZOzv0;=Ԩb ZG+Hނ|h`}p?گ>y|( /" `Bo4Uk >AC *!#7F&tn9 쟉jAtsCBc[{)n?00b(b 9! &{ofT&u7Ka[A"ʀ^[9 x2 ^6 ae7RS9soiy `=0V dL}Z^xr7I%߭$wZͥCWꤿb|ba -=UT!+ \~˿_]B`0ydjR횃BH~)\a8Yٚ-1_?Pw~Ev VZ:`* e`G[u 0 G9W.'B܇+V^r]!0Y1uYq{kA!uꇅT^VZn?~_ޤe}CW ^^Nf2hAy墢_@޼tZl^v ,P@L2&fLcUz9[{HY`dOs&|4k Q/&s/&FXF2dp‘0E$\QPa˖>$pX`t3Nb(!aՑN)hRCo& \d-4p=Z}' VKTLB@n!:445br g~{@ ,#b& v` 0O vy/z/|403T0/vkj\\ mh4el/mf<=lن@"fMدx"|`9PNG@߃ڵlxp*ԃR?rޯ<~Yc-le~f޻ɺ7c!==h0Օr:e"[ۆ|#'"Pw:":n|ݣk z<=;qp3@δ8 -5[c̜*J~rfǏݟdsa`t(ߕ[y7BupB`Dg W_fT-BrC3 7/-97 Q*1ca NFg$ z?#/[}57nɆ[ݲ_Te}ă٩[ߞ #V C Zn@Hz y⊉/{W ׋6r1 B@& hCE'3^tڬ Gl">9oӆgKa s@3|lK\o[/tq˟V_=e{B\ G@c34 /ZWRH++Fl;c }8.ltÌ/Cozh[2DC PY=+!z/ _C;1򳿦Qad0:] i&@[]n"qzn8}_ z>׹^|x]kG픈i}:*2#qcAh@,vȐ^8q p0#v; Nlvm RFQI6A8ۧhE(8|3S ) ` s;;th= ۤy-1 .°',Y?׊}v Ej>@B`[&}>ȕҬA#/ԫ]K1pV,oxfd7lEztZn @Jk?D 0ŭGl#l>x;@|gΧ՗.ǙmuM] eh\0-|#׏@J!4MǮs޲GO{Q`\Ny&䂲 z< c^mj>/v;NQE'.=S汒`hx@k`㹦]|[ϼ5-l40v B~Ax :>*|*&  &_{/Je2ɞ}0t);a_0BkFອ-Dw-[u/a},Ѫq.KZS /8p^49! PUd3 &Qʄ_w0:XN}v'7:]1hX'[3aVTwWz"Xkr\-M,̯Xх^d6w @+ cDg֯?ie7sY.jo@u~79ql͈Kns` @w=ߐ?F:x[Y|X2ȫ_#GޏVG_\{g5 ү2 ?߲-hSVSA)ǝ{cg6]xRY*Gߟk}9a[}" b '{ 㠜/> IE ѱM"W?S)d ٵOc mIzi:>[=RnV+X*8?dd[Lc=~p|LV?a0'~I>/ \DeF/T! QԹʔP.  |'|5pH}|#w|~A y-i>(JG `"9Vw| IDATXܫC~Ho (s~vi|0Q?Nty0*0  ng5[dŧ5i4Cm|2`R{?`[l>@>&q_j T gU&7O/ZO0ګdמ@QTu#!'9E`\箐I8MYIeԣ,91 鷝~LK@t賭Y;'p7w/a/,L[c87`K*{0i۝'!JR"{|Du>@g>@@>z _'QE{GW)_n T ꄴMrPm7?d`&ߗt>'xFg& mD^ai9! Ќc@cߎí^}F%h)"T:@c*phkDjw>)A3/>kƴiI0OP~|-i iG@?thylW[aN{/uI$5J6ck6Μ|8;|[aw(__ J~IՋq Qӿ䟝z}IrB@# Iƀ@uKYyXilĤwK Ma3o?v,qۉP||tfc 0 #b 4ʯB>?lE6ŧ5J!Q@ @'Xҵ׬?u '2υ /v>[ZYe~bKY WMsއc7U$~oC@@:\{穚4PGaׯxK|: |w{0z6\>¯K4O:[UMf e`Z0jNQM7ʧDHNY[F򿫖c-tt' $HJ蘭m?nM[li|hI.|+]UH}j D$<(* W) (UH30V_+i U*_$g>NS4w>\l&k >{N xڇ,5(/  X]}g4P@HOIUG1מH2$o^z/oXl71}k Ֆ 778i >{#%&N^drU_~#)y^\k%{~2):o$EO`D0o{m5|(71Ȳ_[4*#?%*в!=4Xi<|C m!^|/Dm|+_ϤCo>Gl>@-pLÕF@sh(ROsp4i(HȟfdLӵˮ¡|Ws-_}Wm*Ͻk]lDө."Pl J}V8$1>OXB,e9{6?b3DU?;?Ɗ }ʹaEf9qC6}ށd:xa@wCzU|RVeѫҡ*W9!0;?F˭jˬraVN×~ w7).ʭOy|/|G{JzC4 z"࠾?E;O7g{3ex W]}'V(F;tޡGc {r{4HdW>'O7z^lzϼX g\NL2np {_fGw_xw2e㥩od?dpՅA0 yb/r2[bE{qn9{w~<0WTt#SlX vQHWd;;uyވ~}l6AꩬŶiw?Sw37J_L_iOd m߯qu-C7&?q>[^|9/+Ⳑ>WZ=?(Nywzv_(zlKNL 2N׮3j:C}Bm!$#rY+Jk b!{O^M Xd12~PT)rg c^/h)'pk'|z&#sN==wRkf]ɧDx) ҏfAI ]OX0%'pkt_~$7=ͮuÿ kѵsO `bumU«>] m'8/0E&\Sd&_zg[KY@  (tp: y/WܼV7bx(_mc哝;no+H| JRwϵg~xͭژ92i IG@ߡ>嫷W.{OaS:kgܻ ]e ŗ,S{#/ulc{ze=o-Fr`;}}oن~ 8:%4x>wEt=ܟ.柅 R62Z{fgMs_{9fk|=F&J 4>]eٍF@^O';f߈wWy/AO_ض 8P\|$_>C%WMh¤^O2, o4EN ">_˞3o-em쒷aMhPl#0L0^ lAly:Ol(/C=_$WxI}R#B0|={Kԇ "OOwӮg}'yF@v/cw*I&!ܼ/ #~kvؽYW}%|'l~ | ,U:['h(t9/c+^k+9!oA/>ӍWouگ_SK6my)Ckٸ?Ŏ'N} %Y^}y34e-hZ,ؖ7Lll8P(KR)@9TR 1!( ' L9fڥx43F%w~}>3_9_ӧOߜ[X}?GwGl7o_ D_K>ZeDzTґ;; J.Sgzqh쓧Us܅3zRPJwM>{8K$5,׾yة=g/j2矶>}ov{Zo4עݻK|_$7sŁka$\#|}I$H*'gla x[{Q˿#^(\G{e7PH(ᣀ!5X=! g H#"`D]AxxK?]xG֞ ]8; {nIvR{x_;&q݉p-ߛFX/RoYJ .ҋc덀;\A+#x\췺xO.Ll=UvD|i&6?nVnƟcX݋`(5 @k;-e ͓RiNO?(@  #;6a_Z`3S%'# ~p/o}7;w=ob?L.twg c(?Dt4@07˖^~(+/b"`]dwd|r|'GKpy翰pS޷Z4<[oGD>|$5!0' ǿh?(_Vt[7*B`P0"g0?&aGhG~Qd@ P]3}yil|<˃/)ܯc9XF p 5%C@B4(++F(y"F%C~9?^6ٯL8:\w>)E~ lamCرYn~}Gٹz#oaBozW(Q"`O\GǷ4ٯ0۟EtH$|$Du=k~ S{ë~vuɾ/cւWUy! zdPQ&67@}P0gj/}~6[Yߢ$I[$y3'bCcޏGtV+"!Fysݟlcc{8eڧ.n$#絭5G oZ4U Gm}wSv׿`|7d}^sӇJ_CB9 `JcS-s?<hNyih?{Q.'KF@ |ﴦIn}٬$-,s䶏dxorh`mNė"o}%hKOZRqFw챧ۚOmfF;hO#G] s&-!0J(lU߉~[9\&S>ҫJd*o_;TVH-"5?Nz%?bZ,(h5JH0a垘d %5v ߭=s&nj0 [Co̮uޞS tCI"dτy&O?⩐"{[o"ݷX|.@> p6go"jB%5.ģ԰G]bzj:}ſawGnpvM.?n CXK@%ƦmXvȾGu["xb2;a;,ہW`-on"39(%s(3(U xo+:=࿜-\xߏg9#?b |qV+wو&*] \ s)^M@܀E@(  ,;RϠ^+upwf}o&[iWl[»]Uj'~-#o]S 0C?ŝ?M._(@(1@EJt_*>USBXB/tu)Gݾ;;6 6hN?AƇ6!0(baWuSSvќK..e{nȾ㝟 px9Ls6 ~q @Y][N>6GRȟ> IDATw_[Qw@P7( mdҾNW_;7,XӖlaҞaVÝ>W/A$fn F(Q){wxJER5ntu=aF@ |]֡5)釠Me*ҷga&Oڝͱ Cpδ dkH wXX"9f"#)*fi`tew2a@@ b]'2,;,~f>ߏW;I6iQ@7\ʫ֊q .rvOM1u@E +JvT[ol37'ws݇?\B3KHr(G~(4Vs8|79k(gl3(Y E?n}KLy^};gY-[BE¨ QW7;h(m BP/5N GI~9o#A$FԌ>l̖%eYЯ3&-|4;{n(tJr4wHP'ӟ̎=K;֛3[LjK[@5#\yžG_3O\ @;~Ł (&aA@ @ 칇~ϭnLu/-˙[RXsZP^wQI?clUwU8GͅgFN~W  53`PPgwׅVQyTs[e[TW+(78}Gqz/l,Wv}`7o3?Fn;&4-;?!Q}mTa-٩l*DnqJkY ,Jz~6袭~L*dsQ0H4J8cr]|->M~$;([鈰_D.FvCpoس `l%=W?gL4z3 }r_\k !@ex(< C܁l OOL?n1?po>|[EMps'+[]O]_ Ry5V,{ +=&mU졠ws6|#_D\..v^l%ò.%O_gw;G׍0 ZTٙl>ዻ~3_9O릮Ka}|eJzOL?z1*υOMս6_[鷲6,\s>cπ#8 IJ\Mא8` ̅NRv|}g6'^"%CΝ'{ғٞlbjcW,jE@ GRO'C^\\#Xg§|þx!PFNl,Wnxۃ9Kx\xH\P03Gо0 H1 Ke!ϸIA|O{t w9 v[hz~}.{)Lţn_wQuO\uOJxzSI w|XK _+? ! zGu1_ ka֫}~xΣ\OJ|KE6xnbQã̵'ir_%5JJgkka,t瑿߶??VD&! . <>âY(H'C'1I*BrD@ @g5`Q `P.Ho~G7ߙ?n2A+frB׼#$ޘ fI='W"E@ ՋXo~rX2+1[Z>ꪷNK g/_D}ⅿ^|l~31@FCKk,fuN <O׺:'f! 2<;t6oԇ:L{V0'wqw _{D AQ)o$`gpW zet8n( Q!!>ĂGrH&%Ct*qǃ`Ѡc\RE!pfsվ/^}jo40v%;ZǃH--UI\2H n${g4:1>1^vWJ|# ]!y9^0 =aq{{ǾTv1%FY @U{B@\ďpPH>Oe ^a|=p^{$GY]`wo[@H>eka٩-.W!P/J_ !0}w=/ܐ--+fX`OvPB UI{$;$VWq{V}=ZF =4GzwS;VB`#$`y;Cّ>bdlnV S U We \/gpU/Bx5! .cMlv<۾/wgGO~6{ 矶ޗMLd6qpV>1bXk Q!0P nu&#^;];1]71v8HnyvadveO"`žޛoB6XX6ƺm#$LMNeSc<ˏ .q0K#E! v7Mm :; bvg^xmE qc(Yr7mAt>L.BoqEf鰿Y.2g0+.z)茏B@JHhd;] \wanHhI.ڧn/.>ow3 $h}zM=/n YXZj՞ܓ{KMͷ.[5[fF@ @i=#pjc),}lvl)")=¶raTܟO^p8 玏/7;"#<2 ! zCNWسmT`_wPMEl%EN C^ئ&tv}*^%:#3> ! F3 oI L-x3Ih/4!oj~`P/ H oD+ 3xa^GYl=Џ `tΕT!P TvOUO! %NB@ԋzWB@! jA@ @-S! "^ջB@ZPP T! @(.B:B@!P/J_ ! %NB@ԋzWB@! jA@ @-S! "^ջB@ZPP T! @(.B:B@!P/J_ ! %NB@ԋzWB@! jA@ @-S! "^ջB@ZPP T! @(.u!YWCѯ8 ! E`';L ! !a;! 96v呻T? /B`P0'E$B``Qv$}! A: P;mzS&=#k{ޅ-. If9n'B`d*pLv|vh1H/E1aM3H0г{ @.jp$?YGwEB`n(IDZL}7zݖ`Dh@PMn oUB@Ftp37}a7Q['mwЩK՝Wԃpku[4)]8! M&Xh\tNh#vvK|)}ɼ7蘶 rs~(oKB`hVZn浾tp|6q\堐;@G,絆N'U/}'>WN+9⤇_=S+A! FR.k>c@O7?<@W8dHieItp)D<<چu >kgN"#3̳-c^M!  кnB@. .k+1^Uum S͡憓M.REBA:cA+F4Oq2;uiVPA&_j]|O3@?y}.v6cfipB@H_r\C u{-]>SMG8B\ۧꇶKL馃oq;A s_?vTnn6w{߳DRj.oԒ! ڍuxMcm 8#?VXtFyhn@dyף<)'}2=l?`_QIva5KvUB.d\.^a"ĄWy>gC}b}l Z}יNSL._y]6X$*^"D! yv  .hliÆ 틶͆J8*ϗXw| @^)`C?/g'э3@00:>ț\97?ZBGa7}!m5^~_j* )2(7ڶCv^R:n; /zAO}!d#+lN ,~Z`b&uoȸKB@!k2zn|5³_h,_c`ṝ n(b;۪w: @|)PbexC{Aw|NFx Fors%$pd^?DjEB`'(_s[p=/aqG=PolfgO|Os 6:/Rw@b({}`&O?c_‰Y_iAߚ,t %VE!P ݂a kv-wYc#gO~;(Ēfx[b:(1Oۡx;L0Hi n<%z|&c3A>$d!7di?>EBh<>NFvvrK%8=/z?~ CpH mOu =߆%a\Q@XBb#@ }=up-5ĿfΒޮL/yF(t(Qεe;u;N=: n H=(N"VuɥOAO=?|z 7-6landri$ 4o#M0 7V5GZtB@ZʏFhF^6/MtLpE1Cn%+O|6:a)mcWsBJG;u'8IDAT ˞Ibz<Ʊ~7s3 7ۖ &lÎg ?>L ^CjZ3!9n! @%`+Ar7?.! G 7rC#\_G@!6Tm#繁:\u')O ねq~cj)a~_u" ~3\5 ral2jCbB5 XcjS0%8uDBRnS!{Z ALNMG>8kߔ'֝%ՉvɁ/5B`!J)䣱;~ˠ6'"Z"|{W7`OA@S ŃAr36(J_J v=vMx?譑X' hsMdS;|<v7|aCc"纠/tMm3ȅތ!!7d7><cixknwsŸ>##xT=v|'[y k!^3  -:f ~F n>S..nZ8P 5vQVB`T* ];!>!pON n\x's/|sB@fyAc;( :g}RRV>㧞)S sWok{ߜOb k=$%>].R~D@-_/=8rPsEqJx9mcsWpy><z 2CG>NJɀU/]#vE{ >;m >3Cy C9x}-Ї5$ Ag@:wCcنx5N<ӟӏ>@N>UɁo/U; znYk+dͼ%E#QD?4iM~c6請nU},]CkE`CR$M9:=B@16]<U࿺xٯ៞9ŧ88Sf ge'}烾a!e~3\  Qdrʤ!B`ʭ-H:t SǶJtWml1*|b310.Q! B, %f4}XtGϟ9Qseqߪ\.v[oD+~V˻o QyAQ@){ L2de'rONNnݷ'&-}X(1$Άr0kƻf=Pq Ǟ[|ν6VZiUpz|}eا)`T< }[)cfޒb{n G@ϭ*@S ԁv-o;nsU3^11of3+%=B@fϏź~mWϞ[[9}fu ;@hP!SɂmBDi ':OaGQ =/@Qc?< ~((tkG:!  S=Ez\3Q@'2xA|M%h٦S)ԥ yRkLp-zJ@qbpڥ2t|P?*~c{G u=,*v*=%ZvX!yPzR򐷻/EinþBߩ)]6m; zP='f0l@`>)?oLKm6;nNueB@\ ;Aß2uRGS>CG9EMa(s:Qs/Q]eXN@<<1'6 ^ E RF?S}eSJ׉B@ NB6ܠ#O).1öD &x()b PaHyl^&/ԑ7U(h6GS x>)ԙ9!ccZ>)~RmI'y[-UuOQǵ2KQ uvt?Lj.t(13_ـ xX =2KUÿ[AnnEz)(UܪB@@dM7vzB6lF=Bm |ԑTz,ʤ$ ࢐'^ |Q@1:>q$2hj3uI,Uމڛ~Cqi)}eS(ks=Ö05{bPaCL)2h[*gAܠc}ԅ2A=15U-6A*UtB@~":P [B >7׍=R"ovSW+$#q2L4!='xnS:nG B|P6'e⅀;<|(RzhI``vԡS]m0{uz@^B (c>v(کԙt:`VE}]d_e$Oꃧ vI;ۃo&_l (.S/*p2)my(R <}:}?Q(Bz9BדG] d d6id)ʾ=(-O?G]B狯⅀Â&}>e^'JXG[(!eAQb9zک)ۈNrЃ],D18FzhRVQkl7֡.6G2lS|GQ! 0!//x'co:Qߖ筛 % a3 dP-c' z> :*/'eec{6J>+B`'^~JO]LQ:nL}^&OJ?/{۱KQ₾j-Ðt !<2N xRtP xl,>>꠰.xبBzOT!0J4yRyИ2(Бe=Oc=:Сl%KQ膲 K0;;c PcA )xnƆzгxA>ABlԁV齏x! ueP{y<|P){mt铢Х ڬmnw?.).uL{L$t,e#@<}|ݘoFۼeNT!0YyGS{?_%xyPy N?$j=KC }2}9c}PyuAQ|}/Wɩ:B@ #W~86OtyxI ^|:= Cu BO_ߏב'E;~zPnKq:ӏ:P)ڠԥ(t(%PWԫTplucÆlS2u)  xXB`TൔeN9lޗ|_~QKu_[a[FWţ/bڋmuxlyvn ! veR>^G>{' U|=.AυF-l[ z޷m҇rL{:SW#B[ r<b XG)4bUmW/Y`xcګ:>^|B@~ kKt'o#OJPbJXOvF'W񩶫|WЂnW[}IS>N_JGQ! (# .yԓB*O\7e[MߒN @̸={z{>b9% ! ˞Ix|lUqU~}+HC`&o{N:HShB@ ݂cʞ*~q]?Qy  yB(YS}/xڼ:UՇCKH'^gUbٷb)onj_N jd=ú|lT{ЖK꣺,B@zZɯUʯWojH.`YujchJ#*F:]{ߪ6?U6rN?qPO7۠o''B@\.r;VnH!0ާvԌB@!0B(]B@!/ I#B`病F踵B@! v5է_/%븅B`W#`W~B@V3B@]F_UIENDB`icnV Cstimfit-0.16.7/dist/macosx/package.pmdoc/0000775000175000017500000000000014764352500013766 5stimfit-0.16.7/dist/macosx/package.pmdoc/index.xml.in0000664000175000017500000000153214750344764016155 stimfit/Users/cs/stimfit-@PACKAGE_VERSION@.pkgstimfit.org/Users/cs/stimfit/gpl-2.0.txt01stimfit.xmlproperties.systemDomainproperties.titleproperties.anywhereDomainpostinstallActions.actions stimfit-0.16.7/dist/macosx/macports/0000775000175000017500000000000014764352500013122 5stimfit-0.16.7/dist/macosx/macports/insert_checksums.sh.in0000664000175000017500000000360114752406306017355 #! /bin/bash STFVERSION="@PACKAGE_VERSION@" MPDIR=`pwd` GSED=`which gsed` if [ "${GSED}" = "" ] then GSED=`which sed` fi if [ "$1" != "" ]; then cd ../../../ && ./autogen.sh cd build/release ./../../dist/macosx/scripts/conf_macports_release.sh make dist ${GSED} 's/STFVERSION/'${STFVERSION}'/g' ${MPDIR}/upload_stimfit.in > ${MPDIR}/upload_stimfit sftp -b ${MPDIR}/upload_stimfit p8210991@ftp.schmidt-hieber.de cd ${MPDIR} fi RMD160=`openssl rmd160 -r ../../../build/release/stimfit-${STFVERSION}.tar.gz | awk '{print $1;}'` SHA256=`openssl sha256 -r ../../../build/release/stimfit-${STFVERSION}.tar.gz | awk '{print $1;}'` SIZE=`wc -c < ../../../build/release/stimfit-${STFVERSION}.tar.gz | awk '{print $1;}'` echo "rmd160:" ${RMD160} echo "sha256:" ${SHA256} echo "size:" ${SIZE} ${GSED} 's/RMD160/'${RMD160}'/g' ${MPDIR}/science/stimfit/Portfile.in > ${MPDIR}/science/stimfit/Portfile ${GSED} -i 's/SHA256/'${SHA256}'/g' ${MPDIR}/science/stimfit/Portfile ${GSED} -i 's/SIZE/'${SIZE}'/g' ${MPDIR}/science/stimfit/Portfile ${GSED} -i 's/STFVERSION/'${STFVERSION}'/g' ${MPDIR}/science/stimfit/Portfile ${GSED} 's/RMD160/'${RMD160}'/g' ${MPDIR}/python/py-stfio/Portfile.in > ${MPDIR}/python/py-stfio/Portfile ${GSED} -i 's/SHA256/'${SHA256}'/g' ${MPDIR}/python/py-stfio/Portfile ${GSED} -i 's/STFVERSION/'${STFVERSION}'/g' ${MPDIR}/python/py-stfio/Portfile ${GSED} -i 's/SIZE/'${SIZE}'/g' ${MPDIR}/python/py-stfio/Portfile sudo portindex sudo port uninstall stimfit sudo port clean --all stimfit sudo port uninstall py-stfio sudo port clean --all py-stfio sudo port uninstall py38-stfio sudo port clean --all py38-stfio sudo port uninstall py39-stfio sudo port clean --all py39-stfio sudo port uninstall py310-stfio sudo port clean --all py310-stfio sudo port uninstall py311-stfio sudo port clean --all py311-stfio sudo port uninstall py312-stfio sudo port clean --all py312-stfio stimfit-0.16.7/dist/macosx/scripts/0000775000175000017500000000000014764352500012761 5stimfit-0.16.7/dist/macosx/scripts/change_deps_release.sh0000775000175000017500000000651014750344764017212 #! /bin/bash WX_CONFIG=/Users/cs/wxbin/bin/wx-config # WXPY_DIR=/Users/cs/wxPython-src-2.9.1.1/wxPython # WXPY_VER=wx-2.9.1-osx_cocoa # WXPY_INSTALL_DIR=/Users/cs/wxPython-2.9/dummy-install/lib/python2.5/site-packages mkdir -p stimfit.app mkdir -p stimfit.app/Contents mkdir -p stimfit.app/Contents/Frameworks mkdir -p stimfit.app/Contents/MacOS mkdir -p stimfit.app/Contents/libs cp -v -r /Users/cs/matplotlib-1.0.1/build/lib.macosx-10.7-intel-2.6/* ./stimfit.app/Contents/Frameworks cp -v -r /Users/cs/wxbin/lib/python2.6/site-packages/wx* ./stimfit.app/Contents/Frameworks chown -R cs:staff stimfit.app make stimfit.app cp -v .libs/stimfit ./stimfit.app/Contents/MacOS/stimfit chmod +x ./stimfit.app/Contents/MacOS/stimfit mkdir -p ./stimfit.app/Contents/Frameworks/stimfit # if test -n "$1"; then # if [ $1 = '1' ]; then # rm -rf ./stimfit.app/Contents/Frameworks/numpy* # cp -R /System/Library/Frameworks/Python.framework//Versions/2.6/Extras/lib/python/numpy* ./stimfit.app/Contents/Frameworks/ # rm -rf ./stimfit.app/Contents/Frameworks/wx* # cp -R ${WXPY_INSTALL_DIR}/wx* ./stimfit.app/Contents/Frameworks/ # mkdir -p ./stimfit.app/Contents/Frameworks/${WXPY_VER} # mkdir -p ./stimfit.app/Contents/Frameworks/${WXPY_VER}/wx # rsync -l ${WXPY_INSTALL_DIR}/${WXPY_VER}/wx/*.so ./stimfit.app/Contents/Frameworks/${WXPY_VER}/wx # find ./stimfit.app -name "*.so" -exec dylibbundler -of -b -x '{}' -d ./stimfit.app/Contents/libs/ \; # find ./stimfit.app -name "*.pyc" -exec rm '{}' \; # fi # fi ## # rsync -rtuvl `${WX_CONFIG} --exec-prefix`/lib/libwx*.dylib ./stimfit.app/Contents/libs/ mkdir -p ./stimfit.app/Contents/lib/stimfit cp -v ./src/stimfit/py/.libs/libpystf.dylib ./stimfit.app/Contents/lib/stimfit/libpystf.dylib cp -v ./src/stimfit/.libs/libstimfit.dylib ./stimfit.app/Contents/lib/stimfit/libstimfit.dylib cp -v ./src/libstfio/.libs/libstfio.dylib ./stimfit.app/Contents/lib/stimfit/libstfio.dylib rm -fv ./stimfit.app/Contents/Frameworks/stimfit/_stf.so rm -fv ./stimfit.app/Contents/libs/libpystf.dylib rm -fv ./stimfit.app/Contents/libs/libstimfit.dylib # cp -v ./src/app/.libs/libstimfit.dylib ./stimfit.app/Contents/libs/libstimfit.dylib dylibbundler -of -b -x ./stimfit.app/Contents/MacOS/stimfit -d ./stimfit.app/Contents/libs/ CURDIR=`pwd` cd stimfit.app/Contents/Frameworks/stimfit ln -sf ../../libs/libpystf.dylib _stf.so cd ${CURDIR} if test -n "$1"; then if [ $1 = '1' ]; then find ./stimfit.app -name "*.dylib" -exec dylibbundler -of -b -x '{}' -d ./stimfit.app/Contents/libs/ \; find ./stimfit.app -name "*.so" -exec dylibbundler -of -b -x '{}' -d ./stimfit.app/Contents/libs/ \; fi fi rm -rfv ./stimfit.app/Contents/lib cp -v ../../src/stimfit/py/*.py ./stimfit.app/Contents/Frameworks/stimfit/ cp -v ../../src/pystfio/*.py ./stimfit.app/Contents/Frameworks/stimfit/ # # rm ./stimfit.app/Contents/libs/libwx* # # rsync -rtuvl `${WX_CONFIG} --exec-prefix`/lib/libwx_baseu_net-* ./stimfit.app/Contents/libs/ # # rsync -rtuvl `${WX_CONFIG} --exec-prefix`/lib/libwx_baseu-* ./stimfit.app/Contents/libs/ # # rsync -rtuvl `${WX_CONFIG} --exec-prefix`/lib/libwx_osx_cocoau_adv* ./stimfit.app/Contents/libs/ # # rsync -rtuvl `${WX_CONFIG} --exec-prefix`/lib/libwx_osx_cocoau_aui* ./stimfit.app/Contents/libs/ # # rsync -rtuvl `${WX_CONFIG} --exec-prefix`/lib/libwx_osx_cocoau_core* ./stimfit.app/Contents/libs/ stimfit-0.16.7/dist/macosx/scripts/conf_mac_release.sh0000775000175000017500000000171114750344764016515 #! /bin/bash # arch_flags="-arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" arch_flags="" # -arch i386 -arch x86_64" # ../../configure --enable-python --with-wx-config=/Users/cs/wxbin/bin/wx-config CXX="/usr/bin/g++-4.0" CC="/usr/bin/gcc-4.0" LD="/usr/bin/g++-4.0" CPPFLAGS="-DH5_USE_16_API" CFLAGS="$arch_flags" CXXFLAGS="$arch_flags -I/Users/cs/wxPython-2.9/include -I/opt/local/include" LDFLAGS="$arch_flags -headerpad_max_install_names -L/Users/cs/wxbin/lib -L/opt/local/lib -L/usr/lib" PYTHON=/usr/bin/python2.5 ../../configure --with-wx-config=/Users/cs/wxbin/bin/wx-config --disable-dependency-tracking --prefix=/Users/cs/stimfit/build/release/stimfit.app/Contents CPPFLAGS="-DH5_USE_16_API" CFLAGS="" CXXFLAGS="-I/Users/cs/wxbin/include/wx-2.9 -I/opt/local/include" LDFLAGS="-headerpad_max_install_names -L/Users/cs/wxbin/lib -L/opt/local/lib -L/usr/lib" PYTHON=/usr/bin/python CC=/usr/bin/llvm-gcc-4.2 CXX=/usr/bin/llvm-g++-4.2 stimfit-0.16.7/dist/macosx/scripts/mkimage.sh.in0000664000175000017500000000014514750344764015264 #! /bin/bash hdiutil create stimfit-@PACKAGE_VERSION@.dmg -srcfolder ./stimfit.app -ov -format UDBZ stimfit-0.16.7/dist/macosx/stimfit.plist.in0000664000175000017500000000250314750344764014363 CFBundleInfoDictionaryVersion 6.0 CFBundleIdentifier org.stimfit CFBundleDevelopmentRegion English CFBundleLocalizations de en fr it CFBundleExecutable stimfit CFBundleIconFile stimfit.icns CFBundleName stimfit CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion @PACKAGE_VERSION@ CFBundleShortVersionString @PACKAGE_VERSION@ CFBundleGetInfoString stimfit version @PACKAGE_VERSION@, (c) 2003-2011 C. Schmidt-Hieber CFBundleLongVersionString @PACKAGE_VERSION@, (c) 2003-2011 C. Schmidt-Hieber NSHumanReadableCopyright Copyright 2003-2011 C. Schmidt-Hieber LSRequiresCarbon LSRequiresCocoa CSResourcesFileMapped stimfit-0.16.7/src/0000775000175000017500000000000014764352501007625 5stimfit-0.16.7/src/libstfio/0000775000175000017500000000000014764352501011440 5stimfit-0.16.7/src/libstfio/igor/0000775000175000017500000000000014764352501012400 5stimfit-0.16.7/src/libstfio/igor/CrossPlatformFileIO.c0000775000175000017500000002605614750344764016335 // This file contains utilities for cross-platform file I/O. #include #include #include #include #include #if defined(WIN32) && !defined(__MINGW32__) #include #else #include "../abf/axon/Common/unix.h" #endif // The Windows headers create the WIN32 symbol if we are compiling for Windows. // Here, we create an analogous MACINTOSH symbol if we are compiling for Macintosh. #if (defined(GENERATINGPOWERPC) || defined(GENERATING68K)) #define MACINTOSH 1 #endif #include "CrossPlatformFileIO.h" /* CPCreateFile(fullFilePath, overwrite, macCreator, macFileType) Creates a file with the location and name specified by fullFilePath. fullFilePath must be a native path. If overwrite is true and a file by that name already exists, it first deletes the conflicting file. If overwrite is false and a file by that name exists, it returns an error. macFileType is ignored on Windows. On Macintosh, it is used to set the new file's type. For example, use 'TEXT' for a text file. macCreator is ignored on Windows. On Macintosh, it is used to set the new file's creator code. For example, use 'IGR0' (last character is zero) for an file. Returns 0 if OK or an error code. */ int CPCreateFile(const char* fullFilePath, int overwrite) { int err; err = 0; #if defined(_WINDOWS) && !defined(__MINGW32__) if (overwrite) // Delete file if it exists and if overwrite is specified. CPDeleteFile(fullFilePath); // Ignore error. #endif #ifdef MACINTOSH if (err = create(fullFilePath, 0, macCreator, macFileType)) return err; return 0; #endif { HANDLE fileH; long accessMode, shareMode; #if defined(_WINDOWS) && !defined(__MINGW32__) accessMode = GENERIC_READ | GENERIC_WRITE; shareMode = 0; fileH = CreateFileA(fullFilePath, accessMode, shareMode, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); #else fileH = fopen(fullFilePath, "w+b"); #endif if (fileH == INVALID_HANDLE_VALUE) #if defined(_WINDOWS) && !defined(__MINGW32__) err = GetLastError(); #else err = 1; #endif else #if defined(_WINDOWS) && !defined(__MINGW32__) CloseHandle(fileH); #else fclose(fileH); #endif return err; } } /* CPDeleteFile(fullFilePath) Deletes the file specified by fullFilePath. fullFilePath must be a native path. Returns 0 if OK or an error code. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ #if defined(_WINDOWS) && !defined(__MINGW32__) int CPDeleteFile(const char* fullFilePath) { #ifdef MACINTOSH int err; if (err = fsdelete(fullFilePath, 0)) return err; return 0; #endif { int err; err = 0; if (DeleteFileA(fullFilePath) == 0) err = GetLastError(); return err; } } #endif /* CPOpenFile(fullFilePath, readOrWrite, fileRefPtr) If readOrWrite is zero, opens an existing file for reading and returns a file reference via fileRefPtr. If readOrWrite is non-zero, opens an existing file for writing or creates a new file if none exists and returns a file reference via fileRefPtr. fullFilePath must be a native path. Returns 0 if OK or an error code. */ int CPOpenFile(const char* fullFilePath, int readOrWrite, CP_FILE_REF* fileRefPtr) { *fileRefPtr = fopen(fullFilePath, readOrWrite ? "wb" : "rb"); if (*fileRefPtr == NULL) return CP_FILE_OPEN_ERROR; return 0; } /* CPCloseFile(fileRef) Closes the referenced file. Returns 0 if OK or an error code. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPCloseFile(CP_FILE_REF fileRef) { if (fclose(fileRef)) return CP_FILE_CLOSE_ERROR; return 0; } /* CPReadFile(fileRef, count, buffer, numBytesReadPtr) Reads count bytes from the referenced file into the buffer. If numBytesReadPtr is not NULL, stores the number of bytes read in *numBytesReadPtr. Returns 0 if OK or an error code. If bytes remain to be read in the file and you ask to read more bytes than remain, the remaining bytes are returned and the function result is zero. If no bytes remain to be read in the file and you ask to read bytes, no bytes are returned and the function result is CP_FILE_EOF_ERROR. CPReadFile is appropriate when you are reading data of variable size, in which case you do not want to consider it an error if the end of file is reached before reading all of the bytes that you requested. If you are reading a record of fixed size, use use CPReadFile2 instead of CPReadFile. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPReadFile(CP_FILE_REF fileRef, unsigned long count, void* buffer, unsigned long* numBytesReadPtr) { unsigned long numBytesRead; if (count == 0) { if (numBytesReadPtr != NULL) *numBytesReadPtr = 0; return 0; } clearerr(fileRef); numBytesRead = (DWORD)fread(buffer, 1, count, fileRef); if (numBytesReadPtr != NULL) *numBytesReadPtr = numBytesRead; if (ferror(fileRef)) return CP_FILE_READ_ERROR; if (numBytesRead==0 && CPAtEndOfFile(fileRef)) return CP_FILE_EOF_ERROR; // We were at the end of file when asked to read some bytes. return 0; } /* CPReadFile2(fileRef, count, buffer, numBytesReadPtr) Reads count bytes from the referenced file into the buffer. If numBytesReadPtr is not NULL, stores the number of bytes read in *numBytesReadPtr. Returns 0 if OK or an error code. If bytes remain to be read in the file and you ask to read more bytes than remain, the remaining bytes are returned and the function result is CP_FILE_EOF_ERROR. CPReadFile2 is appropriate when you are reading a record of fixed size, in which case you want to consider it an error if the end of file is reached before reading all of the bytes in the record. If you are reading a record of variable size then you should use CPReadFile instead of CPReadFile2. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPReadFile2(CP_FILE_REF fileRef, unsigned long count, void* buffer, unsigned long* numBytesReadPtr) { unsigned long numBytesRead; if (count == 0) { if (numBytesReadPtr != NULL) *numBytesReadPtr = 0; return 0; } clearerr(fileRef); numBytesRead = (DWORD)fread(buffer, 1, count, fileRef); if (numBytesReadPtr != NULL) *numBytesReadPtr = numBytesRead; if (ferror(fileRef)) return CP_FILE_READ_ERROR; if (numBytesRead < count) { // We did not read all of the bytes requested. if (CPAtEndOfFile(fileRef)) return CP_FILE_EOF_ERROR; // We hit the end of file. return CP_FILE_READ_ERROR; // Some other occurred but ferror did not reflect it. } return 0; } /* CPWriteFile(fileRef, count, buffer, numBytesWrittenPtr) Writes count bytes from the buffer to the referenced file. If numBytesWrittenPtr is not NULL, stores the number of bytes written in *numBytesWrittenPtr. Returns 0 if OK or an error code. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPWriteFile(CP_FILE_REF fileRef, unsigned long count, const void* buffer, unsigned long* numBytesWrittenPtr) { unsigned long numBytesWritten; if (count == 0) { if (numBytesWrittenPtr != NULL) *numBytesWrittenPtr = 0; return 0; } numBytesWritten = (DWORD)fwrite(buffer, 1, count, fileRef); if (numBytesWrittenPtr != NULL) *numBytesWrittenPtr = numBytesWritten; if (numBytesWritten != count) return CP_FILE_WRITE_ERROR; return 0; } /* CPGetFilePosition(fileRef, filePosPtr) Returns via filePosPtr the current file position of the referenced file. Returns 0 if OK or an error code. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPGetFilePosition(CP_FILE_REF fileRef, unsigned long* filePosPtr) { long pos; pos = ftell(fileRef); if (pos == -1L) return CP_FILE_POS_ERROR; *filePosPtr = pos; return 0; } /* CPSetFilePosition(fileRef, filePos, mode) Sets the current file position in the referenced file. If mode is -1, then filePos is relative to the start of the file. If mode is 0, then filePos is relative to the current file position. If mode is 1, then filePos is relative to the end of the file. Returns 0 if OK or an error code. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPSetFilePosition(CP_FILE_REF fileRef, long filePos, int mode) { int seekMode; switch(mode) { case -1: seekMode = SEEK_SET; break; case 0: seekMode = SEEK_CUR; break; case 1: seekMode = SEEK_END; break; default: return CP_FILE_POS_ERROR; } if (fseek(fileRef, filePos, seekMode) != 0) return CP_FILE_POS_ERROR; return 0; } /* CPAtEndOfFile(fileRef) Returns 1 if the current file position is at the end of file, 0 if not. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPAtEndOfFile(CP_FILE_REF fileRef) { if (feof(fileRef)) // Hit end of file? return 1; return 0; } /* CPNumberOfBytesInFile(fileRef, numBytesPtr) Returns via numBytesPtr the total number of bytes in the referenced file. Returns 0 if OK or an error code. Added for Igor Pro 3.13 but works with any version. However, some error codes returned require Igor Pro 3.13 or later, so you will get bogus error messages if you return these error codes to earlier versions of Igor. */ int CPNumberOfBytesInFile(CP_FILE_REF fileRef, unsigned long* numBytesPtr) { long originalPos; originalPos = ftell(fileRef); if (fseek(fileRef, 0, SEEK_END) != 0) return CP_FILE_POS_ERROR; *numBytesPtr = ftell(fileRef); if (*numBytesPtr == -1L) return CP_FILE_POS_ERROR; if (fseek(fileRef, originalPos, SEEK_SET) != 0) return CP_FILE_POS_ERROR; return 0; } stimfit-0.16.7/src/libstfio/igor/igorlib.cpp0000775000175000017500000001570014750344764014470 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Export Igor binary waves from stimfit // last revision: 2007-05-07 // CSH, University of Freiburg // Most of this was shamelessly copied from Wavemetrics' sample code. // Blame them for bugs. /* The code in this file writes a sample Igor Pro packed experiment file. See Igor Pro Tech Note PTN#003 for details. */ #include #include #include #include // For offsetof macro. #include #if !defined(_WINDOWS) || defined(__MINGW32__) #include "../abf/axon/Common/unix.h" #endif #include "./igorlib.h" #include "../recording.h" // Headers taken from Wavemetrics' demo files: #ifdef __cplusplus extern "C" { #endif #include "../igor/IgorBin.h" #include "../igor/CrossPlatformFileIO.h" int WriteVersion5NumericWave(CP_FILE_REF fr, WaveHeader5* whp, const void* data, const char* waveNote, long noteSize); #ifdef __cplusplus } #endif namespace stfio { std::string IGORError(const std::string& msg, int nError); // Check compatibility before exporting: bool CheckComp(const Recording& ReturnData); } std::string stfio::IGORError(const std::string& msg, int error) { std::ostringstream ret; ret << "Error # " << error << " while writing Igor packed experiment:\n" << msg; return ret.str(); } bool stfio::CheckComp(const Recording& Data) { std::size_t oldSize=0; if (!Data.get().empty() && !Data[0].get().empty()) { oldSize=Data[0][0].size(); } else { return false; } for (std::size_t n_c=0;n_c channel_name(Data.size()); bool ident=false; for (std::size_t n_c=0;n_c) Channel TempChannel(Data[n_c]); for (std::size_t n_s=0;n_s cpData.size() || Data[n_c][n_s].size() > TempChannel[n_s].size()) { throw std::out_of_range("Out of range exception in WriteVersion5NumericWave"); } std::copy( TempChannel[n_s].get_w().begin(), TempChannel[n_s].get_w().begin()+Data[n_c][n_s].size(), &cpData[n_s*wh.nDim[0]] ); } err=WriteVersion5NumericWave( fr, &wh, &cpData[0], waveNote.c_str(), (long)waveNote.length() ); if (err) { throw std::runtime_error( std::string(IGORError("Error in WriteVersion5NumericWave()\n", err).c_str()) ); } CPCloseFile(fr); } return true; } stimfit-0.16.7/src/libstfio/igor/WriteWave.c0000775000175000017500000001552314750344764014421 // This file contains an example of writing a wave file. #include #include #include #include #include #include "IgorBin.h" #include "CrossPlatformFileIO.h" /* Checksum(data,oldcksum,numbytes) Returns shortwise simpleminded checksum over the data. ASSUMES data starts on an even boundary. */ static int Checksum(short *data, int oldcksum, int numbytes) { numbytes >>= 1; // 2 bytes to a short -- ignore trailing odd byte. while(numbytes-- > 0) oldcksum += *data++; return oldcksum&0xffff; } /* NumBytesPerPoint(int type) Given a numeric wave type, returns the number of data bytes per point. */ static int NumBytesPerPoint(int type) { int numBytesPerPoint; // Consider the number type, not including the complex bit or the unsigned bit. switch(type & ~(NT_CMPLX | NT_UNSIGNED)) { case NT_I8: numBytesPerPoint = 1; // char break; case NT_I16: numBytesPerPoint = 2; // short break; case NT_I32: numBytesPerPoint = 4; // IGORLONG break; case NT_FP32: numBytesPerPoint = 4; // float break; case NT_FP64: numBytesPerPoint = 8; // double break; default: return 0; break; } if (type & NT_CMPLX) numBytesPerPoint *= 2; // Complex wave - twice as many points. return numBytesPerPoint; } /* WriteVersion2NumericWave(fr, whp, data, waveNote, noteSize) Writes an Igor version 2 binary wave with the properties specified in whp, the data specified by data, and the wave note specified by waveNote and noteSize. Returns 0 or an error code. */ static int WriteVersion2NumericWave(CP_FILE_REF fr, WaveHeader2* whp, const void* data, const char* waveNote, long noteSize) { unsigned long numBytesToWrite; unsigned long numBytesWritten; unsigned long waveDataSize; int numBytesPerPoint; short cksum; BinHeader2 bh; char padding[16]; int err; numBytesPerPoint = NumBytesPerPoint(whp->type); if (numBytesPerPoint <= 0) { printf("Invalid wave type (0x%x).\n", whp->type); return -1; } waveDataSize = whp->npnts * numBytesPerPoint; // Prepare the BinHeader structure. memset(&bh,0,sizeof(struct BinHeader2)); bh.version = 2; bh.wfmSize = offsetof(WaveHeader2, wData) + waveDataSize + 16; // Includes 16 bytes padding. bh.noteSize = noteSize; /* The checksum is over the BinHeader2 structure and the WaveHeader2 structure. The wData field of the WaveHeader2 structure is assumed to contain the same data as the first 16 bytes of the actual wave data. This is necessary to get the correct checksum. */ cksum = Checksum((short *)&bh, 0, sizeof(struct BinHeader2)); cksum = Checksum((short *)whp, cksum, sizeof(struct WaveHeader2)); bh.checksum = -cksum; do { // Write the BinHeader. numBytesToWrite = sizeof(struct BinHeader2); err = CPWriteFile(fr, numBytesToWrite, &bh, &numBytesWritten); if (err) break; // Write the WaveHeader, up to but not including the wData field. numBytesToWrite = offsetof(WaveHeader2, wData); err = CPWriteFile(fr, numBytesToWrite, whp, &numBytesWritten); if (err) break; // Write the wave data. numBytesToWrite = waveDataSize; err = CPWriteFile(fr, numBytesToWrite, data, &numBytesWritten); if (err) break; // Write the 16 byte padding. memset(padding, 0, 16); // Write padding at the end of the wave data. numBytesToWrite = 16; err = CPWriteFile(fr, numBytesToWrite, padding, &numBytesWritten); if (err) break; // Now write optional data, in the correct order. // Write the wave note. numBytesToWrite = noteSize; if (numBytesToWrite > 0) { err = CPWriteFile(fr, numBytesToWrite, waveNote, &numBytesWritten); if (err) break; } } while(0); return err; } /* WriteVersion5NumericWave(fr, whp, data, waveNote, noteSize) Writes an Igor version 5 binary wave with the properties specified in whp, the data specified by data, and the wave note specified by waveNote and noteSize. Returns 0 or an error code. */ int WriteVersion5NumericWave(CP_FILE_REF fr, WaveHeader5* whp, const void* data, const char* waveNote, long noteSize) { unsigned long numBytesToWrite; unsigned long numBytesWritten; unsigned IGORLONG waveDataSize; int numBytesPerPoint; short cksum; BinHeader5 bh; int err; #ifdef _STFDEBUG printf("sizeof(short): %lu\n", sizeof(short)); printf("sizeof(int): %lu\n", sizeof(int)); printf("sizeof(long): %lu\n", sizeof(long)); printf("sizeof(IGORLONG): %lu\n", sizeof(IGORLONG)); printf("sizeof(unsigned long): %lu\n", sizeof(unsigned long)); printf("sizeof(unsigned IGORLONG): %lu\n", sizeof(unsigned IGORLONG)); printf("sizeof(float): %lu\n", sizeof(float)); printf("sizeof(double): %lu\n", sizeof(double)); printf("sizeof(void): %lu\n", sizeof(void)); printf("sizeof(void*): %lu\n", sizeof(void*)); printf("sizeof(void**): %lu\n", sizeof(void**)); #endif numBytesPerPoint = NumBytesPerPoint(whp->type); if (numBytesPerPoint <= 0) { printf("Invalid wave type (0x%x).\n", whp->type); return -1; } waveDataSize = whp->npnts * numBytesPerPoint; // Prepare the BinHeader structure. memset(&bh,0,sizeof(struct BinHeader5)); bh.version = 5; bh.wfmSize = offsetof(WaveHeader5, wData) + waveDataSize; bh.noteSize = noteSize; #ifdef _STFDEBUG printf("waveDataSize: %d\n", waveDataSize); printf("wfmSize: %d\n", bh.wfmSize); printf("noteSize: %d\n", bh.noteSize); #endif /* The checksum is over the BinHeader5 structure and the WaveHeader5 structure, excluding the wData field. */ cksum = Checksum((short *)&bh, 0, sizeof(BinHeader5)); #ifdef _STFDEBUG printf("%d\n", cksum); #endif cksum = Checksum((short *)whp, cksum, offsetof(WaveHeader5, wData)); bh.checksum = -cksum; #ifdef _STFDEBUG printf("%d\n", cksum); printf("%d\n", bh.checksum); #endif do { // Write the BinHeader. numBytesToWrite = sizeof(struct BinHeader5); err = CPWriteFile(fr, numBytesToWrite, &bh, &numBytesWritten); if (err) break; // Write the WaveHeader, up to but not including the wData field. numBytesToWrite = offsetof(WaveHeader5, wData); err = CPWriteFile(fr, numBytesToWrite, whp, &numBytesWritten); if (err) break; // Write the wave data. numBytesToWrite = waveDataSize; err = CPWriteFile(fr, numBytesToWrite, data, &numBytesWritten); if (err) break; // Now write optional data, in the correct order. // Write the wave note. numBytesToWrite = noteSize; if (numBytesToWrite > 0) { err = CPWriteFile(fr, numBytesToWrite, waveNote, &numBytesWritten); if (err) break; } } while(0); return err; } stimfit-0.16.7/src/libstfio/igor/igorlib.h0000775000175000017500000000240614750344764014134 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file igorlib.h * \author Christoph Schmidt-Hieber * \date 2008-01-23 * \brief Export Igor binary waves. */ #ifndef _IGORLIB_H #define _IGORLIB_H #include "./../stfio.h" class Recording; namespace stfio { //! Export a Recording to an Igor binary wave. /*! \param fName Full path to the file to be written. * \param WData The data to be exported. * \return At present, always returns 0. */ StfioDll bool exportIGORFile(const std::string& fName, const Recording& WData, ProgressInfo& progDlg); } #endif stimfit-0.16.7/src/libstfio/igor/CrossPlatformFileIO.h0000775000175000017500000000222014750344764016325 #define CP_FILE_OPEN_ERROR 10000 #define CP_FILE_CLOSE_ERROR 10001 #define CP_FILE_EOF_ERROR 10002 #define CP_FILE_READ_ERROR 10003 #define CP_FILE_WRITE_ERROR 10004 #define CP_FILE_POS_ERROR 10005 #define CP_FILE_REF FILE* #if ( __WORDSIZE == 64 ) || defined (__APPLE__) #define IGORLONG int #else #define IGORLONG long #endif int CPCreateFile(const char* fullFilePath, int overwrite); int CPDeleteFile(const char* fullFilePath); int CPOpenFile(const char* fullFilePath, int readOrWrite, CP_FILE_REF* fileRefPtr); int CPCloseFile(CP_FILE_REF fileRef); int CPReadFile(CP_FILE_REF fileRef, unsigned long count, void* buffer, unsigned long* numBytesReadPtr); int CPReadFile2(CP_FILE_REF fileRef, unsigned long count, void* buffer, unsigned long* numBytesReadPtr); int CPWriteFile(CP_FILE_REF fileRef, unsigned long count, const void* buffer, unsigned long* numBytesWrittenPtr); int CPGetFilePosition(CP_FILE_REF fileRef, unsigned long* filePosPtr); int CPSetFilePosition(CP_FILE_REF fileRef, long filePos, int mode); int CPAtEndOfFile(CP_FILE_REF fileRef); int CPNumberOfBytesInFile(CP_FILE_REF fileRef, unsigned long* numBytesPtr); stimfit-0.16.7/src/libstfio/igor/IgorBin.h0000775000175000017500000002220714750344764014037 // IgorBin.h -- structures and #defines for dealing with Igor binary data. #ifdef __cplusplus extern "C" { #endif // All structures written to disk are 2-byte-aligned. #if GENERATINGPOWERPC #pragma options align=mac68k #endif #define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) #if 1 // def WIN32 #pragma pack(2) #endif #if ( __WORDSIZE == 64 ) || defined (__APPLE__) #define IGORLONG int #else #define IGORLONG long #endif typedef void** Handle; // From IgorMath.h #define NT_CMPLX 1 // Complex numbers. #define NT_FP32 2 // 32 bit fp numbers. #define NT_FP64 4 // 64 bit fp numbers. #define NT_I8 8 // 8 bit signed integer. Requires Igor Pro 2.0 or later. #define NT_I16 0x10 // 16 bit integer numbers. Requires Igor Pro 2.0 or later. #define NT_I32 0x20 // 32 bit integer numbers. Requires Igor Pro 2.0 or later. #define NT_UNSIGNED 0x40 // Makes above signed integers unsigned. Requires Igor Pro 3.0 or later. // From wave.h #define MAXDIMS 4 // From binary.h typedef struct BinHeader1 { short version; // Version number for backwards compatibility. IGORLONG wfmSize; // The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding. short checksum; // Checksum over this header and the wave header. } BinHeader1; typedef struct BinHeader2 { short version; // Version number for backwards compatibility. IGORLONG wfmSize; // The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding. IGORLONG noteSize; // The size of the note text. IGORLONG pictSize; // Reserved. Write zero. Ignore on read. short checksum; // Checksum over this header and the wave header. } BinHeader2; typedef struct BinHeader3 { short version; // Version number for backwards compatibility. IGORLONG wfmSize; // The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding. IGORLONG noteSize; // The size of the note text. IGORLONG formulaSize; // The size of the dependency formula, if any. IGORLONG pictSize; // Reserved. Write zero. Ignore on read. short checksum; // Checksum over this header and the wave header. } BinHeader3; typedef struct BinHeader5 { short version; // Version number for backwards compatibility. short checksum; // Checksum over this header and the wave header. IGORLONG wfmSize; // The size of the WaveHeader5 data structure plus the wave data. IGORLONG formulaSize; // The size of the dependency formula, if any. IGORLONG noteSize; // The size of the note text. IGORLONG dataEUnitsSize; // The size of optional extended data units. IGORLONG dimEUnitsSize[MAXDIMS]; // The size of optional extended dimension units. IGORLONG dimLabelsSize[MAXDIMS]; // The size of optional dimension labels. IGORLONG sIndicesSize; // The size of string indicies if this is a text wave. IGORLONG optionsSize1; // Reserved. Write zero. Ignore on read. IGORLONG optionsSize2; // Reserved. Write zero. Ignore on read. } BinHeader5; // From wave.h #define MAX_WAVE_NAME2 18 // Maximum length of wave name in version 1 and 2 files. Does not include the trailing null. #define MAX_WAVE_NAME5 31 // Maximum length of wave name in version 5 files. Does not include the trailing null. #define MAX_UNIT_CHARS 3 // Header to an array of waveform data. struct WaveHeader2 { short type; // See types (e.g. NT_FP64) above. Zero for text waves. struct WaveHeader2 **next; // Used in memory only. Write zero. Ignore on read. char bname[MAX_WAVE_NAME2+2]; // Name of wave plus trailing null. short whVersion; // Write 0. Ignore on read. short srcFldr; // Used in memory only. Write zero. Ignore on read. Handle fileName; // Used in memory only. Write zero. Ignore on read. char dataUnits[MAX_UNIT_CHARS+1]; // Natural data units go here - null if none. char xUnits[MAX_UNIT_CHARS+1]; // Natural x-axis units go here - null if none. IGORLONG npnts; // Number of data points in wave. short aModified; // Used in memory only. Write zero. Ignore on read. double hsA,hsB; // X value for point p = hsA*p + hsB short wModified; // Used in memory only. Write zero. Ignore on read. short swModified; // Used in memory only. Write zero. Ignore on read. short fsValid; // True if full scale values have meaning. double topFullScale,botFullScale; // The min full scale value for wave. char useBits; // Used in memory only. Write zero. Ignore on read. char kindBits; // Reserved. Write zero. Ignore on read. void **formula; // Used in memory only. Write zero. Ignore on read. IGORLONG depID; // Used in memory only. Write zero. Ignore on read. unsigned IGORLONG creationDate; // DateTime of creation. Not used in version 1 files. char wUnused[2]; // Reserved. Write zero. Ignore on read. unsigned IGORLONG modDate; // DateTime of last modification. Handle waveNoteH; // Used in memory only. Write zero. Ignore on read. float wData[4]; // The start of the array of waveform data. }; typedef struct WaveHeader2 WaveHeader2; typedef WaveHeader2 *WavePtr2; typedef WavePtr2 *waveHandle2; struct WaveHeader5 { #if defined(_WINDOWS) && !defined(__MINGW32__) struct WaveHeader5 **next; // link to next wave in linked list. #else int next; #endif unsigned IGORLONG creationDate; // DateTime of creation. unsigned IGORLONG modDate; // DateTime of last modification. IGORLONG npnts; // Total number of points (multiply dimensions up to first zero). short type; // See types (e.g. NT_FP64) above. Zero for text waves. short dLock; // Reserved. Write zero. Ignore on read. char whpad1[6]; // Reserved. Write zero. Ignore on read. short whVersion; // Write 1. Ignore on read. char bname[MAX_WAVE_NAME5+1]; // Name of wave plus trailing null. IGORLONG whpad2; // Reserved. Write zero. Ignore on read. #if defined(_WINDOWS) && !defined(__MINGW32__) struct DataFolder **dFolder; // Used in memory only. Write zero. Ignore on read. #else int dFolder; // Used in memory only. Write zero. Ignore on read. #endif // Dimensioning info. [0] == rows, [1] == cols etc IGORLONG nDim[MAXDIMS]; // Number of of items in a dimension -- 0 means no data. double sfA[MAXDIMS]; // Index value for element e of dimension d = sfA[d]*e + sfB[d]. double sfB[MAXDIMS]; // SI units char dataUnits[MAX_UNIT_CHARS+1]; // Natural data units go here - null if none. char dimUnits[MAXDIMS][MAX_UNIT_CHARS+1]; // Natural dimension units go here - null if none. short fsValid; // TRUE if full scale values have meaning. short whpad3; // Reserved. Write zero. Ignore on read. double topFullScale,botFullScale; // The max and max full scale value for wave. #if defined(_WINDOWS) && !defined(__MINGW32__) Handle dataEUnits; // Used in memory only. Write zero. Ignore on read. Handle dimEUnits[MAXDIMS]; // Used in memory only. Write zero. Ignore on read. Handle dimLabels[MAXDIMS]; // Used in memory only. Write zero. Ignore on read. Handle waveNoteH; // Used in memory only. Write zero. Ignore on read. #else int dataEUnits; // Used in memory only. Write zero. Ignore on read. int dimEUnits[MAXDIMS]; // Used in memory only. Write zero. Ignore on read. int dimLabels[MAXDIMS]; // Used in memory only. Write zero. Ignore on read. int waveNoteH; // Used in memory only. Write zero. Ignore on read. #endif IGORLONG whUnused[16]; // Reserved. Write zero. Ignore on read. // The following stuff is considered private to Igor. short aModified; // Used in memory only. Write zero. Ignore on read. short wModified; // Used in memory only. Write zero. Ignore on read. short swModified; // Used in memory only. Write zero. Ignore on read. char useBits; // Used in memory only. Write zero. Ignore on read. char kindBits; // Reserved. Write zero. Ignore on read. #if defined(_WINDOWS) && !defined(__MINGW32__) void **formula; // Used in memory only. Write zero. Ignore on read. #else int formula; #endif IGORLONG depID; // Used in memory only. Write zero. Ignore on read. short whpad4; // Reserved. Write zero. Ignore on read. short srcFldr; // Used in memory only. Write zero. Ignore on read. #if defined(_WINDOWS) && !defined(__MINGW32__) Handle fileName; // Used in memory only. Write zero. Ignore on read. IGORLONG **sIndices; // Used in memory only. Write zero. Ignore on read. #else int fileName; // Used in memory only. Write zero. Ignore on read. int sIndices; // Used in memory only. Write zero. Ignore on read. #endif float wData[1]; // The start of the array of data. Must be 64 bit aligned. }; typedef struct WaveHeader5 WaveHeader5; typedef WaveHeader5 *WavePtr5; typedef WavePtr5 *WaveHandle5; #if GENERATINGPOWERPC #pragma options align=reset #endif #if 1 //def WIN32 #pragma pack() #endif // All structures written to disk are 2-byte-aligned. #ifdef __cplusplus } #endif stimfit-0.16.7/src/libstfio/heka/0000775000175000017500000000000014764352501012350 5stimfit-0.16.7/src/libstfio/heka/hekalib.h0000775000175000017500000000334114750344764014053 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file hekalib.h * \author Christoph Schmidt-Hieber * \date 2010-09-19 * \brief Import HEKA files. */ // Parts of this code were inspired by sigTOOL: // http://sigtool.sourceforge.net/ // Original comment for the Matlab file: //-------------------------------------------------------------------------- // Author: Malcolm Lidierth 12/09 // Copyright (c) The Author & King's College London 2009- //-------------------------------------------------------------------------- #ifndef _HEKALIB_H #define _HEKALIB_H #include "./../stfio.h" class Recording; namespace stfio { //! Open an HEKA file and store its contents to a Recording object. /*! \param fName The full path to the file to be opened. * \param ReturnData On entry, an empty Recording object. On exit, * the data stored in \e fName. * \param progress True if the progress dialog should be updated. */ void importHEKAFile(const std::string& fName, Recording& ReturnData, ProgressInfo& progDlg); } #endif stimfit-0.16.7/src/libstfio/heka/hekalib.cpp0000664000175000017500000010026714750344764014410 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file hekalib.cpp * \author Christoph Schmidt-Hieber * \date 2010-09-19 * \brief Import HEKA files. */ // Parts of this code were inspired by sigTOOL: // http://sigtool.sourceforge.net/ // Original comment for the Matlab file: //-------------------------------------------------------------------------- // Author: Malcolm Lidierth 12/09 // Copyright (c) The Author & King's College London 2009- //-------------------------------------------------------------------------- #include #include #include #include #include #include #include #include //required for std::swap #include "./hekalib.h" #include "../recording.h" #define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) #define ByteSwap16(x) ByteSwap((unsigned char *) &x,sizeof(x)) #define ByteSwap32(x) ByteSwap((unsigned char *) &x,sizeof(x)) enum Level { root = 0, group, series, sweep, trace }; Level int2Level(int n) { switch (n) { case root: return root; case group: return group; case series: return series; case sweep: return sweep; case trace: return trace; default: return root; } } struct TreeEntry { TreeEntry(Level l, int c, int i) : level(l), counter(c), idx(i) {} Level level; int counter; int idx; }; // // pack structure on byte boundaries // #ifndef RC_INVOKED #pragma pack(push, 1) #endif struct BundleItem { int oStart; /* INT32 */ int oLength; /* INT32 */ char oExtension[8]; /* ARRAY[0..7] OF CHAR */ }; C_ASSERT(sizeof(BundleItem) == 16); struct BundleHeader { char oSignature[8]; /* 8 ARRAY[0..7] OF CHAR */ char oVersion[32]; /* 40 ARRAY[0..31] OF CHAR */ double oTime; /* 48 LONGREAL */ int oItems; /* 52 INT32 */ char oIsLittleEndian[12]; /* 64 BOOLEAN */ BundleItem oBundleItems[12]; /* 256 ARRAY[0..11] OF BundleItem */ }; C_ASSERT(sizeof(BundleHeader) == 256); struct TraceRecord { int TrMark; /* INT32 */ char TrLabel[32]; /* String32Type */ int TrTraceCount; /* INT32 */ int TrData; /* INT32 */ int TrDataPoints; /* INT32 */ int TrInternalSolution; /* INT32 */ int TrAverageCount; /* INT32 */ int TrLeakCount; /* INT32 */ int TrLeakTraces; /* INT32 */ short TrDataKind; /* SET16 */ short TrFiller1; /* SET16 */ char TrRecordingMode; /* BYTE */ char TrAmplIndex; /* CHAR */ char TrDataFormat; /* BYTE */ char TrDataAbscissa; /* BYTE */ double TrDataScaler; /* LONGREAL */ double TrTimeOffset; /* LONGREAL */ double TrZeroData; /* LONGREAL */ char TrYUnit[8]; /* String8Type */ double TrXInterval; /* LONGREAL */ double TrXStart; /* LONGREAL */ char TrXUnit[8]; /* String8Type */ double TrYRange; /* LONGREAL */ double TrYOffset; /* LONGREAL */ double TrBandwidth; /* LONGREAL */ double TrPipetteResistance; /* LONGREAL */ double TrCellPotential; /* LONGREAL */ double TrSealResistance; /* LONGREAL */ double TrCSlow; /* LONGREAL */ double TrGSeries; /* LONGREAL */ double TrRsValue; /* LONGREAL */ double TrGLeak; /* LONGREAL */ double TrMConductance; /* LONGREAL */ int TrLinkDAChannel; /* INT32 */ char TrValidYrange; /* BOOLEAN */ char TrAdcMode; /* CHAR */ short TrAdcChannel; /* INT16 */ double TrYmin; /* LONGREAL */ double TrYmax; /* LONGREAL */ int TrSourceChannel; /* INT32 */ int TrExternalSolution; /* INT32 */ double TrCM; /* LONGREAL */ double TrGM; /* LONGREAL */ double TrPhase; /* LONGREAL */ int TrDataCRC; /* CARD32 */ int TrCRC; /* CARD32 */ double TrGS; /* LONGREAL */ int TrSelfChannel; /* INT32 */ int TrFiller2; /* SET16 */ }; C_ASSERT(sizeof(TraceRecord) == 296); struct SweepRecord { int SwMark; /* INT32 */ char SwLabel[32]; /* String32Type */ int SwAuxDataFileOffset; /* INT32 */ int SwStimCount; /* INT32 */ int SwSweepCount; /* INT32 */ double SwTime; /* LONGREAL */ double SwTimer; /* LONGREAL */ double SwSwUserParams[4]; /* ARRAY[0..3] OF LONGREAL */ double SwTemperature; /* LONGREAL */ int SwOldIntSol; /* INT32 */ int SwOldExtSol; /* INT32 */ short SwDigitalIn; /* SET16 */ short SwSweepKind; /* SET16 */ int SwFiller1; /* INT32 */ double SwMarkers[4]; /* ARRAY[0..3] OF LONGREAL */ int SwFiller2; /* INT32 */ int SwCRC; /* CARD32 */ }; C_ASSERT(sizeof(SweepRecord) == 160); struct UserParamDescrType { char Name[32]; char Unit[8]; }; C_ASSERT(sizeof(UserParamDescrType) == 40); struct AmplifierState { char E9StateVersion[8]; /* 8 = SizeStateVersion */ double E9RealCurrentGain; /* LONGREAL */ double E9RealF2Bandwidth; /* LONGREAL */ double E9F2Frequency; /* LONGREAL */ double E9RsValue; /* LONGREAL */ double E9RsFraction; /* LONGREAL */ double E9GLeak; /* LONGREAL */ double E9CFastAmp1; /* LONGREAL */ double E9CFastAmp2; /* LONGREAL */ double E9CFastTau; /* LONGREAL */ double E9CSlow ; /* LONGREAL */ double E9GSeries ; /* LONGREAL */ double E9StimDacScale ; /* LONGREAL */ double E9CCStimScale ; /* LONGREAL */ double E9VHold ; /* LONGREAL */ double E9LastVHold ; /* LONGREAL */ double E9VpOffset ; /* LONGREAL */ double E9VLiquidJunction ; /* LONGREAL */ double E9CCIHold ; /* LONGREAL */ double E9CSlowStimVolts ; /* LONGREAL */ double E9CCTrackVHold ; /* LONGREAL */ double E9TimeoutLength ; /* LONGREAL */ double E9SearchDelay ; /* LONGREAL */ double E9MConductance ; /* LONGREAL */ double E9MCapacitance ; /* LONGREAL */ char E9SerialNumber[8] ; /* 8 = SizeSerialNumber */ short E9E9Boards ; /* INT16 */ short E9CSlowCycles ; /* INT16 */ short E9IMonAdc ; /* INT16 */ short E9VMonAdc ; /* INT16 */ short E9MuxAdc ; /* INT16 */ short E9TstDac ; /* INT16 */ short E9StimDac ; /* INT16 */ short E9StimDacOffset ; /* INT16 */ short E9MaxDigitalBit ; /* INT16 */ short E9SpareInt1 ; /* INT16 */ short E9SpareInt2 ; /* INT16 */ short E9SpareInt3 ; /* INT16 */ char E9AmplKind ; /* BYTE */ char E9IsEpc9N ; /* BYTE */ char E9ADBoard ; /* BYTE */ char E9BoardVersion ; /* BYTE */ char E9ActiveE9Board ; /* BYTE */ char E9Mode ; /* BYTE */ char E9Range ; /* BYTE */ char E9F2Response ; /* BYTE */ char E9RsOn ; /* BYTE */ char E9CSlowRange ; /* BYTE */ char E9CCRange ; /* BYTE */ char E9CCGain ; /* BYTE */ char E9CSlowToTstDac ; /* BYTE */ char E9StimPath ; /* BYTE */ char E9CCTrackTau ; /* BYTE */ char E9WasClipping ; /* BYTE */ char E9RepetitiveCSlow ; /* BYTE */ char E9LastCSlowRange ; /* BYTE */ char E9Locked ; /* BYTE */ char E9CanCCFast ; /* BYTE */ char E9CanLowCCRange ; /* BYTE */ char E9CanHighCCRange ; /* BYTE */ char E9CanCCTracking ; /* BYTE */ char E9HasVmonPath ; /* BYTE */ char E9HasNewCCMode ; /* BYTE */ char E9Selector ; /* CHAR */ char E9HoldInverted ; /* BYTE */ char E9AutoCFast ; /* BYTE */ char E9AutoCSlow ; /* BYTE */ char E9HasVmonX100 ; /* BYTE */ char E9TestDacOn ; /* BYTE */ char E9QMuxAdcOn ; /* BYTE */ double E9RealImon1Bandwidth ; /* LONGREAL */ double E9StimScale ; /* LONGREAL */ char E9Gain ; /* BYTE */ char E9Filter1 ; /* BYTE */ char E9StimFilterOn ; /* BYTE */ char E9RsSlow ; /* BYTE */ char E9Old1 ; /* BYTE */ char E9CCCFastOn ; /* BYTE */ char E9CCFastSpeed ; /* BYTE */ char E9F2Source ; /* BYTE */ char E9TestRange ; /* BYTE */ char E9TestDacPath ; /* BYTE */ char E9MuxChannel ; /* BYTE */ char E9MuxGain64 ; /* BYTE */ char E9VmonX100 ; /* BYTE */ char E9IsQuadro ; /* BYTE */ char E9SpareBool4 ; /* BYTE */ char E9SpareBool5 ; /* BYTE */ double E9StimFilterHz ; /* LONGREAL */ double E9RsTau ; /* LONGREAL */ short E9FilterOffsetDac ; /* INT16 */ short E9ReferenceDac ; /* INT16 */ short E9SpareInt6 ; /* INT16 */ short E9SpareInt7 ; /* INT16 */ char E9Spares1[24] ; char E9CalibDate[16]; /* 16 = SizeCalibDate */ double E9SelHold; /* LONGREAL */ char E9Spares2[32]; /* remaining */ }; C_ASSERT(sizeof(AmplifierState) == 400); struct LockInParams { /* see definition in AmplTreeFile_v9.txt */ double loExtCalPhase ; /* LONGREAL */ double loExtCalAtten ; /* LONGREAL */ double loPLPhase ; /* LONGREAL */ double loPLPhaseY1 ; /* LONGREAL */ double loPLPhaseY2 ; /* LONGREAL */ double loUsedPhaseShift ; /* LONGREAL */ double loUsedAttenuation ; /* LONGREAL */ char loSpares2[8] ; char loExtCalValid ; /* BOOLEAN */ char loPLPhaseValid ; /* BOOLEAN */ char loLockInMode ; /* BYTE */ char loCalMode ; /* BYTE */ char loSpares[28] ; /* remaining */ }; C_ASSERT(sizeof(LockInParams) == 96); struct SeriesRecord { int SeMark; /* INT32 */ char SeLabel[32]; /* String32Type */ char SeComment[80]; /* String80Type */ int SeSeriesCount; /* INT32 */ int SeNumberSweeps; /* INT32 */ int SeAmplStateOffset; /* INT32 */ int SeAmplStateSeries; /* INT32 */ char SeSeriesType; /* BYTE */ char SeFiller1; /* BYTE */ char SeFiller2; /* BYTE */ char SeFiller3; /* BYTE */ double SeTime; /* LONGREAL */ double SePageWidth; /* LONGREAL */ UserParamDescrType SeSwUserParamDescr[4]; /* ARRAY[0..3] OF UserParamDescrType = 4*40 */ char SeFiller4[32]; /* 32 BYTE */ double SeSeUserParams[4]; /* ARRAY[0..3] OF LONGREAL */ LockInParams SeLockInParams; /* SeLockInSize = 96, see "Pulsed.de" */ AmplifierState SeAmplifierState; /* AmplifierStateSize = 400 */ char SeUsername[80]; /* String80Type */ UserParamDescrType SeSeUserParamDescr[4]; /* ARRAY[0..3] OF UserParamDescrType = 4*40 */ int SeFiller5; /* INT32 */ int SeCRC; /* CARD32 */ }; C_ASSERT(sizeof(SeriesRecord) == 1120); struct GroupRecord { int GrMark; /* INT32 */ char GrLabel[32]; /* String32Size */ char GrText[80]; /* String80Size */ int GrExperimentNumber; /* INT32 */ int GrGroupCount ; /* INT32 */ int GrCRC ; /* CARD32 */ }; C_ASSERT(sizeof(GroupRecord) == 128); struct RootRecord { /* NOTE: The "Version" field must be at offset zero in the file while the "Mark" field must be at offset zero in RAM! */ int RoVersion ; /* INT32 */ int RoMark ; /* INT32 */ char RoVersionName[32]; /* String32Type */ char RoAuxFileName[80] ; /* String80Type */ char RoRootText[400] ; /* String400Type */ double RoStartTime ; /* LONGREAL */ int RoMaxSamples ; /* INT32 */ int RoCRC ; /* CARD32 */ short RoFeatures ; /* SET16 */ short RoFiller1 ; /* INT16 */ int RoFiller2 ; /* INT32 */ }; C_ASSERT(sizeof(RootRecord) == 544); #ifndef RC_INVOKED #pragma pack(pop) // return to default packing #endif struct Tree { std::vector RootList; std::vector GroupList; std::vector SeriesList; std::vector SweepList; std::vector TraceList; std::vector entries; bool needsByteSwap; }; void printHeader(const BundleHeader& header) { std::cout << header.oSignature << std::endl; std::string strsig(header.oSignature); if (strsig == "DATA") { throw std::runtime_error("DATA file format not supported at present"); } else if (strsig=="DAT1" || strsig=="DAT2") { // Newer format std::cout << header.oVersion << std::endl; std::cout << header.oTime << std::endl; std::cout << header.oItems << std::endl; std::cout << int(header.oIsLittleEndian[0]) << std::endl; if (strsig=="DAT1") { } else { // "DAT2" for (int k=0; k<12; ++k) { std::cout << header.oBundleItems[k].oStart << std::endl << header.oBundleItems[k].oLength << std::endl << header.oBundleItems[k].oExtension << std::endl; } } } } void ByteSwap(unsigned char * b, int n) { int i = 0; int j = n-1; while (i> 8) | (*uShort << 8)); } void ByteSwap32(void* ptr32) { unsigned int *uInt = (unsigned int *)ptr32; *uInt = (((*uInt & 0x000000FF)<<24) + ((*uInt & 0x0000FF00)<<8) + ((*uInt & 0x00FF0000)>>8) + ((*uInt & 0xFF000000)>>24)); } #endif void ShortByteSwap(short& s) { ByteSwap((unsigned char *) &s,sizeof(s)); } void FloatByteSwap(float& s) { ByteSwap((unsigned char *) &s,sizeof(s)); } void IntByteSwap(int& s) { ByteSwap((unsigned char *) &s,sizeof(s)); } void DoubleByteSwap(double& s) { ByteSwap((unsigned char *) &s,sizeof(s)); } void SwapItem(BundleItem& item) { ByteSwap32(item.oStart); ByteSwap32(item.oLength); } void SwapHeader(BundleHeader& header) { std::string strsig(header.oSignature); if (strsig == "DATA") { throw std::runtime_error("DATA file format not supported at present"); } else if (strsig=="DAT1" || strsig=="DAT2") { // Newer format ByteSwap32(header.oTime); ByteSwap32(header.oItems); if (strsig=="DAT1") { } else { // "DAT2" for (int k=0; k<12; ++k) { SwapItem(header.oBundleItems[k]); } } } } void SwapRoot(RootRecord& root) { ByteSwap32(root.RoVersion); ByteSwap32(root.RoMark); ByteSwap32(root.RoStartTime); ByteSwap32(root.RoMaxSamples); ByteSwap32(root.RoCRC); ByteSwap16(root.RoFeatures); ByteSwap16(root.RoFiller1); ByteSwap32(root.RoFiller2); } void SwapGroup(GroupRecord& group) { ByteSwap32(group.GrMark); /* INT32 */ ByteSwap32(group.GrExperimentNumber); /* INT32 */ ByteSwap32(group.GrGroupCount ); /* INT32 */ ByteSwap32(group.GrCRC ); /* CARD32 */ } void SwapSeries(SeriesRecord& series) { ByteSwap32(series.SeMark); /* INT32 */ ByteSwap32(series.SeSeriesCount); /* INT32 */ ByteSwap32(series.SeNumberSweeps); /* INT32 */ ByteSwap32(series.SeAmplStateOffset); /* INT32 */ ByteSwap32(series.SeAmplStateSeries); /* INT32 */ ByteSwap32(series.SeTime); /* LONGREAL */ ByteSwap32(series.SePageWidth); /* LONGREAL */ // TODO UserParamDescrType SeSwUserParamDescr[4]); /* ARRAY[0..3] OF UserParamDescrType = 4*40 */ // TODO SeSeUserParams[4]); /* ARRAY[0..3] OF LONGREAL */ // TODO LockInParams SeLockInParams); /* SeLockInSize = 96, see "Pulsed.de" */ // TODO AmplifierState SeAmplifierState); /* AmplifierStateSize = 400 */ // TODO UserParamDescrType SeSeUserParamDescr[4]); /* ARRAY[0..3] OF UserParamDescrType = 4*40 */ ByteSwap32(series.SeFiller5); /* INT32 */ ByteSwap32(series.SeCRC); /* CARD32 */ } void SwapSweep(SweepRecord& sweep) { ByteSwap32(sweep.SwMark); /* INT32 */ ByteSwap32(sweep.SwAuxDataFileOffset); /* INT32 */ ByteSwap32(sweep.SwStimCount); /* INT32 */ ByteSwap32(sweep.SwSweepCount); /* INT32 */ ByteSwap32(sweep.SwTime); /* LONGREAL */ ByteSwap32(sweep.SwTimer); /* LONGREAL */ // TODO SwSwUserParams[4]); /* ARRAY[0..3] OF LONGREAL */ ByteSwap32(sweep.SwTemperature); /* LONGREAL */ ByteSwap32(sweep.SwOldIntSol); /* INT32 */ ByteSwap32(sweep.SwOldExtSol); /* INT32 */ ByteSwap16(sweep.SwDigitalIn); /* SET16 */ ByteSwap16(sweep.SwSweepKind); /* SET16 */ ByteSwap32(sweep.SwFiller1); /* INT32 */ // TODO ByteSwap32(sweep.SwMarkers[4]); /* ARRAY[0..3] OF LONGREAL */ ByteSwap32(sweep.SwFiller2); /* INT32 */ ByteSwap32(sweep.SwCRC); /* CARD32 */ } void SwapTrace(TraceRecord& trace) { ByteSwap32(trace.TrMark); /* INT32 */ ByteSwap32(trace.TrTraceCount); /* INT32 */ ByteSwap32(trace.TrData); /* INT32 */ ByteSwap32(trace.TrDataPoints); /* INT32 */ ByteSwap32(trace.TrInternalSolution); /* INT32 */ ByteSwap32(trace.TrAverageCount); /* INT32 */ ByteSwap32(trace.TrLeakCount); /* INT32 */ ByteSwap32(trace.TrLeakTraces); /* INT32 */ ByteSwap16(trace.TrDataKind); /* SET16 */ ByteSwap16(trace.TrFiller1); /* SET16 */ ByteSwap32(trace.TrDataScaler); /* LONGREAL */ ByteSwap32(trace.TrTimeOffset); /* LONGREAL */ ByteSwap32(trace.TrZeroData); /* LONGREAL */ ByteSwap32(trace.TrXInterval); /* LONGREAL */ ByteSwap32(trace.TrXStart); /* LONGREAL */ ByteSwap32(trace.TrYRange); /* LONGREAL */ ByteSwap32(trace.TrYOffset); /* LONGREAL */ ByteSwap32(trace.TrBandwidth); /* LONGREAL */ ByteSwap32(trace.TrPipetteResistance); /* LONGREAL */ ByteSwap32(trace.TrCellPotential); /* LONGREAL */ ByteSwap32(trace.TrSealResistance); /* LONGREAL */ ByteSwap32(trace.TrCSlow); /* LONGREAL */ ByteSwap32(trace.TrGSeries); /* LONGREAL */ ByteSwap32(trace.TrRsValue); /* LONGREAL */ ByteSwap32(trace.TrGLeak); /* LONGREAL */ ByteSwap32(trace.TrMConductance); /* LONGREAL */ ByteSwap32(trace.TrLinkDAChannel); /* INT32 */ ByteSwap16(trace.TrAdcChannel); /* INT16 */ ByteSwap32(trace.TrYmin); /* LONGREAL */ ByteSwap32(trace.TrYmax); /* LONGREAL */ ByteSwap32(trace.TrSourceChannel); /* INT32 */ ByteSwap32(trace.TrExternalSolution); /* INT32 */ ByteSwap32(trace.TrCM); /* LONGREAL */ ByteSwap32(trace.TrGM); /* LONGREAL */ ByteSwap32(trace.TrPhase); /* LONGREAL */ ByteSwap32(trace.TrDataCRC); /* CARD32 */ ByteSwap32(trace.TrCRC); /* CARD32 */ ByteSwap32(trace.TrGS); /* LONGREAL */ ByteSwap32(trace.TrSelfChannel); /* INT32 */ ByteSwap32(trace.TrFiller2); /* SET16 */ } BundleHeader getBundleHeader(FILE* fh) { BundleHeader header; int res = 0; /* res = */ fseek(fh, 0, SEEK_SET); res = fread(&header, sizeof(BundleHeader), 1, fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); return header; } RootRecord getRoot(FILE* fh, bool needsByteSwap) { int res = 0; RootRecord rec; res = fread(&rec, sizeof(RootRecord), 1, fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); if (needsByteSwap) { SwapRoot(rec); } return rec; } GroupRecord getGroup(FILE* fh, bool needsByteSwap) { int res = 0; GroupRecord rec; res = fread(&rec, sizeof(GroupRecord), 1, fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); if (needsByteSwap) { SwapGroup(rec); } return rec; } SeriesRecord getSeries(FILE* fh, bool needsByteSwap) { int res = 0; SeriesRecord rec; res = fread(&rec, sizeof(SeriesRecord), 1, fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); if (needsByteSwap) { SwapSeries(rec); } return rec; } SweepRecord getSweep(FILE* fh, bool needsByteSwap) { int res = 0; SweepRecord rec; res = fread(&rec, sizeof(SweepRecord), 1, fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); if (needsByteSwap) { SwapSweep(rec); } return rec; } TraceRecord getTrace(FILE* fh, bool needsByteSwap) { int res = 0; TraceRecord rec; res = fread(&rec, sizeof(TraceRecord), 1, fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); if (needsByteSwap) { SwapTrace(rec); } return rec; } int findExt(const BundleHeader& header, const std::string& ext) { int extNo = -1; for (int k=0; k<12; ++k) { if (header.oBundleItems[k].oExtension == ext) { extNo = k; } } return extNo; } void getOneRecord(FILE* fh, Level level, Tree& TreeInOut, int& CounterInOut) { // Gets one record int idx = -1; switch (level) { case root: idx = TreeInOut.RootList.size(); TreeInOut.RootList.push_back(getRoot(fh, TreeInOut.needsByteSwap)); break; case group: idx = TreeInOut.GroupList.size(); TreeInOut.GroupList.push_back(getGroup(fh, TreeInOut.needsByteSwap)); break; case series: idx = TreeInOut.SeriesList.size(); TreeInOut.SeriesList.push_back(getSeries(fh, TreeInOut.needsByteSwap)); break; case sweep: idx = TreeInOut.SweepList.size(); TreeInOut.SweepList.push_back(getSweep(fh, TreeInOut.needsByteSwap)); break; case trace: idx = TreeInOut.TraceList.size(); TreeInOut.TraceList.push_back(getTrace(fh, TreeInOut.needsByteSwap)); break; default: throw std::runtime_error("Couldn't read record"); } TreeInOut.entries.push_back(TreeEntry(level, CounterInOut, idx)); CounterInOut++; } int getOneLevel(FILE* fh, const std::vector& Sizes, Level level, Tree& TreeInOut, int& PositionInOut, int& CounterInOut) { // Gets one record of the tree and the number of children getOneRecord(fh, level, TreeInOut, CounterInOut); PositionInOut += Sizes[level]; fseek(fh, PositionInOut, SEEK_SET); int nchild = 0; int res = 0; res = fread(&nchild, sizeof(int), 1, fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); if (TreeInOut.needsByteSwap) { ByteSwap32(nchild); } PositionInOut = ftell(fh); return nchild; } void getTreeReentrant(FILE* fh, const std::vector& Sizes, Level level, Tree& TreeInOut, int& PositionInOut, int& CounterInOut) { // Recursive routine called from LoadTree int nchild = getOneLevel(fh, Sizes, level, TreeInOut, PositionInOut, CounterInOut); for (int k=0; k& Sizes, int& PositionInOut, bool needsByteSwap) { Tree tree; tree.needsByteSwap = needsByteSwap; // Main entry point for loading tree int Counter = 0; getTreeReentrant(fh, Sizes, int2Level(0), tree, PositionInOut, Counter); return tree; } std::string time2date(double t) { long time = (long)t - 0; // 1580970496; if (time<0) { time += 0; //4294967296; } time += 0; // 9561652096; time_t timer(time); std::string datestr(ctime(&timer)); return datestr; } void ReadData(FILE* fh, const Tree& tree, Recording& RecordingInOut, stfio::ProgressInfo& progDlg) { int nsweeps = tree.SweepList.size(); int ntraces = tree.TraceList.size(); int nchannels = ntraces/nsweeps; RecordingInOut.resize(nchannels); int res = 0; for (int nc=0; nc tmpSection(npoints); res = fread(&tmpSection[0], sizeof(short), npoints, fh); if (res != npoints) throw std::runtime_error("getBundleHeader: Error in fread()"); if (tree.needsByteSwap) std::for_each(tmpSection.begin(), tmpSection.end(), ShortByteSwap); std::copy(tmpSection.begin(), tmpSection.end(), RecordingInOut[nc][ns].get_w().begin()); break; } case 1: { /*int32*/ std::vector tmpSection(npoints); res = fread(&tmpSection[0], sizeof(int), npoints, fh); if (res != npoints) throw std::runtime_error("getBundleHeader: Error in fread()"); if (tree.needsByteSwap) std::for_each(tmpSection.begin(), tmpSection.end(), IntByteSwap); std::copy(tmpSection.begin(), tmpSection.end(), RecordingInOut[nc][ns].get_w().begin()); break; } case 2: { /*double16*/ std::vector tmpSection(npoints); res = fread(&tmpSection[0], sizeof(float), npoints, fh); if (res != npoints) throw std::runtime_error("getBundleHeader: Error in fread()"); if (tree.needsByteSwap) std::for_each(tmpSection.begin(), tmpSection.end(), FloatByteSwap); std::copy(tmpSection.begin(), tmpSection.end(), RecordingInOut[nc][ns].get_w().begin()); break; } case 3: { /*double32*/ std::vector tmpSection(npoints); res = fread(&tmpSection[0], sizeof(double), npoints, fh); if (res != npoints) throw std::runtime_error("getBundleHeader: Error in fread()"); if (tree.needsByteSwap) std::for_each(tmpSection.begin(), tmpSection.end(), DoubleByteSwap); std::copy(tmpSection.begin(), tmpSection.end(), RecordingInOut[nc][ns].get_w().begin()); break; } default: throw std::runtime_error("Unknown data format while reading heka file"); } double factor = 1.0; if (std::string(tree.TraceList[nc].TrYUnit) == "V") { RecordingInOut[nc].SetYUnits("mV"); factor = 1.0e3; } else if (std::string(tree.TraceList[nc].TrYUnit) == "A") { RecordingInOut[nc].SetYUnits("pA"); factor = 1.0e12; } else { RecordingInOut[nc].SetYUnits(tree.TraceList[nc].TrYUnit); } factor *= tree.TraceList[nc].TrDataScaler; RecordingInOut[nc][ns].get_w() = stfio::vec_scal_mul(RecordingInOut[nc][ns].get(), factor); RecordingInOut[nc][ns].get_w() = stfio::vec_scal_plus(RecordingInOut[nc][ns].get(), tree.TraceList[nc].TrZeroData); } RecordingInOut[nc].SetChannelName(tree.TraceList[nc].TrLabel); } double tsc = 1.0; std::string xunits(tree.TraceList[0].TrXUnit); if (xunits == "s") { tsc=1.0e3; } else if (xunits == "ms") { tsc=1.0; } else if (xunits == "µs") { tsc=1.0e-3; } else { throw std::runtime_error("Unsupported time units"); } RecordingInOut.SetXScale(tree.TraceList[0].TrXInterval*tsc); } void stfio::importHEKAFile(const std::string &fName, Recording &ReturnData, ProgressInfo& progDlg) { std::string warnStr("Warning: HEKA support is experimental.\n" \ "Please check sampling rate and report errors to\nchristsc_at_gmx.de." ); progDlg.Update(0, warnStr); std::string errorMsg("Exception while calling importHEKAFile():\n"); std::string yunits; int res = 0; // Open file FILE* dat_fh = fopen(fName.c_str(), "rb"); if (dat_fh==NULL) { return; } BundleHeader header = getBundleHeader(dat_fh); bool needsByteSwap = (int(header.oIsLittleEndian[0]) == 0); if (needsByteSwap) { SwapHeader(header); } int start = 0; bool isBundled = false; if (std::string(header.oSignature)=="DAT2") { // find the pulse data isBundled = true; int extNo = findExt(header, ".pul"); if (extNo < 0) { throw std::runtime_error("Couldn't find .pul file in bundle"); } start = header.oBundleItems[extNo].oStart; } else { throw std::runtime_error("Can only deal with bundled data at present"); } // Base of tree fseek(dat_fh, start, SEEK_SET); char cMagic[4]; res = fread(&cMagic[0], sizeof(char), 4, dat_fh); if (res != 4) throw std::runtime_error("getBundleHeader: Error in fread()"); std::string magic(cMagic); int levels = 0; res = fread(&levels, sizeof(int), 1, dat_fh); if (res != 1) throw std::runtime_error("getBundleHeader: Error in fread()"); if (needsByteSwap) { ByteSwap32(levels); } std::vector sizes(levels); if (levels!=0) res = fread(&sizes[0], sizeof(int), levels, dat_fh); if (needsByteSwap) std::for_each(sizes.begin(), sizes.end(), IntByteSwap); // Get the tree from the pulse file int pos = ftell(dat_fh); Tree tree = getTree(dat_fh, sizes, pos, needsByteSwap); std::string date = ""; //time2date(tree.RootList[0].RoStartTime); if (isBundled) { // find the data int extNo = findExt(header, ".dat"); if (extNo < 0) { throw std::runtime_error("Couldn't find .dat file in bundle"); } start = header.oBundleItems[extNo].oStart; } else { throw std::runtime_error("Can only deal with bundled data at present"); } // Now set pointer to the start of the data fseek(dat_fh, start, SEEK_SET); // NOW IMPORT ReadData(dat_fh, tree, ReturnData, progDlg); // Close file fclose(dat_fh); } stimfit-0.16.7/src/libstfio/intan/0000775000175000017500000000000014764352501012551 5stimfit-0.16.7/src/libstfio/intan/intanlib.h0000664000175000017500000000735214750344764014460 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file intanlib.h * \author Christoph Schmidt-Hieber * \date 2017-03-11 * \brief Reads Intan Technologies CLAMP data file generated by controller GUI. */ /* Mostly a Python version of read_Intan_CLP_file.m from http://www.intantech.com/files/Intan_CLAMP_software_compiled_v1_0.zip as of 2016-11-05 Example: >>> import matplotlib.pyplot as plt >>> import intan >>> intan_file = intan.IntanFile('myexperiment_A_160916_142731.clp') >>> plt.plot(intan_file.data["Time"], intan_file.data["Measured"]) >>> intan_file = intan.IntanFile('myexperiment_AUX_160916_142731.clp') >>> plt.plot(intan_file.data["Time"], intan_file.data["ADC"][1]) */ #ifndef INTANLIB_H #define INTANLIB_H #if __cplusplus > 199711L #include #else #include #endif #include "./../stfio.h" #ifdef _MSC_VER typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; #endif class Recording; static const int MAX_REGISTERS = 14; static const uint32_t MAGIC_NUMBER = 0xf3b1a481; struct Segment { uint8_t waveformNumber; uint32_t tOffset; uint32_t startIndex; uint32_t endIndex; float appliedValue; }; struct VoltageClampSettings { float holdingVoltage; float nominalResistance; float resistance; float desiredBandwidth; float actualBandwidth; }; struct CurrentClampSettings { float holdingCurrent; float currentStepSize; }; struct HeaderSettings { uint8_t enableCapacitiveCompensation; float capCompensationMagnitude; float filterCutoff; float pipetteOffset; float samplingRate; float cellRs; float cellRm; float cellCm; uint8_t isVoltageClamp; uint8_t vClampX2Mode; VoltageClampSettings vcSettings; CurrentClampSettings ccSettings; std::vector waveform; }; struct Calibration { uint8_t coarse; uint8_t fine; }; struct ChannelHeader { uint16_t registers[MAX_REGISTERS]; uint32_t differenceAmpResidual; uint32_t voltageAmpResidual; Calibration bestCalibration[2][4]; float rFeedback[5]; float desiredBandwidth; }; struct ChipHeader { std::vector channels; uint16_t chipRegisters[4]; }; struct IntanHeader { int16_t version_major; int16_t version_minor; int16_t datatype; int16_t date_Year; int16_t date_Month; int16_t date_Day; int16_t date_Hour; int16_t date_Minute; int16_t date_Second; std::vector Chips; HeaderSettings Settings; uint16_t numADCs; }; namespace stfio { //! Open an Intan file and store its contents to a Recording object. /*! \param fName The full path to the file to be opened. * \param ReturnData On entry, an empty Recording object. On exit, * the data stored in \e fName. * \param progress True if the progress dialog should be updated. */ void importIntanFile(const std::string &fName, Recording &ReturnData, ProgressInfo& progDlg); } #endifstimfit-0.16.7/src/libstfio/intan/intanlib.cpp0000664000175000017500000002471114752207205014777 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file hekalib.cpp * \author Christoph Schmidt-Hieber * \date 2017-03-11 * \brief Reads Intan Technologies CLAMP data file generated by controller GUI. */ /* Mostly a C++ version of read_Intan_CLP_file.m from http://www.intantech.com/files/Intan_CLAMP_software_compiled_v1_0.zip as of 2016-11-05 */ #include #include "intanlib.h" #include "streams.h" #include "../recording.h" Segment read_segment(BinaryReader& binreader) { Segment segment; binreader >> segment.waveformNumber; binreader >> segment.tOffset; binreader >> segment.startIndex; binreader >> segment.endIndex; binreader >> segment.appliedValue; return segment; } std::vector read_waveform(BinaryReader& binreader) { float interval; binreader >> interval; uint16_t numSegments; binreader >> numSegments; std::vector waveform(numSegments); for (std::vector::size_type nseg=0; nseg < waveform.size(); ++nseg) { waveform[nseg] = read_segment(binreader); } return waveform; } VoltageClampSettings read_header_voltage_clamp_settings(BinaryReader& binreader) { VoltageClampSettings vcSettings; binreader >> vcSettings.holdingVoltage; binreader >> vcSettings.nominalResistance; binreader >> vcSettings.resistance; binreader >> vcSettings.desiredBandwidth; binreader >> vcSettings.actualBandwidth; return vcSettings; } CurrentClampSettings read_header_current_clamp_settings(BinaryReader& binreader) { CurrentClampSettings ccSettings; binreader >> ccSettings.holdingCurrent; binreader >> ccSettings.currentStepSize; return ccSettings; } HeaderSettings read_header_settings(BinaryReader& binreader) { HeaderSettings hSettings; binreader >> hSettings.enableCapacitiveCompensation; binreader >> hSettings.capCompensationMagnitude; binreader >> hSettings.filterCutoff; binreader >> hSettings.pipetteOffset; binreader >> hSettings.samplingRate; binreader >> hSettings.cellRs; binreader >> hSettings.cellRm; binreader >> hSettings.cellCm; binreader >> hSettings.isVoltageClamp; binreader >> hSettings.vClampX2Mode; if (hSettings.isVoltageClamp > 0) { hSettings.vcSettings = read_header_voltage_clamp_settings(binreader); } else { hSettings.ccSettings = read_header_current_clamp_settings(binreader); } hSettings.waveform = read_waveform(binreader); return hSettings; } ChannelHeader read_one_header_channel(BinaryReader& binreader) { ChannelHeader hChannel; for (unsigned int registerIndex = 0; registerIndex < MAX_REGISTERS; ++registerIndex) { binreader >> hChannel.registers[registerIndex]; } binreader >> hChannel.differenceAmpResidual; binreader >> hChannel.voltageAmpResidual; for (unsigned int a = 0; a < 2; a++) { for (unsigned int b = 0; b < 4; b++) { binreader >> hChannel.bestCalibration[a][b].coarse; binreader >> hChannel.bestCalibration[a][b].fine; } } for (unsigned int rIndex = 0; rIndex < 5; ++rIndex) { binreader >> hChannel.rFeedback[rIndex]; } binreader >> hChannel.desiredBandwidth; return hChannel; } ChipHeader read_one_header_chip(BinaryReader& binreader, unsigned int numChannels) { ChipHeader hChip; hChip.channels.resize(numChannels); for (unsigned int nchan = 0; nchan < numChannels; ++nchan) { hChip.channels[nchan] = read_one_header_channel(binreader); } for (unsigned int nreg = 0; nreg < 4; ++nreg) { binreader >> hChip.chipRegisters[nreg]; } return hChip; } std::vector read_header_chips(BinaryReader& binreader) { uint16_t numChips, numChannels; binreader >> numChips; binreader >> numChannels; std::vector hChips(numChips); for (unsigned int nchip = 0; nchip < hChips.size(); ++nchip) { hChips[nchip] = read_one_header_chip(binreader, numChannels); } return hChips; } IntanHeader read_header(BinaryReader& binreader) { uint32_t magic_number; binreader >> magic_number; if (magic_number != MAGIC_NUMBER) { throw std::runtime_error("Unrecognized file type"); } IntanHeader hIntan; binreader >> hIntan.version_major; binreader >> hIntan.version_minor; binreader >> hIntan.datatype; uint16_t numBytes = 0; switch (hIntan.datatype) { case 0: binreader >> numBytes; binreader >> hIntan.date_Year; binreader >> hIntan.date_Month; binreader >> hIntan.date_Day; binreader >> hIntan.date_Hour; binreader >> hIntan.date_Minute; binreader >> hIntan.date_Second; hIntan.Chips = read_header_chips(binreader); hIntan.Settings = read_header_settings(binreader); break; case 1: binreader >> hIntan.numADCs; binreader >> numBytes; binreader >> hIntan.date_Year; binreader >> hIntan.date_Month; binreader >> hIntan.date_Day; binreader >> hIntan.date_Hour; binreader >> hIntan.date_Minute; binreader >> hIntan.date_Second; binreader >> hIntan.Settings.samplingRate; break; default: throw std::runtime_error("Unrecognized data type"); } uint64_t pos = binreader.currentPos(); if (pos != numBytes) { throw std::runtime_error("Header NumBytes doesn't match number of bytes"); } return hIntan; } std::vector > read_data(BinaryReader& binreader, const IntanHeader& hIntan) { uint64_t bytes_remaining = binreader.bytesRemaining(); uint64_t length = bytes_remaining / (4+4+4+4); std::vector timestamps(length); std::vector applied(length); std::vector totalClamp(length); std::vector > channels(2); channels[0].resize(length); channels[1].resize(length); for (unsigned int idata = 0; idata < length; ++idata) { binreader >> timestamps[idata]; binreader >> applied[idata]; binreader >> channels[1][idata]; binreader >> channels[0][idata]; float vfactor = 1e3; // V -> mV float ifactor = 1e12; // A -> pA if (hIntan.Settings.isVoltageClamp) { channels[0][idata] *= ifactor; channels[1][idata] *= vfactor; } else { channels[1][idata] *= ifactor; channels[0][idata] *= vfactor; } } return channels; } std::vector > read_aux_data(BinaryReader& binreader, uint16_t numADCs) { uint64_t bytes_remaining = binreader.bytesRemaining(); uint64_t length = bytes_remaining / (4+2+2+2*numADCs); std::vector timestamps(length); std::vector digitalIn(length); std::vector digitalOut(length); std::vector > adc(numADCs); for (unsigned int iadc = 0; iadc < numADCs; ++iadc) { adc[iadc].resize(length); } for (unsigned int idata = 0; idata < length; ++idata) { binreader >> timestamps[idata]; binreader >> digitalIn[idata]; binreader >> digitalOut[idata]; for (unsigned int iadc = 0; iadc < numADCs; ++iadc) { uint16_t tmpui; binreader >> tmpui; adc[iadc][idata] = tmpui*0.0003125 - (1<<15); } } return adc; } void stfio::importIntanFile(const std::string &fName, Recording &ReturnData, ProgressInfo& progDlg) { unique_ptr fs(new FileInStream()); #ifdef _WINDOWS std::wstring wfName(fName.begin(), fName.end()); #else std::string wfName(fName); #endif fs->open(wfName); unique_ptr binreader(new BinaryReader(std::move(fs))); IntanHeader hIntan = read_header(*binreader); if (hIntan.datatype == 0) { std::vector > channels = read_data(*binreader, hIntan); ReturnData.resize(channels.size()); ReturnData.SetXScale(1e3/hIntan.Settings.samplingRate); ReturnData.SetXUnits("ms"); int mon = hIntan.date_Month-1; int year = hIntan.date_Year - 1900; ReturnData.SetDateTime(year, mon, hIntan.date_Day, hIntan.date_Hour, hIntan.date_Minute, hIntan.date_Second); for (unsigned int nchan = 0; nchan < channels.size(); ++nchan) { // ReturnData[nchan].resize(hIntan.Settings.waveform.size()); ReturnData[nchan].resize(1); } if (hIntan.Settings.isVoltageClamp) { ReturnData[0].SetYUnits("pA"); ReturnData[1].SetYUnits("mV"); } else { ReturnData[1].SetYUnits("pA"); ReturnData[0].SetYUnits("mV"); } unsigned int nsec = 0; for (unsigned int nchan = 0; nchan < channels.size(); ++nchan) { ReturnData[nchan][nsec].resize(channels[nchan].size()); std::copy(channels[nchan].begin(), channels[nchan].end(), ReturnData[nchan][nsec].get_w().begin()); } // for (std::vector::const_iterator it = hIntan.Settings.waveform.begin(); // it != hIntan.Settings.waveform.end(); // ++it) // { // for (unsigned int nchan = 0; nchan < channels.size(); ++nchan) { // ReturnData[nchan][nsec].resize(it->endIndex - it->startIndex); // std::copy(&(channels[nchan][it->startIndex]), &(channels[nchan][it->endIndex]), // ReturnData[nchan][nsec].get_w().begin()); // } // nsec++; // } } else { std::vector > aux_data = read_aux_data(*binreader, hIntan.numADCs); ReturnData.resize(1); ReturnData[0].resize(1); ReturnData[0][0].resize(aux_data[0].size()); std::copy(aux_data[0].begin(), aux_data[0].end(), ReturnData[0][0].get_w().begin()); } } stimfit-0.16.7/src/libstfio/intan/streams.cpp0000664000175000017500000001406614752207205014657 //---------------------------------------------------------------------------------- // streams.cpp // Downloaded from http://www.intantech.com/files/CLAMP_source_code_v1_0.zip // as of 2017-03-13 // // Copyright information added according to license directory in the original // source code package: // // Intan Technologies // // Copyright (c) 2016 Intan Technologies LLC // // This 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 of the License, or // (at your option) any later version. // // This file is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this file. If not, see . //---------------------------------------------------------------------------------- #include "streams.h" #include #include #include #include #include "common.h" #include using std::cerr; using std::endl; using std::ofstream; using std::ifstream; using std::ios; using std::wstring; using std::vector; using std::exception; using std::runtime_error; #define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100) // ------------------------------------------------------------------------ FileInStream::FileInStream() : filestream(nullptr) { } FileInStream::~FileInStream() { close(); } bool FileInStream::open(const FILENAME& filename) { unique_ptr tmp(new ifstream(filename.c_str(), ios::binary | ios::in)); if (tmp->is_open()) { filestream.reset(tmp.release()); filestream->seekg(0, filestream->end); filesize = filestream->tellg(); filestream->seekg(0, filestream->beg); return true; } else { char buffer[100]; #ifdef _WIN32 if (strerror_s(buffer, sizeof(buffer), errno) == 0) { #else if (strerror_r(errno, buffer, sizeof(buffer)) == 0) { #endif cerr << "Cannot open file for reading: " << buffer << endl; } else { cerr << "Cannot open file for reading: reason unknown" << endl; } return false; } } uint64_t FileInStream::bytesRemaining() { std::istream::pos_type pos = filestream->tellg(); return filesize - pos; } std::istream::pos_type FileInStream::currentPos() { return filestream->tellg(); } void FileInStream::close() { filestream.reset(); } int FileInStream::read(char* data, int len) { filestream->read(data, len); if (filestream->fail()) { throw runtime_error("No more data"); } return static_cast(filestream->gcount()); } // ------------------------------------------------------------------------ #if __cplusplus > 199711L BinaryReader::BinaryReader(unique_ptr&& other_) : #else BinaryReader::BinaryReader(BOOST_RV_REF(unique_ptr) other_) : #endif other(std::move(other_)) { } BinaryReader::~BinaryReader() { } BinaryReader& operator>>(BinaryReader& istream, int32_t& value) { unsigned char data[4]; istream.other->read(reinterpret_cast(data), 4); value = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); return istream; } BinaryReader& operator>>(BinaryReader& istream, uint32_t& value) { unsigned char data[4]; istream.other->read(reinterpret_cast(data), 4); value = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); return istream; } BinaryReader& operator>>(BinaryReader& istream, uint16_t& value) { unsigned char data[2]; istream.other->read(reinterpret_cast(data), 2); value = data[0] | (data[1] << 8); return istream; } BinaryReader& operator>>(BinaryReader& istream, int16_t& value) { unsigned char data[2]; istream.other->read(reinterpret_cast(data), 2); value = data[0] | (data[1] << 8); return istream; } BinaryReader& operator>>(BinaryReader& istream, uint8_t& value) { unsigned char data[1]; istream.other->read(reinterpret_cast(data), 1); value = data[0]; return istream; } BinaryReader& operator>>(BinaryReader& istream, int8_t& value) { unsigned char data[1]; istream.other->read(reinterpret_cast(data), 1); value = data[0]; return istream; } BinaryReader& operator>>(BinaryReader& istream, float& value) { char* tmp = reinterpret_cast(&value); if (IS_BIG_ENDIAN) { char data[4]; istream.other->read(data, sizeof(value)); tmp[0] = data[3]; tmp[1] = data[2]; tmp[2] = data[1]; tmp[3] = data[0]; } else { istream.other->read(tmp, sizeof(value)); } return istream; } BinaryReader& operator>>(BinaryReader& istream, double& value) { float f; istream >> f; value = f; return istream; } BinaryReader& operator>>(BinaryReader& istream, wstring& value) { uint32_t size; istream >> size; value.clear(); if (size > 0) { vector tmp(size + 2); #ifndef _WINDOWS istream.other->read(tmp.data(), size); tmp[size] = 0; tmp[size + 1] = 0; value = reinterpret_cast(tmp.data()); #else istream.other->read(&tmp[0], size); tmp[size] = 0; tmp[size + 1] = 0; value = reinterpret_cast(&tmp[0]); #endif } return istream; } // ------------------------------------------------------------------------ FILENAME toFileName(const std::string& s) { #if defined(_WIN32) && defined(_UNICODE) return toWString(s); #else return s; #endif } FILENAME toFileName(const std::wstring& ws) { #if defined(_WIN32) && defined(_UNICODE) return ws; #else return toString(ws); #endif } stimfit-0.16.7/src/libstfio/intan/common.cpp0000664000175000017500000000445514750344764014504 //---------------------------------------------------------------------------------- // common.h // Downloaded from http://www.intantech.com/files/CLAMP_source_code_v1_0.zip // as of 2017-03-13 // // Original comment and license information for the header file common.h: // Intan Technologies // Common Source File // Version 2.0 (25 August 2015) // // Provides common functionality for RHD and CLAMP source code. // // Copyright (c) 2014-2015 Intan Technologies LLC // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the // use of this software. // // Permission is granted to anyone to use this software for any applications that // use Intan Technologies integrated circuits, and to alter it and redistribute it // freely. // // See http://www.intantech.com for documentation and product information. //---------------------------------------------------------------------------------- #include "common.h" #include using std::ostream; using std::string; using std::wstring; #if __cplusplus <= 199711L #define nullptr NULL #endif class nullbuf : public std::streambuf { protected: virtual int overflow(int c) { return c; } }; class nullstream : public std::ostream { nullbuf _streambuf; public: nullstream() : std::ostream(&_streambuf) { clear(); } }; // A stream that ouputs nowhere nullstream dev_null; ostream* logger = &dev_null; ostream* nulllogger = &dev_null; ostream* SetLogger(std::ostream* logger_) { ostream* prev = logger; if (logger_ == nullptr) { logger = &dev_null; } else { logger = logger_; } return prev; } wstring toWString(const string& s) { wstring ws; ws.insert(ws.begin(), s.begin(), s.end()); return ws; } string toString(const wstring& ws) { string s; s.insert(s.begin(), ws.begin(), ws.end()); return s; } #if defined WIN32 && defined _DEBUG bool _trace(TCHAR *format, ...) { TCHAR buffer[1000]; va_list argptr; va_start(argptr, format); vswprintf_s(buffer, sizeof(buffer)/sizeof(buffer[0]), format, argptr); va_end(argptr); OutputDebugString(buffer); return true; } #endif stimfit-0.16.7/src/libstfio/intan/common.h0000664000175000017500000000530314750344764014142 //---------------------------------------------------------------------------------- // common.h // Downloaded from http://www.intantech.com/files/CLAMP_source_code_v1_0.zip // as of 2017-03-13 // // Original comment and license information: // Intan Technologies // Common Header File // Version 2.0 (25 August 2015) // // Provides common functionality for RHD and CLAMP source code. // // Copyright (c) 2014-2015 Intan Technologies LLC // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the // use of this software. // // Permission is granted to anyone to use this software for any applications that // use Intan Technologies integrated circuits, and to alter it and redistribute it // freely. // // See http://www.intantech.com for documentation and product information. //---------------------------------------------------------------------------------- #pragma once #include #include #include #include using std::endl; // Debug output window printing macro #define DEBUGOUT( s ) \ { \ std::ostringstream os_; \ os_ << " DEBUG: " << s; \ OutputDebugStringA( os_.str().c_str() ); \ } // Logging ----------------------------------------------------------------- // Logging goes to this, which may point to dev_null extern std::ostream* logger; extern std::ostream* nulllogger; // Always points to dev_null // To #define LOG(x) ((x) ? (*logger) : (*nulllogger)) // Use SetLogger(&std::cerr), for example, or SetLogger(nullptr). std::ostream* SetLogger(std::ostream* logger_); // _T macro for unicode support --------------------------------------------- #ifndef _T #if defined(_WIN32) && defined(_UNICODE) #define _T(x) L ##x #else #define _T(x) x #endif #endif std::wstring toWString(const std::string& s); std::string toString(const std::wstring& ws); // Throws an exception if value has more than numBits set. For example, if you're trying to put something into 3 bits, and you specify 15. template T CheckBits(T value, unsigned int numBits) { T mask = (-1 << numBits); if ((value & mask) != 0) { throw std::invalid_argument("Invalid value with too many bits set."); } return value; } #define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember)) #if defined WIN32 #define NOMINMAX #include bool _trace(TCHAR *format, ...); #ifdef _DEBUG #define TRACE _trace #else #define TRACE false && _trace #endif #endif stimfit-0.16.7/src/libstfio/intan/streams.h0000664000175000017500000000727214750344764014337 //---------------------------------------------------------------------------------- // streams.h // Downloaded from http://www.intantech.com/files/CLAMP_source_code_v1_0.zip // as of 2017-03-13 // // Copyright information added according to license directory in the original // source code package: // // Intan Technologies // // Copyright (c) 2016 Intan Technologies LLC // // This 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 of the License, or // (at your option) any later version. // // This file is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this file. If not, see . //---------------------------------------------------------------------------------- #ifndef STREAMS_H #define STREAMS_H #include #include #if __cplusplus > 199711L #include using std::unique_ptr; using std::move; #else #include #include using boost::movelib::unique_ptr; using boost::move; #define nullptr NULL #endif #include #include #include "./intanlib.h" #if defined(_WIN32) && defined(_UNICODE) typedef std::wstring FILENAME; #else typedef std::string FILENAME; #endif // ------------------------------------------------------------------------ class InStream { public: virtual ~InStream() {} virtual int read(char* data, int len) = 0; virtual uint64_t bytesRemaining() = 0; virtual std::istream::pos_type currentPos() = 0; }; // ------------------------------------------------------------------------ class FileInStream : public InStream { public: FileInStream(); ~FileInStream(); virtual bool open(const FILENAME& filename); // Opens with new name virtual int read(char* data, int len) override; uint64_t bytesRemaining() override; std::istream::pos_type currentPos() override; private: unique_ptr filestream; std::istream::pos_type filesize; virtual void close(); }; // ------------------------------------------------------------------------ class BinaryReader { public: #if __cplusplus > 199711L BinaryReader(unique_ptr&& other_); #else BinaryReader(BOOST_RV_REF(unique_ptr) other_); #endif virtual ~BinaryReader(); uint64_t bytesRemaining() { return other->bytesRemaining(); } std::istream::pos_type currentPos() { return other->currentPos(); } protected: friend BinaryReader& operator>>(BinaryReader& istream, int32_t& value); friend BinaryReader& operator>>(BinaryReader& istream, uint32_t& value); friend BinaryReader& operator>>(BinaryReader& istream, int16_t& value); friend BinaryReader& operator>>(BinaryReader& istream, uint16_t& value); friend BinaryReader& operator>>(BinaryReader& istream, int8_t& value); friend BinaryReader& operator>>(BinaryReader& istream, uint8_t& value); friend BinaryReader& operator>>(BinaryReader& istream, float& value); friend BinaryReader& operator>>(BinaryReader& istream, double& value); friend BinaryReader& operator>>(BinaryReader& istream, std::wstring& value); private: unique_ptr other; }; FILENAME toFileName(const std::string& s); FILENAME toFileName(const std::wstring& ws); #endif // STREAMS_H stimfit-0.16.7/src/libstfio/recording.cpp0000664000175000017500000002720514752207205014043 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "./stfio.h" #include "./recording.h" #include #include #include Recording::Recording(void) : ChannelArray(0) { init(); } Recording::Recording(const Channel& c_Channel) : ChannelArray(1,c_Channel) { init(); } Recording::Recording(const std::deque& ChannelList) : ChannelArray(ChannelList) { init(); } Recording::Recording(std::size_t c_n_channels, std::size_t c_n_sections, std::size_t c_n_points) : ChannelArray(c_n_channels, Channel(c_n_sections, c_n_points)) { init(); } void Recording::init() { file_description = "\0"; global_section_description = "\0"; scaling = "\0"; comment = "\0"; xunits = "ms" ; dt = 1.0; // get current time time_t timer; timer = time(0); memcpy(&datetime, localtime(&timer), sizeof(datetime)); cc = 0; sc = 1; cs = 0; selectedSections = std::vector(0); selectBase = Vector_double(0); sectionMarker = std::vector(0); } Recording::~Recording() { } const Channel& Recording::at(std::size_t n_c) const { try { return ChannelArray.at(n_c); } catch (...) { throw; } } Channel& Recording::at(std::size_t n_c) { try { return ChannelArray.at(n_c); } catch (...) { throw; } } int Recording::SetDate(const std::string& value) { struct tm t = GetDateTime(); #if HAVE_STRPTIME_H strptime(value.c_str(), "%F", &t); #else if ( sscanf(value.c_str(),"%i-%i-%i", &t.tm_year, &t.tm_mon, &t.tm_mday)==3 || sscanf(value.c_str(),"%i.%i.%i", &t.tm_mday, &t.tm_mon, &t.tm_year)==3 || sscanf(value.c_str(),"%i/%i/%i", &t.tm_mon, &t.tm_mday, &t.tm_year)==3 ) { t.tm_mon--; if (t.tm_year < 50) t.tm_year += 100; else if (t.tm_year < 139); else if (t.tm_year > 1900) t.tm_year -= 1900; } else { // TODO: error handling fprintf(stderr,"SetDate(%s) failed\n",value.c_str()); return(-1); } #endif SetDateTime(t); return(0); } int Recording::SetTime(const std::string& value) { struct tm t = GetDateTime(); #if HAVE_STRPTIME_H strptime(value.c_str(), "%T", &t); #else if ( sscanf(value.c_str(),"%i-%i-%i", &t.tm_hour, &t.tm_min, &t.tm_sec)==3 || sscanf(value.c_str(),"%i.%i.%i", &t.tm_hour, &t.tm_min, &t.tm_sec)==3 || sscanf(value.c_str(),"%i:%i:%i", &t.tm_hour, &t.tm_min, &t.tm_sec)==3 ) { ; // everthing is fine } else { // TODO: error handling fprintf(stderr,"SetTime(%s) failed\n",value.c_str()); return(-1); } #endif SetDateTime(t); return(0); } int Recording::SetTime(int hour, int minute, int sec) { datetime.tm_hour=hour; datetime.tm_min=minute; datetime.tm_sec=sec; return(0); } int Recording::SetDate(int year, int month, int mday) { datetime.tm_year=year; datetime.tm_mon=month; datetime.tm_mday=mday; return(0); } void Recording::SetDateTime(int year, int month, int mday,int hour, int minute, int sec) { datetime.tm_year=year; datetime.tm_mon=month; datetime.tm_mday=mday; datetime.tm_hour=hour; datetime.tm_min=minute; datetime.tm_sec=sec; } void Recording::InsertChannel(Channel& c_Channel, std::size_t pos) { try { if ( ChannelArray.at(pos).size() <= c_Channel.size() ) { ChannelArray.at(pos).resize( c_Channel.size() ); } // Resize sections if necessary: std::size_t n_sec = 0; for ( sec_it sit = c_Channel.get().begin(); sit != c_Channel.get().end(); ++sit ) { if ( ChannelArray.at(pos).at(n_sec).size() <= sit->size() ) { ChannelArray.at(pos).at(n_sec).get_w().resize( sit->size() ); } n_sec++; } } catch (...) { throw; } ChannelArray.at(pos) = c_Channel; } void Recording::CopyAttributes(const Recording& c_Recording) { file_description=c_Recording.file_description; global_section_description=c_Recording.global_section_description; scaling=c_Recording.scaling; datetime=c_Recording.datetime; comment=c_Recording.comment; for ( std::size_t n_ch = 0; n_ch < c_Recording.size(); ++n_ch ) { if ( size() > n_ch ) { ChannelArray[n_ch].SetYUnits( c_Recording[n_ch].GetYUnits() ); } } dt=c_Recording.dt; } void Recording::resize(std::size_t c_n_channels) { ChannelArray.resize(c_n_channels); } size_t Recording::GetChannelSize(std::size_t n_channel) const { try { return ChannelArray.at(n_channel).size(); } catch (...) { throw; } } void Recording::SetCurChIndex(size_t value) { if (value>=get().size()) { throw std::out_of_range("channel out of range in Recording::SetCurChIndex()"); } cc=value; } void Recording::SetSecChIndex(size_t value) { if (value>=get().size() || value==cc) { throw std::out_of_range("channel out of range in Recording::SetSecChIndex()"); } sc=value; } void Recording::SetCurSecIndex( size_t value ) { if (value >= get()[cc].size()) { throw std::out_of_range("channel out of range in Recording::SetCurSecIndex()"); } cs=value; } void Recording::SelectTrace(std::size_t sectionToSelect, std::size_t base_start, std::size_t base_end) { // Check range so that sectionToSelect can be used // without checking again: if (sectionToSelect>=curch().size()) { std::out_of_range e("subscript out of range in Recording::SelectTrace\n"); throw e; } selectedSections.push_back(sectionToSelect); double sumY=0; if (curch()[sectionToSelect].size()==0) { selectBase.push_back(0); } else { int start = base_start; int end = base_end; if (start > (int)curch()[sectionToSelect].size()-1) start = curch()[sectionToSelect].size()-1; if (start < 0) start = 0; if (end > (int)curch()[sectionToSelect].size()-1) end = curch()[sectionToSelect].size()-1; if (end < 0) end = 0; #ifdef _OPENMP #pragma omp parallel for reduction(+:sumY) #endif for (int i=start; i<=end; i++) { sumY += curch()[sectionToSelect][i]; } int n=(int)(end-start+1); selectBase.push_back(sumY/n); } } bool Recording::UnselectTrace(std::size_t sectionToUnselect) { //verify whether the trace has really been selected and find the //number of the trace within the selectedTraces array: bool traceSelected=false; std::size_t traceToRemove=0; for (std::size_t n=0; n < selectedSections.size() && !traceSelected; ++n) { if (selectedSections[n] == sectionToUnselect) traceSelected=true; if (traceSelected) traceToRemove=n; } //Shift the selectedTraces array by one position, beginning //with the trace to remove: if (traceSelected) { //shift traces by one position: for (std::size_t k=traceToRemove; k < GetSelectedSections().size()-1; ++k) { selectedSections[k]=selectedSections[k+1]; selectBase[k]=selectBase[k+1]; } // resize vectors: selectedSections.resize(selectedSections.size()-1); selectBase.resize(selectBase.size()-1); return true; } else { //msgbox return false; } } void Recording::SetXScale(double value) { dt=value; for (ch_it it1 = ChannelArray.begin(); it1 != ChannelArray.end(); it1++) { for (sec_it it2 = it1->get().begin(); it2 != it1->get().end(); it2++) { it2->SetXScale(value); } } } void Recording::MakeAverage(Section& AverageReturn, Section& SigReturn, std::size_t channel, const std::vector& section_index, bool isSig, const std::vector& shift) const { if (channel >= ChannelArray.size()) { throw std::out_of_range("Channel number out of range in Recording::MakeAverage"); } unsigned int n_sections = section_index.size(); if (shift.size() != n_sections) { throw std::out_of_range("Shift out of range in Recording::MakeAverage"); } for (unsigned int l = 0; l < n_sections; ++l) { if (section_index[l] >= ChannelArray[channel].size()) { throw std::out_of_range("Section number out of range in Recording::MakeAverage"); } if (AverageReturn.size() + shift[l] > ChannelArray[channel][section_index[l]].size()) { throw std::out_of_range("Sampling point out of range in Recording::MakeAverage"); } } for (unsigned int k=0; k < AverageReturn.size(); ++k) { AverageReturn[k]=0.0; //Calculate average for (unsigned int l = 0; l < n_sections; ++l) { AverageReturn[k] += ChannelArray[channel][section_index[l]][k+shift[l]]; } AverageReturn[k] /= n_sections; // set sample interval of averaged traces AverageReturn.SetXScale(ChannelArray[channel][section_index[0]].GetXScale()); if (isSig) { SigReturn[k]=0.0; //Calculate variance for (unsigned int l=0; l < n_sections; ++l) { SigReturn[k] += pow(ChannelArray[channel][section_index[l]][k+shift[l]] - AverageReturn[k], 2); } SigReturn[k] /= (n_sections - 1); SigReturn[k]=sqrt(SigReturn[k]); } } } void Recording::AddRec(const Recording &toAdd) { // check number of channels: if (toAdd.size()!=size()) { throw std::runtime_error("Number of channels doesn't match"); } // check dt: if (toAdd.GetXScale()!=dt) { throw std::runtime_error("Sampling interval doesn't match"); } // add sections: std::deque< Channel >::iterator it; std::size_t n_c = 0; for (it = ChannelArray.begin();it != ChannelArray.end(); it++) { std::size_t old_size = it->size(); it->resize(toAdd[n_c].size()+old_size); for (std::size_t n_s=old_size;n_sInsertSection(toAdd[n_c].at(n_s-old_size),n_s); } catch (...) { throw; } } n_c++; } } std::string Recording::GetEventDescription(int type) { return listOfMarkers[type]; } void Recording::SetEventDescription(int type, const char* Description) { listOfMarkers[type] = Description; } void Recording::InitSectionMarkerList(size_t n) { sectionMarker.resize(n); return; } int Recording::GetSectionType(size_t section_number) { return sectionMarker[section_number]; } void Recording::SetSectionType(size_t section_number, int type) { sectionMarker[section_number]=type; return; } stimfit-0.16.7/src/libstfio/stfio.h0000664000175000017500000002124114750344764012664 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file stfio.h * \author Christoph Schmidt-Hieber * \date 2011-09-25 * \brief header file for libstfio * * * Header file for libstfio */ #ifndef _STFIO_H_ #define _STFIO_H_ #include #if (__cplusplus < 201103) # include #else # include # include #endif #include #include #include #include #include #ifdef _MSC_VER #pragma warning( disable : 4251 ) // Disable warning messages #pragma warning( disable : 4996 ) // Disable warning messages #endif //! Defines dll export or import functions for Windows #if defined(_WINDOWS) && !defined(__MINGW32__) #ifdef STFIODLL #define StfioDll __declspec( dllexport ) #else #define StfioDll __declspec( dllimport ) #endif #else #define StfioDll #endif typedef std::vector Vector_double; typedef std::vector Vector_float; #ifdef _MSC_VER #ifndef NAN static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; #define NAN (*(const float *) __nan) #endif #ifndef INFINITY #define INFINITY (DBL_MAX+DBL_MAX) #endif StfioDll long int lround(double x); #define snprintf _snprintf #endif #include "./recording.h" #include "./channel.h" #include "./section.h" /* class Recording; */ /* class Channel; */ /* class Section; */ //! The stfio namespace. /*! All essential core functions and classes are in this namespace. * Its purpose is to reduce name mangling problems. */ namespace stfio { /*! \addtogroup stfio * @{ */ StfioDll Vector_double vec_scal_plus(const Vector_double& vec, double scalar); StfioDll Vector_double vec_scal_minus(const Vector_double& vec, double scalar); StfioDll Vector_double vec_scal_mul(const Vector_double& vec, double scalar); StfioDll Vector_double vec_scal_div(const Vector_double& vec, double scalar); StfioDll Vector_double vec_vec_plus(const Vector_double& vec1, const Vector_double& vec2); StfioDll Vector_double vec_vec_minus(const Vector_double& vec1, const Vector_double& vec2); StfioDll Vector_double vec_vec_mul(const Vector_double& vec1, const Vector_double& vec2); StfioDll Vector_double vec_vec_div(const Vector_double& vec1, const Vector_double& vec2); //! ProgressInfo class /*! Abstract class to be used as an interface for the file io read/write functions * Can be a GUI Dialog or stdout messages */ class StfioDll ProgressInfo { public: //! Constructor /*! \param title Dialog title * \param message Message displayed * \param maximum Maximum value for the progress meter * \param verbose Whether or not to emit a lot of noise */ ProgressInfo(const std::string& title, const std::string& message, int maximum, bool verbose) {}; //! Updates the progress info /*! \param value New value of the progress meter * \param newmsg New message for the info text * \param skip This is set to true if the user has chosen to skip the operation * \return True unless the operation was cancelled. */ virtual bool Update(int value, const std::string& newmsg="", bool* skip=NULL) = 0; }; //! StdoutProgressInfo class /*! Example of a ProgressInfo that prints to stdout */ class StfioDll StdoutProgressInfo : public stfio::ProgressInfo { public: StdoutProgressInfo(const std::string& title, const std::string& message, int maximum, bool verbose); bool Update(int value, const std::string& newmsg="", bool* skip=NULL); private: bool verbosity; }; //! Text file import filter settings struct txtImportSettings { txtImportSettings() : hLines(1),toSection(true),firstIsTime(true),ncolumns(2), sr(20),yUnits("mV"),yUnitsCh2("pA"),xUnits("ms") {} int hLines; /*!< Number of header lines. */ bool toSection; /*!< Import columns into separate sections rather than separate channels. */ bool firstIsTime; /*!< First column contains time. */ int ncolumns; /*!< Number of columns. */ double sr; /*!< Sampling rate. */ std::string yUnits; /*!< y units string. */ std::string yUnitsCh2; /*!< y units string of second channel. */ std::string xUnits; /*!< x units string. */ }; //! File types enum filetype { atf, /*!< Axon text file. */ abf, /*!< Axon binary file. */ axg, /*!< Axograph binary file. */ ascii, /*!< Generic text file. */ cfs, /*!< CED filing system. */ igor, /*!< Igor binary wave. */ son, /*!< CED Son files. */ hdf5, /*!< hdf5 files. */ heka, /*!< heka files. */ biosig, /*!< biosig files. */ tdms, /*!< TDMS files. */ intan, /*!< Intan CLAMP files. */ none /*!< Undefined file type. */ }; #ifndef TEST_MINIMAL //! Attempts to determine the filetype from the filter extension. /*! \param ext The filter extension to be tested (in the form wxT("*.ext")). * \return The corresponding file type. */ StfioDll stfio::filetype findType(const std::string& ext); #endif // TEST_MINIMAL //! Returns file extension for a file type /*! \param ftype File type * \return File extension for given file type (in the form ".ext") */ StfioDll std::string findExtension(stfio::filetype ftype); //! Generic file import. /*! \param fName The full path name of the file. * \param type The file type. * \param ReturnData Will contain the file data on return. * \param txtImport The text import filter settings. * \param ProgressInfo Progress indicator * \return true if the file has successfully been read, false otherwise. */ StfioDll bool importFile( const std::string& fName, stfio::filetype type, Recording& ReturnData, const stfio::txtImportSettings& txtImport, stfio::ProgressInfo& progDlg ); //! Generic file export. /*! \param fName The full path name of the file. * \param type The file type. * \param Data Data to be written * \param ProgressInfo Progress indicator * \return true if the file has successfully been written, false otherwise. */ StfioDll bool exportFile(const std::string& fName, stfio::filetype type, const Recording& Data, ProgressInfo& progDlg); //! Produce new recording with concatenated sections /*! \param src Source recording * \param sections Indices of selected sections * \param ProgressInfo Progress indicator * \return New recording with concatenated selected sections */ StfioDll Recording concatenate(const Recording& src, const std::vector& sections, ProgressInfo& progDlg); //! Produce new recording with multiplied sections /*! \param src Source recording * \param sections Indices of selected sections * \param channel Channel index * \param factor Multiplication factor * \return New recording with multiplied selected sections */ StfioDll Recording multiply(const Recording& src, const std::vector& sections, std::size_t channel, double factor); /*@}*/ } // end of namespace typedef std::vector< std::string >::iterator sst_it; /*!< std::string iterator */ typedef std::vector< std::string >::const_iterator c_sst_it; /*!< constant std::string iterator */ typedef std::vector< std::size_t >::const_iterator c_st_it; /*!< constant size_t iterator */ typedef std::vector< int >::iterator int_it; /*!< int iterator */ typedef std::vector< int >::const_iterator c_int_it; /*!< constant int iterator */ typedef std::deque< Channel >::iterator ch_it; /*!< Channel iterator */ typedef std::deque< Channel >::const_iterator c_ch_it; /*!< constant Channel iterator */ typedef std::deque< Section >::iterator sec_it; /*!< Section iterator */ typedef std::deque< Section >::const_iterator c_sec_it; /*!< constant Section iterator */ #endif stimfit-0.16.7/src/libstfio/channel.h0000775000175000017500000001305014750344764013152 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file channel.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares the Channel class. */ #ifndef _CHANNEL_H #define _CHANNEL_H /*! \addtogroup stfgen * @{ */ #include "section.h" //! A Channel contains several data \link #Section Sections \endlink representing observations of the same physical quantity. class StfioDll Channel { public: //ctor/dtor--------------------------------------------------- //! Default constructor explicit Channel(void); //! Constructor /*! \param c_Section A single section from which to construct the channel */ explicit Channel(const Section& c_Section); //! Constructor /*! \param SectionList A vector of Sections from which to construct the channel */ explicit Channel(const std::deque

& SectionList); //! Constructor /*! Setting the number of sections at construction time will avoid unnecessary * memory re-allocations. * \param c_n_sections The number of sections. * \param section_size Initial section size. Will serve additional * re-alocations if known at construction time. */ explicit Channel(std::size_t c_n_sections, std::size_t section_size = 0); //! Destructor ~Channel(); //operators--------------------------------------------------- //! Unchecked access to a section (read and write) /*! Use at() for range-checked access. * \param at_ The section index. * \return The section at index at_. */ Section& operator[](std::size_t at_) { return SectionArray[at_]; } //! Unchecked access to a section (read-only) /*! Use at() for range-checked access. * \param at_ The section index. * \return The section at index at_. */ const Section& operator[](std::size_t at_) const { return SectionArray[at_]; } //member access: read----------------------------------------- //! Retrieves the channel name /*! \return The channel name. */ const std::string& GetChannelName() const { return name; } //! Retrieves the y units string. /*! \return The y units string. */ const std::string& GetYUnits( ) const { return yunits; } //! Retrieves the size of the section array. /*! \return The size of the section array. */ size_t size() const { return SectionArray.size(); } //! Range-checked access to a section (read-only). /*! Will throw std::out_of_range if out of range. * \param at_ The index of the section. * \return The section at index at_. */ const Section& at(std::size_t at_) const; //! Range-checked access to a section (read and write). /*! Will throw std::out_of_range if out of range. * \param at_ The index of the section. * \return The section at index at_. */ Section& at(std::size_t at_); //! Low-level access to the section array (read-only). /*! \return The vector containing the sections. */ const std::deque< Section >& get() const { return SectionArray; } //! Low-level access to the section array (read and write). /*! \return The vector containing the sections. */ std::deque< Section >& get() { return SectionArray; } //member access: write---------------------------------------- //! Sets the channel name /*! \param value The channel name. */ void SetChannelName(const std::string& value) { name = value; } //! Sets the y units string /*! \param value The new y units string. */ void SetYUnits( const std::string& value ) { yunits = value; } //misc-------------------------------------------------------- //! Inserts a section at the given position, overwriting anything that's currently stored at that position /*! Meant to be used after constructing with Channel(const unsigned int& c_n_sections}. * The section array size has to be larger than pos because it won't be resized. * Will throw std::out_of_range if out of range. * \param c_Section The section to be inserted. * \param pos The position at which to insert the section. */ void InsertSection(const Section& c_Section, std::size_t pos); //! Resize the section array. /*! \param newSize The new number of sections. */ void resize(std::size_t newSize); //! Reserve memory for a number of sections. /*! This will avoid unnecessary memory re-allocations. * \param resSize The number of sections to reserve memory for. */ void reserve(std::size_t resSize); private: //private members--------------------------------------------- std::string name, yunits; // An array of sections std::deque< Section > SectionArray; }; /*@}*/ #endif stimfit-0.16.7/src/libstfio/hdf5/0000775000175000017500000000000014764352501012266 5stimfit-0.16.7/src/libstfio/hdf5/hdf5lib.cpp0000775000175000017500000005230514750344764014246 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "hdf5.h" #if H5_VERS_MINOR > 6 #include "hdf5_hl.h" #else #include "H5TA.h" #endif #include #include #include #include "./hdf5lib.h" #include "../recording.h" const static unsigned int DATELEN = 128; const static unsigned int TIMELEN = 128; const static unsigned int UNITLEN = 16; typedef struct rt { int channels; char date[DATELEN]; char time[TIMELEN]; } rt; typedef struct ct { int n_sections; } ct; typedef struct st { double dt; char xunits[UNITLEN]; char yunits[UNITLEN]; } st; bool stfio::exportHDF5File(const std::string& fName, const Recording& WData, ProgressInfo& progDlg) { hid_t file_id = H5Fcreate(fName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); const int NRECORDS = 1; const int NFIELDS = 3; /* Calculate the size and the offsets of our struct members in memory */ size_t rt_offset[NFIELDS] = { HOFFSET( rt, channels ), HOFFSET( rt, date ), HOFFSET( rt, time )}; /* Define an array of root tables */ rt p_data; p_data.channels = WData.size(); struct tm t = WData.GetDateTime(); std::size_t date_length = snprintf(p_data.date, DATELEN, "%04i-%02i-%02i", t.tm_year+1900, t.tm_mon+1, t.tm_mday); std::size_t time_length = snprintf(p_data.time, TIMELEN, "%02i:%02i:%02i", t.tm_hour, t.tm_min, t.tm_sec); // ensure that an undefine string is set to "\0", and that the terminating \0 is counted in string length p_data.date[date_length++] = 0; p_data.time[time_length++] = 0; /* Define field information */ const char *field_names[NFIELDS] = { "channels", "date", "time" }; hid_t field_type[NFIELDS]; /* Initialize the field field_type */ hid_t string_type1 = H5Tcopy( H5T_C_S1 ); hid_t string_type2 = H5Tcopy( H5T_C_S1 ); H5Tset_size( string_type1, date_length); H5Tset_size( string_type2, time_length); field_type[0] = H5T_NATIVE_INT; field_type[1] = string_type1; field_type[2] = string_type2; std::ostringstream desc; desc << "Description of " << fName; herr_t status = H5TBmake_table( desc.str().c_str(), file_id, "description", (hsize_t)NFIELDS, (hsize_t)NRECORDS, sizeof(rt), field_names, rt_offset, field_type, 10, NULL, 0, &p_data ); if (status < 0) { std::string errorMsg("Exception while writing description in stfio::exportHDF5File"); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg); } hid_t comment_group = H5Gcreate2( file_id,"/comment", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); /* File comment. */ std::string description(WData.GetFileDescription()); if (description.length() <= 0) { description = "No description"; } status = H5LTmake_dataset_string(file_id, "/comment/description", description.c_str()); if (status < 0) { std::string errorMsg("Exception while writing description in stfio::exportHDF5File"); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg); } std::string comment(WData.GetComment()); if (comment.length() <= 0) { comment = "No comment"; } status = H5LTmake_dataset_string(file_id, "/comment/comment", comment.c_str()); if (status < 0) { std::string errorMsg("Exception while writing comment in stfio::exportHDF5File"); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg); } H5Gclose(comment_group); std::vector channel_name(WData.size()); hid_t channels_group = H5Gcreate2( file_id,"/channels", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); for ( std::size_t n_c=0; n_c < WData.size(); ++n_c) { /* Channel descriptions. */ std::ostringstream ossname; ossname << WData[n_c].GetChannelName(); if ( ossname.str() == "" ) { ossname << "ch" << (n_c); } channel_name[n_c] = ossname.str(); hsize_t dimsc[1] = { 1 }; hid_t string_typec = H5Tcopy( H5T_C_S1 ); std::size_t cn_length = channel_name[n_c].length(); if (cn_length <= 0) cn_length = 1; H5Tset_size( string_typec, cn_length ); std::vector datac(channel_name[n_c].length()); std::copy(channel_name[n_c].begin(),channel_name[n_c].end(), datac.begin()); std::ostringstream desc_path; desc_path << "/channels/ch" << (n_c); status = H5LTmake_dataset(file_id, desc_path.str().c_str(), 1, dimsc, string_typec, &datac[0]); if (status < 0) { std::string errorMsg("Exception while writing channel name in stfio::exportHDF5File"); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg); } std::ostringstream channel_path; channel_path << "/" << channel_name[n_c]; hid_t channel_group = H5Gcreate2( file_id, channel_path.str().c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if (channel_group < 0) { std::ostringstream errorMsg; errorMsg << "Exception while creating channel group for " << channel_path.str().c_str(); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg.str()); } /* Calculate the size and the offsets of our struct members in memory */ size_t ct_size = sizeof( ct ); size_t ct_offset[1] = { HOFFSET( rt, channels ) }; /* Define an array of channel tables */ ct c_data = { (int)WData[n_c].size() }; /* Define field information */ const char *cfield_names[1] = { "n_sections" }; hid_t cfield_type[1] = {H5T_NATIVE_INT}; std::ostringstream c_desc; c_desc << "Description of channel " << n_c; status = H5TBmake_table( c_desc.str().c_str(), channel_group, "description", (hsize_t)1, (hsize_t)1, ct_size, cfield_names, ct_offset, cfield_type, 10, NULL, 0, &c_data ); if (status < 0) { std::string errorMsg("Exception while writing channel description in stfio::exportHDF5File"); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg); } int max_log10 = 0; if (WData[n_c].size() > 1) { max_log10 = int(log10((double)WData[n_c].size()-1.0)); } for (std::size_t n_s=0; n_s < WData[n_c].size(); ++n_s) { int progbar = // Channel contribution: (int)(((double)n_c/(double)WData.size())*100.0+ // Section contribution: (double)(n_s)/(double)WData[n_c].size()*(100.0/WData.size())); std::ostringstream progStr; progStr << "Writing channel #" << n_c + 1 << " of " << WData.size() << ", Section #" << n_s << " of " << WData[n_c].size(); progDlg.Update(progbar, progStr.str()); // construct a number with leading zeros: int n10 = 0; if (n_s > 0) { n10 = int(log10((double)n_s)); } std::ostringstream strZero; strZero << ""; for (int n_z=n10; n_z < max_log10; ++n_z) { strZero << "0"; } // construct a section name: std::ostringstream section_name; section_name << WData[n_c][n_s].GetSectionDescription(); if ( section_name.str() == "" ) { section_name << "sec" << n_s; } // create a child group in the channel: std::ostringstream section_path; section_path << channel_path.str() << "/" << "section_" << strZero.str() << n_s; hid_t section_group = H5Gcreate2( file_id, section_path.str().c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); // add data and description, store as 32 bit little endian independent of machine: hsize_t dims[1] = { WData[n_c][n_s].size() }; std::ostringstream data_path; data_path << section_path.str() << "/data"; Vector_float data_cp(WData[n_c][n_s].get().size()); /* 32 bit */ for (std::size_t n_cp = 0; n_cp < WData[n_c][n_s].get().size(); ++n_cp) { data_cp[n_cp] = float(WData[n_c][n_s][n_cp]); } status = H5LTmake_dataset(file_id, data_path.str().c_str(), 1, dims, H5T_IEEE_F32LE, &data_cp[0]); if (status < 0) { std::string errorMsg("Exception while writing data in stfio::exportHDF5File"); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg); } const int NSRECORDS = 1; const int NSFIELDS = 3; /* Calculate the size and the offsets of our struct members in memory */ size_t st_size = sizeof( st ); size_t st_offset[NSFIELDS] = { HOFFSET( st, dt ), HOFFSET( st, xunits ), HOFFSET( st, yunits )}; /* Define an array of root tables */ st s_data; s_data.dt = WData.GetXScale(); if (WData.GetXUnits().length() < UNITLEN) strcpy( s_data.xunits, WData.GetXUnits().c_str() ); if (WData[n_c].GetYUnits().length() < UNITLEN) strcpy( s_data.yunits, WData[n_c].GetYUnits().c_str() ); /* Define field information */ const char *sfield_names[NSFIELDS] = { "dt", "xunits", "yunits" }; hid_t sfield_type[NSFIELDS]; /* Initialize the field field_type */ hid_t string_type4 = H5Tcopy( H5T_C_S1 ); hid_t string_type5 = H5Tcopy( H5T_C_S1 ); H5Tset_size( string_type4, 2); std::size_t yu_length = WData[n_c].GetYUnits().length(); if (yu_length <= 0) yu_length = 1; H5Tset_size( string_type5, yu_length ); sfield_type[0] = H5T_NATIVE_DOUBLE; sfield_type[1] = string_type4; sfield_type[2] = string_type5; std::ostringstream sdesc; sdesc << "Description of " << section_name.str(); status = H5TBmake_table( sdesc.str().c_str(), section_group, "description", (hsize_t)NSFIELDS, (hsize_t)NSRECORDS, st_size, sfield_names, st_offset, sfield_type, 10, NULL, 0, &s_data ); if (status < 0) { std::string errorMsg("Exception while writing section description in stfio::exportHDF5File"); H5Fclose(file_id); H5close(); throw std::runtime_error(errorMsg); } H5Gclose(section_group); } H5Gclose(channel_group); } H5Gclose(channels_group); /* Terminate access to the file. */ status = H5Fclose(file_id); if (status < 0) { std::string errorMsg("Exception while closing file in stfio::exportHDF5File"); throw std::runtime_error(errorMsg); } /* Release all hdf5 resources */ status = H5close(); if (status < 0) { std::string errorMsg("Exception while closing file in stfio::exportHDF5File"); throw std::runtime_error(errorMsg); } return (status >= 0); } void stfio::importHDF5File(const std::string& fName, Recording& ReturnData, ProgressInfo& progDlg) { /* Create a new file using default properties. */ hid_t file_id = H5Fopen(fName.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); /* H5TBread_table const int NRECORDS = 1;*/ const int NFIELDS = 3; /* Calculate the size and the offsets of our struct members in memory */ size_t rt_offset[NFIELDS] = { HOFFSET( rt, channels ), HOFFSET( rt, date ), HOFFSET( rt, time )}; rt rt_buf[1]; size_t rt_sizes[NFIELDS] = { sizeof( rt_buf[0].channels), sizeof( rt_buf[0].date), sizeof( rt_buf[0].time)}; herr_t status=H5TBread_table( file_id, "description", sizeof(rt), rt_offset, rt_sizes, rt_buf ); if (status < 0) { std::string errorMsg("Exception while reading description in stfio::importHDF5File"); throw std::runtime_error(errorMsg); } int numberChannels =rt_buf[0].channels; if ( ReturnData.SetDate(rt_buf[0].date) || ReturnData.SetTime(rt_buf[0].time) ) { std::cout << "Warning HDF5: could not decode date/time " << rt_buf[0].date << " " << rt_buf[0].time << std::endl; } /* Create the data space for the dataset. */ hsize_t dims; H5T_class_t class_id; size_t type_size; std::string description, comment; hid_t group_id = H5Gopen2(file_id, "/comment", H5P_DEFAULT); status = H5Lexists(group_id, "/comment/description", 0); if (status==1) { status = H5LTget_dataset_info( file_id, "/comment/description", &dims, &class_id, &type_size ); if (status >= 0) { description.resize( type_size ); status = H5LTread_dataset_string (file_id, "/comment/description", &description[0]); if (status < 0) { std::string errorMsg("Exception while reading description in stfio::importHDF5File"); throw std::runtime_error(errorMsg); } } } ReturnData.SetFileDescription(description); status = H5Lexists(group_id, "/comment/comment", 0); if (status==1) { status = H5LTget_dataset_info( file_id, "/comment/comment", &dims, &class_id, &type_size ); if (status >= 0) { comment.resize( type_size ); status = H5LTread_dataset_string (file_id, "/comment/comment", &comment[0]); if (status < 0) { std::string errorMsg("Exception while reading comment in stfio::importHDF5File"); throw std::runtime_error(errorMsg); } } } ReturnData.SetComment(comment); double dt = 1.0; std::string yunits = ""; for (int n_c=0;n_c szchannel_name(ctype_size); // szchannel_name.reset( new char[ctype_size] ); status = H5LTread_dataset(file_id, desc_path.str().c_str(), string_typec, &szchannel_name[0] ); if (status < 0) { std::string errorMsg("Exception while reading channel name in stfio::importHDF5File"); throw std::runtime_error(errorMsg); } std::ostringstream channel_name; for (std::size_t c=0; c 1) { max_log10 = int(log10((double)ct_buf[0].n_sections-1.0)); } for (int n_s=0; n_s < ct_buf[0].n_sections; ++n_s) { int progbar = // Channel contribution: (int)(((double)n_c/(double)numberChannels)*100.0+ // Section contribution: (double)(n_s)/(double)ct_buf[0].n_sections*(100.0/numberChannels)); std::ostringstream progStr; progStr << "Reading channel #" << n_c + 1 << " of " << numberChannels << ", Section #" << n_s+1 << " of " << ct_buf[0].n_sections; progDlg.Update(progbar, progStr.str()); // construct a number with leading zeros: int n10 = 0; if (n_s > 0) { n10 = int(log10((double)n_s)); } std::ostringstream strZero; strZero << ""; for (int n_z=n10; n_z < max_log10; ++n_z) { strZero << "0"; } // construct a section name: std::ostringstream section_name; section_name << "sec" << n_s; // create a child group in the channel: std::ostringstream section_path; section_path << channel_path.str() << "/" << "section_" << strZero.str() << n_s; hid_t section_group = H5Gopen2(file_id, section_path.str().c_str(), H5P_DEFAULT ); std::ostringstream data_path; data_path << section_path.str() << "/data"; hsize_t sdims; H5T_class_t sclass_id; size_t stype_size; status = H5LTget_dataset_info( file_id, data_path.str().c_str(), &sdims, &sclass_id, &stype_size ); if (status < 0) { std::string errorMsg("Exception while reading data information in stfio::importHDF5File"); throw std::runtime_error(errorMsg); } Vector_float TempSection(sdims); status = H5LTread_dataset(file_id, data_path.str().c_str(), H5T_IEEE_F32LE, &TempSection[0]); if (status < 0) { std::string errorMsg("Exception while reading data in stfio::importHDF5File"); throw std::runtime_error(errorMsg); } Section TempSectionT(TempSection.size(), section_name.str()); for (std::size_t cp = 0; cp < TempSectionT.size(); ++cp) { TempSectionT[cp] = double(TempSection[cp]); } // std::copy(TempSection.begin(),TempSection.end(),&TempSectionT[0]); try { TempChannel.InsertSection(TempSectionT,n_s); } catch (...) { throw; } /* H5TBread_table const int NSRECORDS = 1; */ const int NSFIELDS = 3; /* Calculate the size and the offsets of our struct members in memory */ size_t st_offset[NSFIELDS] = { HOFFSET( st, dt ), HOFFSET( st, xunits ), HOFFSET( st, yunits )}; st st_buf[1]; size_t st_sizes[NSFIELDS] = { sizeof( st_buf[0].dt), sizeof( st_buf[0].xunits), sizeof( st_buf[0].yunits)}; status=H5TBread_table( section_group, "description", sizeof(st), st_offset, st_sizes, st_buf ); if (status < 0) { std::string errorMsg("Exception while reading data description in stfio::importHDF5File"); throw std::runtime_error(errorMsg); } dt = st_buf[0].dt; yunits = st_buf[0].yunits; H5Gclose( section_group ); } try { if ((int)ReturnData.size() #if ( __WORDSIZE == 64 ) || defined (__APPLE__) #define CFSLONG int #else #define CFSLONG long #endif #include /* Needed for various types */ #include /* ditto */ #include /* for LDBL_DIG */ #if defined(WIN32) || defined (_MSC_VER) /* if its windows define our windows symbol */ #define _IS_WINDOWS_ /* WIN32 is defined for 32-bit at moment */ #undef _IS_MSDOS_ /* and we arent doing msdos after all */ #endif #ifdef _INC_WINDOWS /* the alternative windows symbolic defn */ #ifndef _IS_WINDOWS_ /* as above but _INC_WINDOWS is for 16 bit */ #define _IS_WINDOWS_ #endif #undef _IS_MSDOS_ /* and we arent doing msdos after all */ #endif #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) /* Now set up for windows use */ #include #define F_memcpy memcpy /* Define model-independent routines */ #define F_memmove memmove #define F_strlen strlen #define F_strcat strcat #define F_strcpy strcpy #define F_strcmp strcmp #define F_strncat strncat #define F_strncpy strncpy #define F_strncmp strncmp #define F_strchr strchr #define _fstrrchr strrchr #define _near /* stop compiler errors for 32 bit compile*/ #define DllExport __declspec(dllexport) #define DllImport __declspec(dllimport) typedef CFSLONG Coord; /* this is LONG in the MacApp definitions */ typedef double fdouble; #define FDBL_DIG DBL_DIG #define FDBL_MAX DBL_MAX typedef HGLOBAL THandle; #define F_malloc malloc #define F_free free #define M_AllocMem(x) GlobalAlloc(GMEM_MOVEABLE,x) #define M_AllocClear(x) GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,x) #define M_FreeMem(x) GlobalFree(x) #define M_LockMem(x) GlobalLock(x) #define M_MoveLockMem(x) GlobalLock(x) #define M_UnlockMem(x) (GlobalUnlock(x)==0) #define M_NewMemSize(x,y) (x = GlobalReAlloc(x,y,GMEM_MOVEABLE)) #define M_GetMemSize(x) GlobalSize(x) #else #define F_memcpy memcpy #define F_memmove memmove #define F_strlen strlen #define F_strcat strcat #define F_strcpy strcpy #define F_strcmp strcmp #define F_strncat strncat #define F_strncpy strncpy #define F_strncmp strncmp #define F_strchr strchr #define FAR #define PASCAL #define _far #define _near #define DllExport #define DllImport #define FDBL_DIG LDBL_DIG #define FDBL_MAX LDBL_MAX typedef char * LPSTR; typedef const char * LPCSTR; typedef unsigned short WORD; // typedef unsigned CFSLONG DWORD; typedef unsigned char BYTE; typedef long double fdouble; typedef CFSLONG Coord; /* Borrowed from MacApp */ typedef WORD THandle; #define F_malloc malloc #define F_free free #define M_AllocMem(x) NewHandle(x) #define M_AllocClear(x) NewHandleClear(x) #define M_FreeMem(x) DisposHandle(x) #define M_LockMem(x) (HLock(x),*x) #define M_MoveLockMem(x) (HLockHi(x),*x) #define M_UnlockMem(x) (HUnlock(x),TRUE) #define M_NewMemSize(x,y) (SetHandleSize(x,y),MemError() == 0) #define M_GetMemSize(x) GetHandleSize(x) #endif /*UNIX*/ #endif /* not defined __MACHINE__ */ stimfit-0.16.7/src/libstfio/cfs/cfslib.h0000775000175000017500000000331614750344764013563 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file cfslib.h * \author Christoph Schmidt-Hieber * \date 2008-01-23 * \brief Import from and export to the CED filing system. */ #ifndef _CFSLIB_H #define _CFSLIB_H #include "../stfio.h" class Recording; namespace stfio { //! Open a CFS file and store its contents to a Recording object. /*! \param fName Full path to the file to be read. * \param ReturnData On entry, an empty Recording object. On exit, * the data stored in \e fName. * \param progress Set to true if a progress dialog should be updated. * \return 0 upon success, a negative error code upon failure. */ int importCFSFile(const std::string& fName, Recording& ReturnData, ProgressInfo& progDlg); //! Export a Recording to a CFS file. /*! \param fName Full path to the file to be written. * \param WData The data to be exported. * \return The CFS file handle. */ StfioDll bool exportCFSFile(const std::string& fName, const Recording& WData, ProgressInfo& progDlg); } #endif stimfit-0.16.7/src/libstfio/cfs/cfs.c0000775000175000017500000060665214750344764013103 /***************************************************************************** ** ** MSC version of CFS functions ** ** Copyright (c) Cambridge Electronic Design Limited 1988 .. 1999 ** ** Started by J.Grayer 13th Oct 1990 ** ** V 2.11 Maximum file size upped to c. 1 GByte TDB 12-Jun-91 ** ** V 2.12 Changes made so data pointers changed to _far so that the ** user may use any model and still put large data items outside ** the default data segment. ** ** V 2.13 JG 17th Jan 1992 ** Re-jigged various things so all non_ANSI functions now appear in ** msio.h/c. ** Bug corrected in which table pointer did not get reset to NULL ** when a file was opened with the pointer table not in memory. ** Change made to SetComment so it can be used with a file opened in ** edit mode. ** Re-did the flag usage. ** When file opened in edit mode and nothing changed file not updated. ** Bug in recoverTable fixed. ** ** V 2.14 JG 8th Jun 1992 ** Small change to WriteData so it doesnt truncate the file if number ** of bytes to write is given as zero. ** (12th June v.minor change: added return statemnt to TransferTable ** function.) ** ** V 2.15 JG 24th Jun 1992 ** Change to GetChanData so you can read from the current data section ** provided you have called SetDSChan. ** ** V 2.16 TDB 24th Jul 1992 ** Changes to GetChanData (above) corrected. GetDSChan and GetHeader ** adjusted to work online. Began work on tidying code ** ** V 2.17 JCN 24-Aug-92 ** Added routine ClearDS to abandon current DS by setting dataSz back ** to 0 and resetting fileSz to dataSt. On closing the file no ** InsertDs will then be called and file will not include the empty ** data set. ** Commented out the calls to InternalError in GetMemTable. ** ** V 2.18 TDB 16-Sep-92 ** Removed InternalError calls from GetMemTable, fixed bug in ** GetMemTable, brought up to v 2.18. ** ** V 2.20 KJ 6-Jun-93, Version for DOS, WINDOWS and MACINTOSH. ** ** MAE - for macintosh definitions of OpenCFSFile & CreateCFSFile ** would be good idea to use FSSpec instead of 3 separate params ** for name, vRefNum & dirID. ** Also note that changing the type TSFlags from bit fields to ** a WORD has swapped the 2 flag bytes over on the macintosh, ** but not on the PC (Horace Townsends convertor programme no ** longer works.) ** May want to use FindFolder to get the temporary folder, and ** create the temporary files in that. ** ** V 2.20 KJ 14-Jul-93, ** Tidied up errors handling calls in OpenCFSFile, CloseCFSFile ** and TransferTable routines. ** ** V 2.30 KJ 01-Sep-93, ** CommitCFSFile function added. ** This is used to write the head and data sections info ** to to the disk file and to commit all the data currently ** in buffers for the given handle. ** Assert function implemented whereever possible. ** Error mechanism altered, so that all errors are logged ** so they can be retreived by FileError. ** ** V 2.31 TDB 02/Nov/93 ** Removed requirement for oldnames in link (now ANSII names ** throughout. Fixed GP faults caused by empty file. Tested ** with Visual Basic in DLL form, created Visual Basic Interface ** file. Altered Windows file I/O to use C LLIO (non-stream) ** mechanisms, as Windows _lopen set does not include set ** file length function! CFS16.MAK now uses large model. ** ** V 2.32 TDB 25/Feb/94 ** Redid CommitCFSFile so that all errors trapped, code for ** first error is code returned, and all errors logged using ** InternalError. ** ** V 2.33 TDB 07/Dec/95 ** Fixed trivial problems causing warnings in 32-bit build, now ** commit code uses correct close function (probably irrelevant) ** and MSVC make file etc for 32-bit build generated. Ensured ** that errors in Open/Create calls are passed to InternalError. ** ** V 2.40 TDB 02/May/96 ** Added CFSFileSize function. TDataKind changed to TCFSKind to ** prevent name clash with SON library. Extended file open checks ** to detect file too short to be a CFS file - get BADVER error ** instead of read error. ** ** V 2.41 TDB 16/May/96 ** Changed pointer parameters to const forms wherever appropriate. ** ** V 2.50 TDB 08/Nov/96 ** Changed GetVarVal, SetVarVal and DSFlags so that all of these ** can be used freely on new files, with 0 specifing the new DS ** and other section parameters specifying the DS as expected. ** ** V 2.51 TDB 12/May/97 ** Changed SetDSChan and WriteData as above, both can be used on ** all data sections of a new file, with DS set to 0 or n. ** ** V 2.52 TDB 27/May/98 ** Altered StoreTable so that it will increase the size of the ** memory table if necessary - for AppendDS. Also tidied up the ** AppendDS code. ** ** v 2.60 TDB 24/Feb/99 ** Switched to using non handle-based memory allocation (basically ** malloc) for WIN32 builds, file table is extended as required ** to allow unlimited numbers of open files. Now uses WIN32 file ** I/O functions as required, plus AppendDS has been fixed - it ** was not calling FileUpdate to get the pointer table off the end ** of the file - leading to corrupted files. ** ** v 2.61 TDB 28/Apr/99 ** Adjusted handling of DS table so that 32-bit build can handle ** up to 64000 data sections. Changed LoadData & FileData. ** ** v 2.62 SMP 16/Mar/00 ** ClearDS now returns a value when it succeeds! ** Fixed AppendDS so it now no longer produces a duff DSHeader ** if called multiple times ** ** v 2.63 SMP 04/Apr/00 ** Temp file name can now be up to 300 chars long. ** ** v 2.64 SMP 01/Jun/00 ** Buffer sizes >= 64k now work without crashing or inefficency in ** the 32 bit build. ** ** v 2.65 SMP 16/Aug/00 ** AppendDS no longer looses changes to the previously appended DS ** In particular the scaling factors are maintained. ** ** v 2.66 SMP 13/Mar/01 ** ASSERT definition changed to use _DEBUG and not DEBUG ** Meaningless ASSERT removed from AppendDS ** ** v 2.67 SMP 27/Feb/02 ** CreateCFSFile was trying to flag errors by setting a handle to ** -1. This wouldn't work under Windows so errors went unreported. ** ** v 2.68 SMP 17/Jan/03 ** Added SUBSIDIARY channel kind *****************************************************************************/ #include /* C library I/O functions */ #include /* C library type checking functions */ #include /* C library data conversion + misc functions */ #include /* C library time and date functions */ #include /* C library string function definitions */ /************************************************************************* ** ** These are the machine specific definitions and includes. Some of them ** are not really machine specific, but I've put them here anyway. first ** of all are the system defines, next machine global, finally specific ** ** Remove the NDEBUG definition to cause the asserts to be used ** The LLIO (low level i/o) should be undefined to use streams library and ** defined for low level. This is to make it a bit easier to implement the ** code on different machines which may not have the low level stuff. ** LLIO is defined in cfs.h and used in cfs.h and here ** ** ** macintosh and MSC are set by the compiler, and define machine type ** _IS_MSDOS_ set in machine.h for an msdos native mode build ** _IS_WINDOWS_ set in machine.h for windows 16 or 32 bit mode ** qDebug (mac)set by MPW to enable debug fprintf ** ** NDEBUG gets rid of the asserts. ** USEHANDLES To use memory handles in place of pointers. This form is ** supported by code generated for the Mac and Windows forms. ** Actually, it is ignored. ** ** LLIO (dos) if defined, low level I/O is used, otherwise streams. ** CFSCONVERT (mac) define if we should convert format (little-big endian) ** [convert (mac) specifies direction of conversion - for CfsConvert] ** ** #undef NDEBUG No asserts if this is defined ** */ #if defined(qDebug) || defined(_STFDEBUG) #undef NDEBUG #include #define ASSERT(x) assert(x) #else #define NDEBUG 1 #define ASSERT(x) #endif #include "cfs.h" /* Exported type, constant and function definitions */ #ifdef CFSCONVERT #include "CfsConv.h" #endif /* define some constants needed in the program */ #define INITCEDFILES 16 /* Initial file array length */ #define MAXCEDFILES 2048 /* Max no. files for WINDOWS */ #define NDATATYPE 8 /* number of data types defined in CFS */ #define NDATAKIND 3 /* number of data kinds defined in CFS */ #define MAXCHANS 100 /* max number of channels of data in CFS file */ #define MAXFILVARS 100 /* max File varaibles in CFS file */ #define MAXDSVARS 100 /* max data Sections in CFS file */ #define MAXSTR 256 /* max CFS string length including NULL */ #define CEDMARKER "CEDFILE\"" /* Version 1 marker */ #define PARTMARK "CEDFILE" /* Marker for testing old files */ #define MAXLSEEK 2000000000 /* Roughly 2 GByte, the maximum file size */ #define MAXFORWRD 65535 /* maximum value for unsigned short */ #define MAXNODS 64000 /* alloc restrictions are looser for WIN32 */ #define MAXMEMALLOC 65519 /* get problems if try to allocate more */ #define WHOLEFILECHARS 1024/* to hold whole of temp file name including path */ #define MARKERCHARS 8 /* characters in file marker */ #define PARTMARKCHARS 7 /* characters to test for old version file */ #define MAXFNCHARS 1024 /* characters to test for file name */ /* define error codes */ #define NOHANDLE -1 #define BADHANDLE -2 #define NOTWRIT -3 #define NOTWORE -4 #define NOTWORR -5 #define NOTOPEN -6 #define BADVER -7 #define NOMEMR -8 #define BADCREAT -11 #define BADOPEN -12 #define READERR -13 #define WRITERR -14 #define RDDS -15 #define WRDS -16 #define DISKPOS -17 #define BADINS -18 #define BADFL -19 #define BADDESC -20 #define BADPAR -21 #define BADCHAN -22 #define XSDS -23 #define BADDS -24 #define BADKIND -25 #define BADVARN -26 /* to convert marker char to old version number */ #define BADDSZ -27 #define BADOLDVER -39 /* define file access mode */ #define rMode 0 /* READ only */ #define wMode 2 /* WRITE only */ #define rwMode 0 /* READ|WRITE used to open new file */ /* define types which give data structure of CFS file */ typedef char TBigName[WHOLEFILECHARS+2]; /* for temp file name */ typedef char TMarker[MARKERCHARS]; /* for CED file marker */ #pragma pack(1) /* 1. for file header (fixed) channel information */ typedef struct { TDesc chanName; /* users name for channel, 20 chars */ TUnits unitsY; /* name of Yunits 8 chars */ TUnits unitsX; /* name of xunits 8 chars */ TDataType dType; /* storage type 1 of 8 allowed */ TCFSKind dKind; /* equalspaced, matrix or subsidiary */ short dSpacing; /* bytes between elements */ short otherChan; /* used for matrix data */ } TFilChInfo; typedef TFilChInfo TFilChArr[MAXCHANS]; /* 2. for data section (may vary with DS) channel information */ typedef struct { CFSLONG dataOffset; CFSLONG dataPoints; float scaleY; float offsetY; float scaleX; float offsetX; } TDSChInfo; typedef TDSChInfo TDSChArr[MAXCHANS]; /* 3. for data section headers */ typedef struct { CFSLONG lastDS; /* offset in file of header of previous DS */ CFSLONG dataSt; /* data start position */ CFSLONG dataSz; /* data size in bytes */ TSFlags flags; /* flags for this section */ short dSpace[8]; /* spare space */ TDSChArr DSChArr; /* array of DS channel info */ } TDataHead; /* 4. for the file header */ typedef struct { TMarker marker; TFileName name; CFSLONG fileSz; char timeStr[8]; char dateStr[8]; short dataChans; /* number of channels of data */ short filVars; /* number of file variables */ short datVars; /* number of data section variables */ short fileHeadSz; short dataHeadSz; CFSLONG endPnt; /* offset in file of header of last DS */ WORD dataSecs; /* number of data sections */ WORD diskBlkSize; /* usually 1 or 512 */ TComment commentStr; CFSLONG tablePos; /* offset in file for start of table of DS header offsets */ short fSpace[20]; /* spare */ TFilChArr FilChArr; /* array of fixed channel info */ } TFileHead; #pragma pack() #if !defined(_IS_WINDOWS_) || defined(__MINGW32__) typedef TFileHead * TpFHead; /* pointer to start of file header */ typedef TDataHead * TpDHead; /* pointer to start of data header */ typedef TDSChInfo * TpDsInfo; typedef TFilChInfo * TpChInfo; #else typedef TFileHead FAR * TpFHead; /* pointer to start of file header */ typedef TDataHead FAR * TpDHead; /* pointer to start of data header */ typedef TDSChInfo FAR * TpDsInfo; typedef TFilChInfo FAR * TpChInfo; #endif typedef enum /* define types to describe file in program */ { reading, writing, editing, nothing } TAllowed; typedef struct { fDef p ; /* file handle */ fDef d ; /* file handle */ } TDOSHdl; typedef struct { TpVDesc nameP; /* pointers to start of variable descriptions */ TpSStr dataP; /* pointers to corresponding data storage */ } TPointers; typedef struct /* for storing and sending back current error information */ { short eFound; short eHandleNo; short eProcNo; short eErrNo; } TError; typedef struct /* For program to keep track of storage locations */ { TAllowed allowed; /* current state of this set of TFileInfo */ // THandle fHeadH; /* handle to area for file head */ // THandle dHeadH; /* handle to area for data section */ // THandle eHeadH; /* handle to area for insert data section */ // THandle tableH; /* handle to area for offsets of ds headers */ TpFHead fileHeadP; /* to storage allocated for general header */ TpDHead dataHeadP; /* to storage allocated for data section header */ TpDHead extHeadP; /* to storage allocated for Insert data section */ TPointers FVPoint; /* to descriptions and values of file variables */ TPointers DSPoint; /* to descrip and values of data section variables */ TpLong tableP; /* array of offsets in the file of the DS headers */ TDOSHdl DOSHdl; TBigName tempFName; WORD thisSection; short DSAltered; } TFileInfo; /*********************** CFS FILE STRUCTURE ***************************** ** ** The file header consist of a struct of type TFileHead less the final ** array which is replaced by fixed info array for each channel + file and ** DS vraiable descriptions + byte array containing values of the file data ** variables. ** The file also contains the channel data and the data sections. How these ** are arranged in the file is not defined. Each data section (DS) consists ** of a struct of type TDataHead less the final array which is replaced by ** DS info array for each cahnnel + byte array containing values of the DS ** data variables for that DS. ** The position and size of the actual channel data is in the DS header. ** At the end of the file is a table of pointers to the start of each DS. ** *****************************************************************************/ /**************************************************************************** ** ** Global Variables Declaration and Initialisation ** NB declare near so they go in the default data segment. ** ** 1. Declare pointer to FileInfo and initialise to null, set global ** array length info to zero. ** *****************************************************************************/ int g_maxCfsFiles = 0; /* The length of the array of file info */ TFileInfo* g_fileInfo = NULL; /**************************************************************************** ** ** 2. Declare an error structure and initialise all fields to zero. ** *****************************************************************************/ #if !defined(_IS_WINDOWS_) || defined(__MINGW32__) TError errorInfo = {0,0,0,0}; #else TError _near errorInfo = {0,0,0,0}; #endif char gWorkStr[MAXFNCHARS]; /* Global var on DS to avoid DLL SS != DS problems */ /* Local function definitions */ static void CleanUpCfs(void); static short FindUnusedHandle(void); static short SetSizes(TpCVDesc theArray,TpShort offsetArray,short numVars); static void TransferIn(TpCStr olds,TpStr pNew,BYTE max); static void TransferOut(TpCStr olds,TpStr pNew,BYTE max); static void SetVarDescs(short numOfVars,TPointers varPoint, TpCVDesc useArray,TpShort Offsets,short vSpace); static CFSLONG BlockRound(short handle,CFSLONG raw); static void InternalError(short handle,short proc,short err); static short GetHeader(short handle,WORD getSection); static short FileData(short handle, TpVoid startP, CFSLONG st, CFSLONG sz); static short LoadData(short handle, TpVoid startP, CFSLONG st, CFSLONG sz); static CFSLONG GetTable(short handle, WORD position); static void StoreTable(short handle,WORD position,CFSLONG DSPointer); static short RecoverTable(short handle,TpLong relSize,TpLong tPos, TpUShort dSecs,TpLong fSize); static short TransferTable(WORD sects, fDef rdHdl, fDef wrHdl); static short GetMemTable(short handle); static TpStr AllocateSpace(TpUShort sizeP, WORD steps); static void ExtractBytes(TpStr destP,WORD dataOffset, TpStr srcP,WORD points,WORD spacing,WORD ptSz); static short FileUpdate(short handle,TpFHead fileHP); /* Function definitions for IO functions . */ static short TempName(short handle,TpCStr name,TpStr str2, unsigned str2len); static short CCreat(TpCStr name, short mode, fDef* pFile); static short CUnlink(TpCStr path); static short COpen(TpCStr name, short mode, fDef* pFile); static short CCloseAndUnlink(fDef handle, TpCStr path); static CFSLONG CGetFileLen(fDef handle); static short CClose(fDef handle); static CFSLONG CLSeek(fDef handle, CFSLONG offset, short mode); static WORD CReadHandle(fDef handle,TpStr buffer, WORD bytes); static WORD CWriteHandle(fDef handle,TpStr buffer, WORD bytes); static void CMovel(TpVoid dest,const TpVoid src, int count); static short CSetFileLen(fDef handle, CFSLONG size); static TpVoid CMemAllcn(int size); static void CFreeAllcn(TpVoid p); static void CStrTime(char *timeStr); static void CStrDate(char *dateStr); /************************************************************************** ** ** Function definitions for IO functions . ** Set of C functions which call the MS ones in io.h ** THESE FUNCTIONS ARE FOR BINARY FILES. ** Changes made and memory allocation functions added to force FAR pointers ** ***************************************************************************/ /************************* CCreat ******************************** ** ** CCreat. This is very like the Pascal equiv in MSDOSLIB CREAT but only ** modes allowed are 0 Read/Write, 1 Read only ** ** Either creates a new file or opens and truncates an existing one. ** The mode is applied to newly opened files only. It sets the allowed ** file access after the file has been closed. ** ** On the Mac we have to explicitly create a new file before opening it ** If the file exists, we must truncate it. Then set the file type and ** creator. ** ** Return is handle value or -ve error code. ** ***************************************************************************/ short CCreat(TpCStr name, short mode, fDef* pFile) { short sErr = 0; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) DWORD dwMode; #else short pmode; char fname[MAXFNCHARS]; /* To get near variable holding string */ #endif fDef file; /* The various types of file handle */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) if (mode) /* Sort out the file access value */ dwMode = GENERIC_READ; else dwMode = GENERIC_READ | GENERIC_WRITE; file = CreateFileA(name, dwMode, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) sErr = BADCREAT; #else if (mode) pmode = S_IREAD; else pmode = S_IREAD|S_IWRITE; char* omode; if (mode) /* Sort out the file access value */ omode = "r"; else omode = "w+"; if (strlen(name) < MAXFNCHARS) F_strcpy(fname, name); /* Get filename in near var */ file = fopen(fname,omode); if (file == 0) sErr = -1; #endif if (sErr == 0) *pFile = file; return sErr; } /* end of CCreat */ /******************* 2. CUnlink for deleteing files. *********************** ** ** Delete file specified by path. Return 0 if ok, -ve error code ** ****************************************************************************/ short CUnlink(TpCStr path) { #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) int a; a = _unlink(path); /* C function in io.h */ if (a < 0) return (short)(0 - _doserrno); else return 0; #else return remove(path); /* C function in io.h */ #endif } /************* 3. CClose for closing files given DOS handle **************** ** ** Close the file associated with handle. ** Return 0 if ok or -ve error code. ** ****************************************************************************/ short CClose(fDef handle) { int res = 0; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) if (!CloseHandle(handle)) res = BADHANDLE; #else res = fclose(handle); #endif return (short)res; } /* end of CClose */ /************* CCloseAndUnlink closes then deletes the file **************** ** ** Closes the file associated with handle, and then deletes it ** Return 0 if ok or -ve error code. ** ****************************************************************************/ short CCloseAndUnlink(fDef handle, TpCStr path) { short err = 0; err = CClose(handle); #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) err = CUnlink(path); #else err += CUnlink(path); #endif return err; } /************* 4. CLSeek for moving file pointer *************************** ** ** Move the file pointer (ie. next position for read/write) by offset bytes ** in file with DOShandle handle from a start position depending on mode. ** Returns new file position or -ve error code ** *****************************************************************************/ CFSLONG CLSeek(fDef handle, /* DOS handle of file */ CFSLONG offset, /* amount to move in bytes */ short mode) /* 0 Move from file start 1 Move from current file position 2 Move from file end */ { #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) /* Windows seek */ CFSLONG res = 0; DWORD dwMode; switch (mode) { case 0 : dwMode = FILE_BEGIN; /* start of file */ break; case 1 : dwMode = FILE_CURRENT; /* current posn of file pointer */ break; case 2 : dwMode = FILE_END; /* end of file */ break; } res = SetFilePointer(handle, offset, NULL, dwMode); if (res == 0xFFFFFFFF) return DISKPOS; else return res; #else CFSLONG res; short origin = 0; switch (mode) { case 0 : origin = SEEK_SET; /* start of file */ break; case 1 : origin = SEEK_CUR; /* current position of file pointer */ break; case 2 : origin = SEEK_END; /* end of file */ break; } res = fseek (handle, offset, origin); /* stdio read */ if (res==0) { return ftell(handle); } else { return -1; } #endif } /* end of CLSeek */ /******************** 5. Transfer from file to buffer ********************** ** ** Transfer from current file position of file, specified by its DOS file ** handle, to the buffer the specified number of bytes.(counted from file) ** Return the number of bytes transferred to the buffer or zero if error. ** NB C Function _dos_read can have been successful and NOT give numread=bytes ** It can have read numread bytes then found EOF or the file can be text ** in which case CRLF is counted as 2 bytes in the file but only ** 1 byte (LF) in numread. ** *****************************************************************************/ WORD CReadHandle(fDef handle, TpStr buffer, WORD bytes) { #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) DWORD dwRead; if (ReadFile(handle, buffer, bytes, &dwRead, NULL)) return bytes; else return 0; #else if (fread(buffer,1,bytes,handle) != bytes) return 0; else return bytes; #endif }; /******************** 6. Transfer from buffer to file ********************** ** ** Transfer to current file position of file, specified by its DOS file ** handle, from the buffer the specified number of bytes. ** Return the number of bytes transferred from the buffer or zero if error. ** NB C Function _dos_write can have been successful and NOT give numwrt=bytes ** It can have written numwrt bytes then run out of disk space. ** If the file is of type text LF in the buffer is replaced by 2 bytes ** CRLF but numwrt is unchanged since it refers to the buffer bytes. ** *****************************************************************************/ WORD CWriteHandle(fDef handle, TpStr buffer, WORD bytes) { #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) DWORD dwWrit; if (WriteFile(handle, buffer, bytes, &dwWrit, NULL)) return bytes; else return 0; #else if (fwrite(buffer, 1, bytes, handle) != bytes) return 0; else return bytes; #endif } /* end of CWriteHandle */ /******************** 7. Memory transfer *********************************** ** ** Transfer count bytes from src to dest addresses. ** memcpy is used so any overlap of regions is not checked. ** *****************************************************************************/ void CMovel(TpVoid dest, const TpVoid src, int count) { TpVoid ret; /* for return pointer of memcpy */ ret = F_memcpy(dest,src,(size_t)count); /* C function from string.h */ return; }; /* end of CMovel */ /****** 8. Change file size. NB operates on file handle NOT file name *****/ short CSetFileLen(fDef handle, CFSLONG size) /* ** For a file specified by its DOS handle, extend or truncate file to length, ** in bytes, specified by size. File must be open for writing. ** Return 0 if successful, -DOS error code if not. */ { #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) if (SetFilePointer(handle, size, NULL, FILE_BEGIN) != 0xFFFFFFFF) if (SetEndOfFile(handle)) return 0; else return BADHANDLE; else return DISKPOS; #else return -1; #endif } /* end of CSetFileLen */ /****** 8a. Retrieve file size. NB operates on file handle NOT file name *****/ CFSLONG CGetFileLen(fDef pFile) /* ** For a file specified by its DOS handle, find the file size in bytes. ** Returns file size if successful, -DOS error code if not. */ { CFSLONG lSize; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) lSize = GetFileSize(pFile, NULL); if (lSize != -1) return lSize; else return BADHANDLE; #else fpos_t cur; if (fgetpos(pFile,&cur)!=0) return -1; if (fseek (pFile, 0, SEEK_END)!=0) return -1; lSize=ftell (pFile); if (fsetpos(pFile,&cur)!=0) return -1; return lSize; #endif } /* end of CGetFileLen */ /************** 9.Open an exisiting file of specified name ***************** ** ** Open file specified by its path. ** For mode = 0 Read only (default) ** = 1 Write only ** = 2 Read/Write. ** Return DOS file handle if ok DOS error code (-ve) if not. ** ** for the mac, we need vRefNum, which we hope to get from stdFile SFGetFile ** also we want to make sure we have a pascal string ** *****************************************************************************/ short COpen(TpCStr name, short mode, fDef* pFile) { short sRes = 0; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) fDef file; DWORD dwMode; switch (mode) /* use C library constants to set mode */ { case 1 : dwMode = GENERIC_WRITE; break; case 2 : dwMode = GENERIC_READ | GENERIC_WRITE; break; default: dwMode = GENERIC_READ; break; } file = CreateFileA(name, dwMode, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) sRes = BADOPEN; if (sRes == 0) *pFile = file; #else char fname[MAXFNCHARS]; /* To get near variable holding string */ char* omode; switch (mode) /* use C library constants to set mode */ { case 1 : omode = "w"; break; case 2 : omode = "r+"; break; default: omode = "r"; break; } if (strlen(name) < MAXFNCHARS) F_strcpy(fname, name); /* Get filename in near var */ *pFile = fopen(fname,omode); if (*pFile == 0) sRes = -1; #endif return sRes; } /************** 10. Allocate memory on the far heap ************************ ** ** Allocate size bytes of memory outside the default data segment and ** return a far pointer to it. ** *****************************************************************************/ TpVoid CMemAllcn(int size) { TpVoid p; p = F_malloc(size); /* Use a simple, non-handle based, allocation */ // if ((*dummy = (THandle) M_AllocMem(size)) != NULL) // p = M_MoveLockMem(*dummy); // else // p = NULL; return p; } /*************** 11.Free memory allocated by above function **************** ** ** Free memory allocated on far heap by _fmalloc. ** No return. ** *****************************************************************************/ void CFreeAllcn(TpVoid p) { F_free(p); /* Simple memory free mechanism */ // if (M_UnlockMem(*dummy)) // M_FreeMem(*dummy); } /*************** 12. Get the time as string in required format ************* ** ** Gets time formatted as hh:mm:ss. ** timeStr must be at least 9 bytes ** *****************************************************************************/ void CStrTime(char *timeStr) { #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) _strtime(timeStr); /* timsStr must be at least 9 bytes */ #else time_t now; struct tm *today; now = time(NULL); today = localtime(&now); strftime(timeStr, 9, "%H:%M:%S", today); #endif } /* end of CStrTime */ /************ 13. Get the date as string in the required format *********** ** ** gets the date formatted as dd/mm/yy. ** dateStr must be at least 9 bytes ** *****************************************************************************/ void CStrDate(char *dateStr) { #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) char sdata[9]; _strdate(dateStr); /* dateStr must be at least 9 bytes */ F_strncpy(sdata,dateStr,8); /* store time without NULL */ sdata[0] = dateStr[3]; sdata[1] = dateStr[4]; sdata[3] = dateStr[0]; sdata[4] = dateStr[1]; F_strncpy(dateStr,sdata,8); /* store time without NULL */ #else time_t now; struct tm *today; now = time(NULL); today = localtime(&now); strftime(dateStr, 9, "%d/%m/%y", today); #endif } /* end of CStrDate */ /*********************** CreateCFSFile ******************************** ** ** Function to create CFS file open it for writing and allocate storage ** space for header and data section structures ready to fill and write to ** the file when ready. ** ** On the Mac we have to explicitly create a new file before opening it ** If the file exists, we must truncate it. Then set the file type and ** creator. ** Returns file handle or -ve error code. ** *****************************************************************************/ CFSAPI(short) CreateCFSFile(TpCStr fname, /* name of file */ TpCStr comment, /* general comment */ WORD blockSize, /* 1 or 512 */ short channels, /* number of data channels */ TpCVDesc fileArray,/* file variable descriptions */ TpCVDesc DSArray, /* DS variable descriptions */ short fileVars, /* no. of file varables */ short DSVars) /* no. of DS variables */ { short proc = 18; /* function number for error record */ short retval; /* return value */ short sErr; /* for checking return codes */ short handle; /* CFS file handle */ WORD bytSz; /* used to calcualte space needed when allocating */ short search; /* loop varable */ short pathend = 0; /* end of path part of fname */ short filVarSpace; /* space needed for file and DS variable data */ short DSVarSpace; TpShort filOffsets; /* temp store offsets */ TpShort DSOffsets; /* temp store offsets */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif /* pointer for current files info in global array */ TpFHead pFileH; /* used to shorten pointers */ TpDHead pDataH; TpChInfo pFilChInfo; TpDsInfo pDSChInfo; /* 1. Get program file handle */ handle = FindUnusedHandle(); /* 0,1,2 or error */ if (handle < 0) { retval = NOHANDLE; /* error code for no spare handles */ InternalError(handle,proc,retval); return retval; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* 2. Open file for writing */ sErr = CCreat(fname, rwMode, &pfileInfo->DOSHdl.d);/* Open data file */ if (sErr != 0) { pfileInfo->DOSHdl.d = (fDef)-1; retval = sErr; /* error code for unopenable file */ InternalError(handle,proc,retval); return retval; } TempName(handle, fname, pfileInfo->tempFName, WHOLEFILECHARS+2); /* get temp file name */ sErr = CCreat(pfileInfo->tempFName, rwMode, &pfileInfo->DOSHdl.p); if (sErr != 0) { pfileInfo->DOSHdl.p = (fDef)-1; retval = sErr; goto Close_1; /* close CFS file before return */ } /* open temp file */ /* 3. Get space for file,DS and spare headers */ /* ** error code for problem with file or Ds variable sizing. ** allocate some space for the offset arrays used by SetSizes, there is ** allways 2 bytes of space allocated to avoid problem when either of ** these two equals 0 */ DSOffsets = (TpShort)CMemAllcn((2*DSVars+2)); filOffsets = (TpShort)CMemAllcn((2*fileVars+2)); if ((DSOffsets == NULL) || (filOffsets == NULL)) { retval = NOMEMR; goto Close0; } /* ** setsizes computes the total space needed to store the variables described ** and sets up an offset array which says whereabouts each variables would ** start if you stored all the variables in a byte list */ DSVarSpace = SetSizes(DSArray, DSOffsets, DSVars); filVarSpace = SetSizes(fileArray, filOffsets, fileVars); if ((filVarSpace < 0) || (DSVarSpace < 0)) { retval = BADDESC; goto Close0; } /* File header size consists of */ bytSz = (WORD)(sizeof(TFileHead) - sizeof(TFilChArr) + /* File header without array */ channels*sizeof(TFilChInfo) + /* Info for each channel */ ((fileVars+DSVars+2) * sizeof(TVarDesc)) + /* desc for each var */ filVarSpace); /* space computed for actual file variables */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) if (bytSz > (WORD)MAXMEMALLOC) { retval = NOMEMR; /* error code for not enough space */ goto Close0; /* dont attempt to allocate over max */ } #endif pfileInfo->fileHeadP = (TpFHead)CMemAllcn(bytSz); /* allocate space for file header */ pFileH = pfileInfo->fileHeadP; if (pFileH == NULL) { retval = NOMEMR; /* error code for not enough space */ goto Close0; /* clear up files before return */ } pFileH->fileHeadSz = (short)bytSz;/* save space in bytes for file head */ pFileH->diskBlkSize = blockSize; /* store blocksize specified */ /* ** Now do the Data Section header size */ bytSz = (WORD)(sizeof(TDataHead) - sizeof(TDSChArr) + /* Data header without array */ (channels * sizeof(TDSChInfo))+ /* Info for each channel */ DSVarSpace); /* DS varable data space */ /* round to nearest block */ bytSz = (WORD)(((bytSz+(WORD)(blockSize-1)) / blockSize)*blockSize); #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) if (bytSz>(WORD)MAXMEMALLOC) { retval = NOMEMR; goto Close1; } #endif pfileInfo->dataHeadP= (TpDHead)CMemAllcn(bytSz); /* allocate space for DS header */ pDataH = pfileInfo->dataHeadP; if (pDataH == NULL) { retval = NOMEMR; goto Close1; /* release file and allocated file header */ } pFileH->dataHeadSz = (short)bytSz; /* store DS header size in bytes */ pfileInfo->extHeadP = (TpDHead)CMemAllcn(bytSz); /* space for insert block (another DS header) */ if (pfileInfo->extHeadP == NULL) { retval = NOMEMR; goto Close2; /* release file,fileheader,data header */ } /* 4. Store variables in header checking range */ retval = BADPAR; /* error code for out of range */ if ( (channels < 0) || (fileVars < 0) || (DSVars < 0) || (channels >= MAXCHANS) || (fileVars >= MAXFILVARS) || (DSVars >= MAXDSVARS) ) { retval = NOMEMR; goto Close3; /* Release file file header data header insert block */ } pFileH->filVars = fileVars; /* store specified number of file vars */ pFileH->datVars = DSVars; /* store number of data section vars */ pFileH->dataChans= channels; /* store specified number of data channels */ /* 5. Set pointers to within spaces allocated to start of various items */ /* The fixed channel information following the general occupies fileChArr[channels] and the space straight after this is for the descrition of the file variables. */ pfileInfo->FVPoint.nameP = (TpVDesc)(pFileH->FilChArr+channels); /* The fixed file variable descriptions occupy nameP[filvars+1] and the data section variables start after them. */ pfileInfo->DSPoint.nameP = pfileInfo->FVPoint.nameP+fileVars+1; /* The data section variable descriptions occupy nameP[DSVars+1] then come the actual file variables */ pfileInfo->FVPoint.dataP = (TpSStr)(pfileInfo->DSPoint.nameP + DSVars+1); /* The actual data section variables are part of the data header (not fileheader) and come straight after the data section channel info */ pfileInfo->DSPoint.dataP = (TpSStr)(pDataH->DSChArr + channels); /* 6. Store default values in data structure structs */ /* Fixed channel information in File Header */ for (search = 0;search < channels;search++) { pFilChInfo = pFileH->FilChArr+search; /* pointer to relevant chan info */ /* Put null strings in Chan name and units */ TransferIn("", pFilChInfo->chanName, 0); TransferIn("", pFilChInfo->unitsY, 0); TransferIn("", pFilChInfo->unitsX, 0); pFilChInfo->dType = INT2; /* default type is integer */ pFilChInfo->dKind = EQUALSPACED; pFilChInfo->dSpacing = 2; /* integers stored in sequence */ pFilChInfo->otherChan= 0; } /*************************************************************************** ** Fixed file variables in the File header ** Copy the variable descriptions to the space allocated (which is in the ** form of variable description structs) storing the offsets in the data ** array for each variable value in the vsize field ****************************************************************************/ SetVarDescs(fileVars,pfileInfo->FVPoint,fileArray,filOffsets,filVarSpace); /* Data section variables descriptions */ SetVarDescs(DSVars,pfileInfo->DSPoint,DSArray,DSOffsets,DSVarSpace); /* Now fill in as much as poss of header block */ pDataH->lastDS = 0; /* no data section there yet */ /* lastDS of zero means the fileheader is the 'previous' DS */ pDataH->dataSt = BlockRound(handle,(CFSLONG)pFileH->fileHeadSz);/*round up */ pFileH->fileSz = pDataH->dataSt; /* reset so they are consistent */ pDataH->dataSz = 0; /* fill in later */ pDataH->flags = noFlags; /* start with no flags */ for (search = 0;search < 8;search++) pDataH->dSpace[search] = 0; /* zero spare space */ /* Initialise channel information */ for (search = 0; search < channels; search++) { pDSChInfo = pDataH->DSChArr + search; pDSChInfo->dataOffset = 0; /* no data there yet */ pDSChInfo->dataPoints = 0; pDSChInfo->scaleY = (float)1.0; pDSChInfo->offsetY = (float)0.0; pDSChInfo->scaleX = (float)1.0; pDSChInfo->offsetX = (float)0.0; } TransferIn(comment,pFileH->commentStr,COMMENTCHARS); /* users comment in LSTRING form */ F_strncpy(pFileH->marker,CEDMARKER,MARKERCHARS); /* marker with no NULL */ CStrTime(gWorkStr); /* time + NULL */ F_strncpy(pFileH->timeStr,gWorkStr,8); /* store time without NULL */ CStrDate(gWorkStr); /* date + NULL */ F_strncpy(pFileH->dateStr,gWorkStr,8); /* store date without NULL */ pFileH->dataSecs = 0; /* No DS yet */ pfileInfo->tableP = NULL; /* table giving file offsets for each DS header is not in memory */ pFileH->tablePos= 0; /* position in file where DS offsets table starts */ pFileH->endPnt = 0;/* this will hold the offset of the final DS header */ pfileInfo->allowed = writing; /* file now opened */ pfileInfo->thisSection= 0xFFFF; /* not used in writing mode */ for (search = 0;search < 20; search++) pFileH->fSpace[search] = 0; /* zero spare space */ pfileInfo->DSAltered = 0; /* initialise to 0 so that GetHeader does not write the DS header to file.(InsertDS is only valid way to do this for a new file. */ errorInfo.eFound = 0; /* no filing errors yet */ #if defined(_IS_MSDOS_) || defined(_IS_WINDOWS_) /* In file header store the file name without a path or leading spaces in LSTRING format */ search = 0; /* find 1st non space TpStr */ while (isspace(fname[search])) search++; pathend = (short)(search-1); /* If there is no path in fname it ends before the start */ /* look for last occurrence of '\\' or ':' */ while (search<(short)F_strlen(fname)) { if ((fname[search] == '\\') || (fname[search] == ':')) pathend = search; search = (short)(search + 1); } TransferIn(&fname[pathend+1],pFileH->name,FNAMECHARS); #endif /* return space allocated for temp arrays of affsets */ CFreeAllcn(filOffsets); CFreeAllcn(DSOffsets); return handle; /* all ok so return the file handle */ /* ** Here for the general error handling. Tidy up and return error code, ** also calling Internal Error so that any errors are remembered. */ Close3: CFreeAllcn(pfileInfo->extHeadP); /* free mem for data insert */ pfileInfo->extHeadP = NULL; Close2: CFreeAllcn(pfileInfo->dataHeadP); /* and for data header */ Close1: CFreeAllcn(pfileInfo->fileHeadP); /* and for file header */ Close0: CCloseAndUnlink(pfileInfo->DOSHdl.p, pfileInfo->tempFName); /* delete temp file */ CFreeAllcn(filOffsets); /* release space for offset arrays */ CFreeAllcn(DSOffsets); Close_1: if (strlen(fname) < MAXFNCHARS) F_strcpy(gWorkStr,fname); /* Get file name into global var */ CCloseAndUnlink(pfileInfo->DOSHdl.d, gWorkStr); /* delete empty CFS file */ InternalError(handle,proc,retval); return retval; /* retval is error code */ } /* end of CreatCFSFile */ /************************ SetFileChan ******************************** ** ** Set the channel information that stays same throughout file and goes ** in the file header. ** *****************************************************************************/ CFSAPI(void) SetFileChan(short handle, /* program file handle */ short channel, /* channel numb in CFS storage */ TpCStr channelName, /* users identifier for channel */ TpCStr yUnits, /* users name for units */ TpCStr xUnits,/* only for equal spaces often s */ TDataType dataType, /* one of 8 types */ TCFSKind dataKind, /* one of 2 kinds */ short spacing, /* bytes between equal spaced elements */ short other) /* next channel for matrix data */ { short proc = 1; /* function number for error record */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif /* to point to set of file info with given handle */ TpChInfo pFilChInfo; /* to point to this channels info structure */ short ecode; /* for return of FileUpdate */ ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(channel >= 0); ASSERT(channel < g_fileInfo[handle].fileHeadP->dataChans); ASSERT(dataType >= 0); ASSERT(dataType < NDATATYPE); ASSERT(dataKind >= 0); ASSERT(spacing >= 0); ASSERT((g_fileInfo[handle].allowed == writing) || (g_fileInfo[handle].allowed == editing)); /* 1. Check valid handle given and that its file is open for write/edit */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if ((pfileInfo->allowed == writing) || (pfileInfo->allowed == editing)) { /* 2. Check channel number in range */ if ((channel < 0) || (channel >= pfileInfo->fileHeadP->dataChans)) { InternalError(handle,proc,BADCHAN); return; } /* Additional checks on parameters dataType and dataKind */ if ((dataType < 0) || (dataType >= NDATATYPE)) { InternalError(handle,proc,BADPAR); return; } if ((dataKind < 0) || (dataKind >= NDATAKIND)) { InternalError(handle,proc,BADKIND); return; } if ((spacing < 0) || ((dataKind == MATRIX) && (other < 0))) { InternalError(handle,proc,BADPAR); return; } /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->allowed == editing) && (pfileInfo->fileHeadP->tablePos != 0)) { ecode = FileUpdate(handle,pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle,proc,ecode); return; } } /* channels info parameters look reasonable so fill them in */ pFilChInfo = pfileInfo->fileHeadP->FilChArr + channel; /* pick out chan */ TransferIn(channelName,pFilChInfo->chanName,DESCCHARS); TransferIn(yUnits,pFilChInfo->unitsY,UNITCHARS); TransferIn(xUnits,pFilChInfo->unitsX,UNITCHARS); pFilChInfo->dType = dataType; pFilChInfo->dKind = dataKind; pFilChInfo->dSpacing = spacing; pFilChInfo->otherChan = other; } else InternalError(handle,proc,NOTWORE); /* failed allowed test */ return; } /* end of SetFileChan */ /************************** SetDSChan ******************************** ** ** Sort out the data section channel info ie the bit that can change ** with data section. ** *****************************************************************************/ CFSAPI(void) SetDSChan(short handle, /* program file handle */ short channel, /* CFS channel number */ WORD dataSection, /* reference when editing */ CFSLONG startOffset, /* byte offset to 1st element */ CFSLONG points, /* number of channel elements */ float yScale, /* data scale */ float yOffset, float xScale, float xOffset) { short proc = 2; /* number for this function */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpDsInfo pDSChInfo; short ecode; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT((g_fileInfo[handle].allowed == writing) || (g_fileInfo[handle].allowed == editing)); ASSERT(channel >= 0); ASSERT(channel < g_fileInfo[handle].fileHeadP->dataChans); /* 1. Is Handle ok */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return; } /* 1a. Is file open for writing/editing */ pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if ((pfileInfo->allowed == writing) || (pfileInfo->allowed == editing)) { /* 2. Check channel number */ if ((channel < 0) || (channel >= pfileInfo->fileHeadP->dataChans)) { InternalError(handle,proc,BADCHAN); return; } /* 3. Check data section number if editing and read in its header from the CFS file */ if (pfileInfo->allowed == editing) { if ((dataSection<1)||(dataSection>pfileInfo->fileHeadP->dataSecs)) { InternalError(handle,proc,BADDS); return; } ecode = GetHeader(handle,dataSection); if (ecode != 0) { InternalError(handle,proc,ecode); return; } } else { if (/*(dataSection<0)||*/(dataSection>pfileInfo->fileHeadP->dataSecs)) { InternalError(handle,proc,BADDS); return; } if (dataSection > 0) { CMovel(pfileInfo->extHeadP, pfileInfo->dataHeadP, /* Save current DS header */ pfileInfo->fileHeadP->dataHeadSz); ecode = GetHeader(handle, dataSection); /* Read in wanted */ if (ecode != 0) { InternalError(handle,proc,ecode); goto Restore; } } } /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->allowed == editing) && (pfileInfo->fileHeadP->tablePos != 0)) { ecode = FileUpdate(handle,pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle,proc,ecode); return; } } /* Store information from function parameters in program */ pDSChInfo = pfileInfo->dataHeadP->DSChArr + channel; pDSChInfo->dataOffset = startOffset; pDSChInfo->dataPoints = points; pDSChInfo->scaleY = yScale; pDSChInfo->offsetY = yOffset; pDSChInfo->scaleX = xScale; pDSChInfo->offsetX = xOffset; if (pfileInfo->allowed == editing) pfileInfo->DSAltered = 1; /* (TRUE) */ else { if (dataSection > 0) /* If we are at previous data section */ { CFSLONG tableValue; /* Write the data back to disk */ tableValue = GetTable(handle, dataSection); if (FileData(handle, pfileInfo->dataHeadP, tableValue, (WORD)pfileInfo->fileHeadP->dataHeadSz) == 0) { InternalError(handle, proc, WRITERR); goto Restore; } } } Restore: if ((pfileInfo->allowed == writing) && (dataSection > 0)) { /* Then copy the old data back into position */ CMovel(pfileInfo->dataHeadP,pfileInfo->extHeadP, pfileInfo->fileHeadP->dataHeadSz); } } else InternalError(handle,proc,NOTWORE); /* failed writing/editing */ return; } /* end of setDSChans */ /************************** Write Data ******************************** ** ** Write actual data into current data block. ** *****************************************************************************/ CFSAPI(short) WriteData(short handle, /* program file handle */ WORD dataSection, /* data section for data */ CFSLONG startOffset, /* offset in DS for write */ WORD bytes, /* number of bytes to write */ TpVoid dataADS) /* ptr to start of data to write */ { short proc = 19; /* number for this function */ short ecode = 0; CFSLONG endOffset; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpDHead dataHP; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); ASSERT(g_fileInfo[handle].allowed != reading); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return BADHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* action depends on whether file was opened by CREAT (writing) or OPEN (editing) */ if ((pfileInfo->allowed == writing) && (dataSection == 0)) { /* adjust pointers for data size */ dataHP = pfileInfo->dataHeadP; endOffset = dataHP->dataSt + startOffset + bytes; if (pfileInfo->fileHeadP->fileSz < endOffset) { pfileInfo->fileHeadP->fileSz = endOffset; dataHP->dataSz = endOffset - dataHP->dataSt; } ecode = FileData(handle,dataADS,dataHP->dataSt + startOffset,bytes); if (ecode == 0) { InternalError(handle,proc,WRITERR); ecode = WRITERR; } else ecode = 0; /* Set to no error result otherwise */ } else { if ((pfileInfo->allowed != editing) && /* must be OK to write */ (pfileInfo->allowed != writing)) { InternalError(handle, proc, NOTWORE); return NOTWORE; } if ((dataSection < 1) || (dataSection > pfileInfo->fileHeadP->dataSecs)) { InternalError(handle,proc,BADDS); /* check data section number */ return BADDS; } /* If writing, preserve the current data section header */ if (pfileInfo->allowed == writing) { CMovel(pfileInfo->extHeadP, pfileInfo->dataHeadP, pfileInfo->fileHeadP->dataHeadSz); } ecode = GetHeader(handle, dataSection); if (ecode != 0) /* can be READERR or WRITERR */ { InternalError(handle,proc,ecode); /* check data section number */ goto Restore; } if ((startOffset + bytes) > pfileInfo->dataHeadP->dataSz) { InternalError(handle,proc,BADDSZ); /* check data section number */ ecode = BADDSZ; goto Restore; } /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->fileHeadP->tablePos != 0) && (pfileInfo->allowed == editing)) { ecode = FileUpdate(handle, pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle,proc,ecode); goto Restore; } } ecode = FileData(handle, dataADS, pfileInfo->dataHeadP->dataSt + startOffset,bytes); if (ecode == 0) { InternalError(handle,proc,WRITERR); ecode = WRITERR; goto Restore; } else ecode = 0; /* No errors, so clear function return */ Restore: /* Copy the old data back into position if required */ if (pfileInfo->allowed == writing) { CMovel(pfileInfo->dataHeadP, pfileInfo->extHeadP, pfileInfo->fileHeadP->dataHeadSz); } } return ecode; } /* end of WriteData */ /************************** Set Write Data ****************************** ** ** For file opened with CREAT only. Set it up ready for fast sequential write. ** Attempt to by pass piecewise disk allocation and speed up write to disc. ** NB BUFFERS = prameter in CONFIG.SYS needs to be at least 20. ** Any error is put into global error struct. ** *****************************************************************************/ CFSAPI(void) SetWriteData(short handle, /* program file handle */ CFSLONG startOffset, /* byte offset within DS for writing */ CFSLONG bytes) /* number of bytes to write */ { short proc = 3; /* function number */ char oneByte; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpDHead dataHP; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed == writing); /* 1. Check handle */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed != writing) /* check created file */ { InternalError(handle,proc,NOTWRIT); return; } dataHP = pfileInfo->dataHeadP; if ((bytes >= 0) && (startOffset >= 0)) /* If parameters are ok */ /* 2. move to end of data and write 1 byte to allocate file space */ { if (FileData(handle,dataHP,dataHP->dataSt+startOffset + bytes,1) == 0) { /* attempt write to wouldbe end of file */ InternalError(handle,proc,WRITERR); return; } } else { /* either bytes or startOffset duff */ InternalError(handle,proc,BADPAR); return; } /* 3. move to start of data area and read 1 byte to position of head */ if (LoadData(handle, &oneByte, dataHP->dataSt+startOffset-1, 1) == 0) { InternalError(handle,proc,READERR); return; } return; } /* end of SetWritedata */ /**************************** CFSFileSize ********************************* ** ** Return the file size, in bytes. The name is to avoid C library clashes. ** *****************************************************************************/ CFSAPI(CFSLONG) CFSFileSize(short handle) { short proc = 24; /* function number */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle, proc, BADHANDLE); /* check handle */ return BADHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed == nothing) /* and also check for file not open */ { InternalError(handle, proc, NOTOPEN); return NOTOPEN; } fileHP = pfileInfo->fileHeadP; /* Get pointer to file header */ return fileHP->fileSz; /* return the file size from the header */ } /**************************** Insert DS ****************************** ** ** Close the current data block and insert it at datasection th data ** block in the file. For dataSection 0 put it at the end. ** Return zero or error code. ** *****************************************************************************/ CFSAPI(short) InsertDS(short handle, /* program file handle */ WORD dataSection, /* section number */ TSFlags flagSet) /* flags for this DS */ { short proc = 17; /* function number */ WORD index,relevantSize; CFSLONG gtPlace,gtPlace1; CFSLONG tableValue; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; TpDHead dataHP; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed == writing); ASSERT(dataSection < MAXNODS); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); /* check handle */ return BADHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* 1. check file open for writing and dataSection valid */ if (pfileInfo->allowed != writing) { InternalError(handle,proc,NOTWRIT); return NOTWRIT; } fileHP = pfileInfo->fileHeadP; if (fileHP->dataSecs >= MAXNODS) { InternalError(handle,proc,XSDS); return XSDS; } if (dataSection == 0) dataSection = (WORD)(fileHP->dataSecs + 1); if ((dataSection < 1) || (dataSection > (fileHP->dataSecs + 1))) { InternalError(handle,proc,BADDS); return BADDS; } /* 2. change the pointer table to accommodate new data section */ for (index = fileHP->dataSecs;index >= dataSection;index--) { /* move entries past current DS up one */ tableValue = GetTable(handle,index); StoreTable(handle,(WORD)(index+1),tableValue); } dataHP = pfileInfo->dataHeadP; /* 3. change pointers for current section */ /* for first DS lastDS=0 ie previous thing is the header */ if (dataSection == 1) dataHP->lastDS = 0; else dataHP->lastDS = GetTable(handle,(WORD)(dataSection-1)); /* previous section */ dataHP->dataSz = fileHP->fileSz - dataHP->dataSt; /* set size of data which should be on end of file */ gtPlace = dataHP->dataSt + BlockRound(handle, dataHP->dataSz); /* offset corresponding to this DS */ StoreTable(handle, dataSection, gtPlace); /* store offset for this DS header */ /* 4. write the data header to the file */ dataHP->flags = flagSet; /* set flags for this DS */ if (FileData(handle,dataHP,gtPlace,(WORD)fileHP->dataHeadSz) == 0) { InternalError(handle,proc,WRITERR); return WRITERR; } /* 5. alter lastDS pointer in subsequent header */ relevantSize = sizeof(TDataHead) - sizeof(TDSChArr); if (dataSection < (fileHP->dataSecs + 1)) { /* not the last one */ gtPlace1 = GetTable(handle,(WORD)(dataSection + 1)); /* offset for next DS */ if (LoadData(handle,pfileInfo->extHeadP,gtPlace1,relevantSize) == 0) { InternalError(handle,proc,READERR); return READERR; /* read header to change */ } pfileInfo->extHeadP->lastDS = gtPlace; /* make the change */ if (FileData(handle,pfileInfo->extHeadP,gtPlace1,relevantSize) == 0) { InternalError(handle,proc,WRITERR); return WRITERR; } } else fileHP->endPnt = gtPlace; /* action for end DS */ /* 6. update fileHeader and dataheader variable */ fileHP->dataSecs = (WORD)(fileHP->dataSecs + 1); fileHP->fileSz = gtPlace + fileHP->dataHeadSz; dataHP->dataSt = fileHP->fileSz; dataHP->dataSz = 0; return 0; /* all ok */ } /* end of InsertDS */ /**************************** AppendDS ****************************** ** ** Add an empty data section onto the end of the file, so that we can ** write to it. Intended for use with offline files. ** ** Return zero or error code. ** *****************************************************************************/ CFSAPI(short) AppendDS(short handle, /* program file handle */ CFSLONG lSize, /* size of the new section */ TSFlags flagSet) /* flags for this DS */ { short proc = 25; /* function number */ WORD headSize, thisDS; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; TpDHead dataHP; CFSLONG lPrev, lThis; CFSLONG tableValue; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT((g_fileInfo[handle].allowed == editing) || (g_fileInfo[handle].allowed == writing)); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); /* check handle */ return BADHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed == writing) /* If writing just use InsertDS */ return InsertDS(handle, 0, flagSet); /* as this does it */ /* 1. check file open for writing and work out this DS number */ if (pfileInfo->allowed != editing) { InternalError(handle, proc, NOTWORE); return NOTWORE; } if (pfileInfo->DSAltered == 1) /* do we need to write this DS out first? */ { tableValue = GetTable(handle,pfileInfo->thisSection); pfileInfo->DSAltered = 0; if (FileData(handle,pfileInfo->dataHeadP,tableValue,(WORD) pfileInfo->fileHeadP->dataHeadSz) == 0) { InternalError(handle,proc,WRITERR); return WRITERR; } } pfileInfo->thisSection = 0xFFFF; /* If this is the first edit made to a file get it ready for the change */ /* This code strips the lookup table from the file size, which will help out! */ if (pfileInfo->fileHeadP->tablePos != 0) { short ecode; ecode = FileUpdate(handle, pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle, proc, ecode); return ecode; } } fileHP = pfileInfo->fileHeadP; /* Pointer to the file info */ dataHP = pfileInfo->dataHeadP; /* and the data header buffer */ if (fileHP->dataSecs >= MAXNODS) { InternalError(handle,proc,XSDS); return XSDS; } headSize = fileHP->dataHeadSz; /* Size of DS header in total */ thisDS = fileHP->dataSecs + 1; /* The number for the new data section */ lThis = fileHP->fileSz + BlockRound(handle, lSize); /* New DS head pos */ /* 2. Read in the previous DS header so we can meddle */ lPrev = GetTable(handle, (WORD)(thisDS - 1));/* offset for prev DS */ if (LoadData(handle, dataHP, lPrev, headSize) == 0) { InternalError(handle,proc,READERR); return READERR; /* read header to change */ } /* 3. Start creating the new data section. The new section goes at the end */ dataHP->dataSt = lPrev + headSize; /* Start posn for the data */ dataHP->dataSz = lSize; /* Size of the data */ dataHP->lastDS = lPrev; dataHP->flags = flagSet; /* set flags for this DS */ pfileInfo->thisSection = thisDS; /* now talking about a different DS */ StoreTable(handle, thisDS, lThis); /* Get the DS start into table */ /* 4. write the data header to the file */ if (FileData(handle, dataHP, lThis, headSize) == 0) { InternalError(handle,proc,WRITERR); return WRITERR; } /* 5. update fileHeader and dataheader variable */ fileHP->dataSecs = thisDS; fileHP->endPnt = lThis; /* pointer to the last DS header */ fileHP->fileSz = lThis + headSize; /* Updated file size */ return 0; /* all ok */ } /* end of AppendDS */ /**************************** Get DS Size ******************************** ** ** Returns size (in bytes) of specified data section for old file or current ** data section for new file. (file specified by its program file handle ). ** The size returned is the disk space for the channel data and doesn't ** include the DS header. ** Return is the size or -ve error code. ** *****************************************************************************/ CFSAPI(CFSLONG) GetDSSize(short handle, /* program file handle */ WORD dataSection) { short proc = 22; short ecode; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif /* check handle */ ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return BADHANDLE; } /* check file status */ pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed != nothing) { /* get header if old file */ if (pfileInfo->allowed != writing) { if ((dataSection < 1) || (dataSection > pfileInfo->fileHeadP->dataSecs)) { InternalError(handle,proc,BADDS); return BADDS; } ecode = GetHeader(handle,dataSection); if (ecode < 0) { InternalError(handle,proc,ecode); return ecode; } } return pfileInfo->dataHeadP->dataSz; /* return stored size */ } else { InternalError(handle,proc, NOTWORR); return NOTWORR; } } /* end of GetDSSize */ /************************** Clear DS ******************************** ** ** Clear out data already written in current DS. See WriteData. ** *****************************************************************************/ CFSAPI(short) ClearDS(short handle) { short proc = 20; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpDHead dataHP = NULL; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed == writing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return BADHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* action depends on if file was opened by CREAT(writing) or OPEN (editing) */ if (pfileInfo->allowed == writing) /* adjust pointers for data size 0 */ { pfileInfo->fileHeadP->fileSz = dataHP->dataSt; pfileInfo->dataHeadP->dataSz = 0; } else { InternalError(handle,proc,NOTWRIT); return NOTWRIT; /* cannot do it unless CREAT (writing) */ } return 0; } /***************************** Remove DS ********************************* ** ** Remove a data section from the CFS file. Doesn't actually shorten the ** file but rearranges pointers so blocks dont appear any more. ** *****************************************************************************/ CFSAPI(void) RemoveDS(short handle, /* program file handle */ WORD dataSection) /* DS to remove */ { short proc = 4; /* number for this function */ CFSLONG storeLastDS; WORD relSize,index,ecode; CFSLONG tableValue; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(dataSection > 0); ASSERT(dataSection <= g_fileInfo[handle].fileHeadP->dataSecs); ASSERT((g_fileInfo[handle].allowed == writing) || (g_fileInfo[handle].allowed == editing)); /* 1. Check handle and data section parameters are valid */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ relSize = sizeof(TDataHead) - sizeof(TDSChArr); /* size of data header without channel infoe array */ if ((pfileInfo->allowed != writing) && (pfileInfo->allowed != editing)) { InternalError(handle,proc,NOTWORE); return; } if ((dataSection < 1) || (dataSection > pfileInfo->fileHeadP->dataSecs)) { InternalError(handle,proc,BADDS); return; } /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->allowed == editing) && (pfileInfo->fileHeadP->tablePos != 0)) { ecode = FileUpdate(handle,pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle,proc,ecode); return; } } tableValue = GetTable(handle,dataSection); if (LoadData(handle,pfileInfo->extHeadP,tableValue,relSize) == 0) { InternalError(handle,proc,READERR); return; } storeLastDS = pfileInfo->extHeadP->lastDS; /* save the pointer to previous DS */ /* 3. If current DS needs Filing do so */ if (pfileInfo->DSAltered == 1) { tableValue = GetTable(handle,pfileInfo->thisSection); pfileInfo->DSAltered = 0; if (FileData(handle,pfileInfo->dataHeadP,tableValue,(WORD) pfileInfo->fileHeadP->dataHeadSz) == 0) { InternalError(handle,proc,WRITERR); return; } } pfileInfo->thisSection = 0xFFFF; /* 4. Remove section from pointer table */ for (index = dataSection;index < pfileInfo->fileHeadP->dataSecs;index++) { tableValue = GetTable(handle,(WORD)(index + 1)); /* shift all offsets one place */ StoreTable(handle,index,tableValue); /* back in array */ } /* 5. set lastDS for DS which now has removed ones index (or endPnt) if last */ if (dataSection < pfileInfo->fileHeadP->dataSecs) /* DS is not last one */ { tableValue = GetTable(handle,dataSection); /* offset for new DS with this number */ if (LoadData(handle,pfileInfo->extHeadP,tableValue,relSize) == 0) { InternalError(handle,proc,READERR); return; } pfileInfo->extHeadP->lastDS = storeLastDS; /* set new previous section */ if (FileData(handle,pfileInfo->extHeadP,tableValue,relSize) == 0) { InternalError(handle,proc,WRITERR); return; } /* write it back to file again */ } else pfileInfo->fileHeadP->endPnt = storeLastDS; /* if DS is last one */ /* 6. There is now 1 DS less in file */ pfileInfo->fileHeadP->dataSecs--; return; } /* end of Remove DS */ /***************************** Set Comment ******************************* ** ** Can use this function if file opened with CreateCFSFile or OpenCFSFile in ** edit mode. Overwrite the comment stored in the file header. ** *****************************************************************************/ CFSAPI(void) SetComment(short handle, /* program file handle */ TpCStr comment) /* comment to store */ { short proc = 15; /* function number */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; short ecode; /* for return from FileUpdate */ ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT((g_fileInfo[handle].allowed == writing) || (g_fileInfo[handle].allowed == editing)); /* check handle and file status */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ fileHP = pfileInfo->fileHeadP; if ((pfileInfo->allowed != writing) && (pfileInfo->allowed != editing)) { InternalError(handle,proc,NOTWRIT); return; } /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->allowed == editing) && (pfileInfo->fileHeadP->tablePos != 0)) { ecode = FileUpdate(handle,pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle,proc,ecode); return; } } /* if all ok transfer comment to its place in the file header */ TransferIn(comment,fileHP->commentStr,COMMENTCHARS); } /* end of setComment */ /*************************** Set Var Val ******************************* ** ** Transfer the variable value to the byte list ready for transfer to file. ** ** If file opened by CreateCFSFile (allowed=writing) and the DS variable ** value applies to the current data section it will keep the value set ** for subsequent data sections unless changed. ** ** File opened by OpenCFSFile (allowed=editing) the new DS variable value ** applies to the data section specified only. ** *****************************************************************************/ CFSAPI(void) SetVarVal(short handle, /* program file handle */ short varNo, /* variable number (file or DS) */ short varKind, /* FILEVAR or DSVAR */ WORD dataSection, /* 0 or DS number */ TpVoid varADS) /* location of data to write to file */ { short proc = 5; /* function number */ short maxVarNo, ecode; int size = 0; int varOff; int stType; /* 1 for string transfers 0 for others */ TpSStr dest = NULL; BYTE maxLen = 0; BYTE charCount; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif CFSLONG* pLong = (CFSLONG*)varADS; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); ASSERT(g_fileInfo[handle].allowed != reading); /* NB ALL variable descriptions should be entered before the FIRST value is transferred */ /* Check handle parameter */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* Check file status */ if ((pfileInfo->allowed != writing) && (pfileInfo->allowed != editing)) { InternalError(handle, proc, NOTWORE); return; } stType = 0; /* Assume not a string */ /* Check variable kind and number */ switch (varKind) { case FILEVAR: { maxVarNo = pfileInfo->fileHeadP->filVars; if ((varNo >= 0) && (varNo < maxVarNo)) { /* retrieve place at which to store variable */ varOff = pfileInfo->FVPoint.nameP[varNo].vSize; dest = pfileInfo->FVPoint.dataP + varOff; /* get variable size from its offset and the next one */ size = (short)(pfileInfo->FVPoint. nameP[varNo+1].vSize-varOff); /* watch out for lstr type */ if (pfileInfo->FVPoint.nameP[varNo].vType == LSTR) { /* size allocated is for max number of chars + 2bytes */ maxLen = (BYTE)(size-2); /* maximum characters in transfer */ stType = 1; /* flag string transfer */ } else maxLen = 255; } break; } case DSVAR: { maxVarNo = pfileInfo->fileHeadP->datVars; /* same comments as above */ if ((varNo >= 0) && (varNo < maxVarNo)) { varOff = pfileInfo->DSPoint.nameP[varNo].vSize; dest = pfileInfo->DSPoint.dataP + varOff; size = (short)(pfileInfo->DSPoint.nameP[varNo+1]. vSize-varOff); if (pfileInfo->DSPoint.nameP[varNo].vType == LSTR) { maxLen = (BYTE)(size - 2); stType = 1; } else maxLen = 255; } break; } default: { InternalError(handle,proc,BADKIND); return; } } if ((varNo < 0) || (varNo >= maxVarNo)) { /* can now check variable number is in range */ InternalError(handle,proc,BADVARN); return; } /* Now split depending upon the variable type */ if (varKind == FILEVAR) { /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->allowed == editing) && (pfileInfo->fileHeadP->tablePos != 0)) { ecode = FileUpdate(handle,pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle,proc,ecode); return; } } if (stType == 0) /* not a string to transfer */ CMovel(dest, varADS, (short)size); else { /* varADS is address of C string to transfer dest is address of LSTRING for storage */ charCount = (BYTE)F_strlen((TpStr)varADS); /* how many cahracters in string */ if (charCount > maxLen) charCount = maxLen; TransferIn((TpStr)varADS,(TpStr)dest,charCount); } } else { /* check datasection is in files range */ if ((pfileInfo->allowed == writing) && (dataSection == 0)) dataSection = (WORD)(pfileInfo->fileHeadP->dataSecs + 1); if ((dataSection < 1) || /* Now check for a legal DS */ ((dataSection > pfileInfo->fileHeadP->dataSecs) && (pfileInfo->allowed != writing)) || ((dataSection > pfileInfo->fileHeadP->dataSecs + 1) && (pfileInfo->allowed == writing))) { InternalError(handle,proc,BADDS); return; } /* If writing and looking back in file, preserve the data header */ if ((pfileInfo->allowed == writing) && (dataSection <= pfileInfo->fileHeadP->dataSecs)) { CMovel(pfileInfo->extHeadP, pfileInfo->dataHeadP, pfileInfo->fileHeadP->dataHeadSz); } /* If editing or reading need to load data header of DS specified */ if (dataSection <= pfileInfo->fileHeadP->dataSecs) { ecode = GetHeader(handle,dataSection); /* load data header */ if (ecode < 0) /* error code can be read/write error */ { InternalError(handle,proc,ecode); goto Restore; } } /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->allowed == editing) && (pfileInfo->fileHeadP->tablePos != 0)) { ecode = FileUpdate(handle, pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle,proc,ecode); goto Restore; } } if (stType == 0) /* not a string to transfer */ CMovel(dest, varADS, (short)size); else { /* varADS is address of C string to transfer dest is address of LSTRING for storage */ charCount = (BYTE)F_strlen((TpStr)varADS); /* how many cahracters in string */ if (charCount > maxLen) charCount = maxLen; TransferIn((TpStr)varADS,(TpStr)dest,charCount); } /* If editing update DS header flag so it gets written to file later */ if (pfileInfo->allowed == editing) pfileInfo->DSAltered = 1; Restore: /* Restore header for DS being written if required */ if ((pfileInfo->allowed == writing) && (dataSection <= pfileInfo->fileHeadP->dataSecs)) { CFSLONG tableValue; // First write the data back to disk tableValue = GetTable(handle, dataSection); if (FileData(handle, pfileInfo->dataHeadP, tableValue, (WORD)pfileInfo->fileHeadP->dataHeadSz) == 0) InternalError(handle, proc, WRITERR); /* Then copy the old data back into position */ CMovel(pfileInfo->dataHeadP,pfileInfo->extHeadP, pfileInfo->fileHeadP->dataHeadSz); } } return; } /* end of SetVarVal */ /************************** Close CFS File ******************************* ** ** Close the CFS file specified by its program handle. ** It can have been opened by CreateCFSFile or OpenCFSFile. ** Return 0 if ok or error code if not. ** *****************************************************************************/ CFSAPI(short) CloseCFSFile(short handle) { short proc = 21; short flag = 0, exchange = 0, retval = 0; CFSLONG tabSize, tableValue; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; TpDHead dataHP; int index; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); /* 1. Check handle */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return BADHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed == nothing) { InternalError(handle,proc,BADHANDLE); return BADHANDLE; } fileHP = pfileInfo->fileHeadP; dataHP = pfileInfo->dataHeadP; retval = 0; /* return value for ok. Will overwrite if error */ /* 2. File the last DS if necessary */ if ((pfileInfo->allowed == writing) && (fileHP->fileSz > dataHP->dataSt)) { if (InsertDS(handle,(WORD)(fileHP->dataSecs+1),dataHP->flags) != 0) retval = BADINS; } if (pfileInfo->allowed != reading) { /* 3. Transfer the pointer table first make sure that any altered DS header is filed. */ /* Check that the file actually needs updating */ if ((pfileInfo->allowed == editing) && (fileHP->tablePos != 0)) { /* no change has been made. DO NOT write to file. Tidy up. */ CFreeAllcn(pfileInfo->extHeadP); /* if file opened for table pointers close and delete it */ if (pfileInfo->tableP == NULL) { /* delete CFS file */ retval = CCloseAndUnlink(pfileInfo->DOSHdl.p, pfileInfo->tempFName); if (retval < 0) retval = WRDS; } } else { if (pfileInfo->DSAltered == 1) { tableValue = GetTable(handle,pfileInfo->thisSection); if (FileData(handle,dataHP,tableValue,fileHP->dataHeadSz) == 0) retval = WRITERR; } /* it is to go on end of CFS file */ if (CLSeek(pfileInfo->DOSHdl.d, fileHP->fileSz, 0) < 0) retval = DISKPOS; tabSize = fileHP->dataSecs * 4; /* size of table */ if (pfileInfo->tableP == NULL) /* table not in memory */ { /* copy from start of temp file */ if (CLSeek(pfileInfo->DOSHdl.p,(CFSLONG)0,0) < 0) retval = DISKPOS; exchange = TransferTable(fileHP->dataSecs, pfileInfo->DOSHdl.p, pfileInfo->DOSHdl.d); if (exchange < 0) retval = exchange; /* want to return error if not ok */ flag = CCloseAndUnlink(pfileInfo->DOSHdl.p, pfileInfo->tempFName);/* delete pointer file */ if ((flag < 0) && (exchange >= 0)) retval = WRDS; /* delete pointer table file */ } else /* table is in memory so write it to file */ if (CWriteHandle(pfileInfo->DOSHdl.d,(TpStr)pfileInfo->tableP, (WORD)tabSize) < (WORD)tabSize) retval = WRDS; /* 4. Store file header */ if (exchange < 0) fileHP->tablePos = 0; /* if transfer failed, enabling to rebuild table on the next run */ else fileHP->tablePos = fileHP->fileSz; /* table position at end of rest of file */ fileHP->fileSz = fileHP->fileSz + tabSize; /* add table to file size */ if (FileData(handle, fileHP, (CFSLONG)0, fileHP->fileHeadSz) == 0) retval = WRITERR; CFreeAllcn(pfileInfo->extHeadP); /* release space for insert header applies to writing and editing files */ /* set the file length */ if (CSetFileLen(pfileInfo->DOSHdl.d, pfileInfo->fileHeadP->fileSz) != 0) retval = BADFL; } } CClose(pfileInfo->DOSHdl.d); /* Close the CFS file */ CFreeAllcn(pfileInfo->fileHeadP); /* free space allocated for header */ CFreeAllcn(pfileInfo->dataHeadP); /* free space allocated for data */ /* flag handle as not used */ pfileInfo->allowed = nothing; /* no need to initialise other file prams */ /* as they will be initialised on opening/creating next CFS file */ /* if the table is in memory free its allocated space */ if (pfileInfo->tableP != NULL) CFreeAllcn(pfileInfo->tableP); for (index = 0; index < g_maxCfsFiles; index++) /* Finally, check tables */ if (g_fileInfo[index].allowed != nothing) /* Any files still open? */ break; /* If so, we exit the loop early */ if (index >= g_maxCfsFiles) /* If no files open, will clean up memory */ CleanUpCfs(); return retval; /* return 0 or errorcode */ } /* end of CloseCFSFile */ /************************** Open CFS File ******************************* ** ** Open en exisiting CFS file for reading or editing. ** Return the program handle if ok (even if cant fulfil table in memory ** request) or -ve error code. ** If only problem is inability to allocate memory for the table, this error ** is returned via the error record and things are set to proceed with the ** table on disc. ** *****************************************************************************/ CFSAPI(short) OpenCFSFile(TpCStr fname, /* C string containing file name */ short enableWrite, /* 1 for editing 0 for readonly */ short memoryTable) /* 1 for table in memory 0 for on disk */ { short proc; /* function number */ short loop,retval; WORD relevantSize; CFSLONG tblSz; short exchange, handle; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; TpDHead dataHP,extHP; proc = 13; /* initialise here to get rid of compiler warning */ extHP = NULL; /* do with goto */ /* 1. get a program file handle */ handle = FindUnusedHandle(); if (handle < 0) { InternalError(handle,proc,NOHANDLE); return NOHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* 2. open the file with required status */ /* use loop as temp variable */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) loop = 0; if (COpen(fname,(short)((enableWrite == 0) ? rMode : wMode), &pfileInfo->DOSHdl.d) != 0) loop = -1; #else loop = 0; if (COpen(fname,(short)((enableWrite == 0) ? 0 : 2), &pfileInfo->DOSHdl.d) != 0) loop = -1; #endif if (loop < 0) { InternalError(handle,proc,BADOPEN); return BADOPEN; } /* file is now open and DOS handle stored */ /* 2a. Check the file size against minimum */ /* Calculate space needed for minimal file file header */ relevantSize = sizeof(TFileHead) - sizeof(TFilChArr); if (CGetFileLen(pfileInfo->DOSHdl.d) < (CFSLONG)relevantSize) { retval = BADVER; goto Close0; /* need to close file before exit */ } /* file is now open and DOS handle stored */ /* 3. get memory needed initially for file header and data header */ /* Calculate space needed for just a minimalist file header */ relevantSize = sizeof(TFileHead) - sizeof(TFilChArr); pfileInfo->fileHeadP = (TpFHead)CMemAllcn(relevantSize); fileHP = pfileInfo->fileHeadP; if (fileHP == NULL) /* allocation failed */ { retval = NOMEMR; goto Close0; /* need to close file before exit */ } /* read the file header into the space allocated */ if (LoadData(handle,fileHP,(CFSLONG)0,relevantSize) == 0) { retval = READERR; /* load failed */ goto Close1; /* free space allated and close file */ } /* check the file marker . first whole of current version marker .*/ if (F_strncmp(fileHP->marker,CEDMARKER,MARKERCHARS) != 0) { retval = BADVER; /* now 2nd check to sort out old version file from foreigner */ if (F_strncmp(fileHP->marker,PARTMARK,PARTMARKCHARS) == 0) { /* fish out which old version from ASCII of last TpStr */ retval = fileHP->marker[PARTMARKCHARS]; retval = (short)(-(retval+BADOLDVER)); /* convert to error code .Yuck! */ } goto Close1; /* tidy up and return error code */ } relevantSize = fileHP->fileHeadSz; /* size of full header including chan stuff */ CFreeAllcn(pfileInfo->fileHeadP); /* release smaller space */ fileHP = (TpFHead)CMemAllcn(relevantSize); /* get enough for all */ if (fileHP == NULL) { retval = NOMEMR; goto Close0; /* close file only before exit */ } pfileInfo->fileHeadP = fileHP; /* store pointer to space allocated */ /* 4. read whole of file header including fixed channel info */ if (LoadData(handle,fileHP,(CFSLONG)0,relevantSize) == 0) { retval = READERR; goto Close1; } /* allocate space for data header */ pfileInfo->dataHeadP = (TpDHead)CMemAllcn(fileHP->dataHeadSz); dataHP = pfileInfo->dataHeadP; if (dataHP == NULL) { retval = NOMEMR; /* failure at DS header allocation */ goto Close1; } if (enableWrite != 0) { /* if user wants to edit file get extra DS header for insert */ pfileInfo->extHeadP = (TpDHead)CMemAllcn(fileHP->dataHeadSz); extHP = pfileInfo->extHeadP; if (extHP == NULL) { retval = NOMEMR; goto Close2; /* free DS header, file header and close file */ } } else pfileInfo->extHeadP = NULL; /* set explicitly to NULL if not allocated */ /* 5. set pointers within allocated space */ /* file variable descriptions come after fixed channel data */ pfileInfo->FVPoint.nameP = (TpVDesc)(fileHP->FilChArr+fileHP->dataChans); /* DS variable descriptions come after the file variables */ pfileInfo->DSPoint.nameP = pfileInfo->FVPoint.nameP + fileHP->filVars + 1; /* file variable values follow the DS variable descriptions */ pfileInfo->FVPoint.dataP = (TpSStr)(pfileInfo->DSPoint.nameP + fileHP->datVars + 1); /* DS variable values follow the DS channel information */ pfileInfo->DSPoint.dataP = (TpSStr)(dataHP->DSChArr+fileHP->dataChans); /* 6. get pointer table in memory or in separate file */ tblSz = 4 * fileHP->dataSecs; /* first locate table in CFS file */ if (fileHP->tablePos == 0) /* is pointer table lost */ { if (enableWrite == 0) { /* need to change file access to read/write */ if (CClose(pfileInfo->DOSHdl.d) != 0) { retval = WRITERR; /* nearset error poss. */ goto Close2; } #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) loop = 0; if (COpen(fname, wMode, &pfileInfo->DOSHdl.d) != 0) loop = -1; #else loop = 0; if (COpen(fname, 2, &pfileInfo->DOSHdl.d) != 0) loop = -1; #endif if (loop < 0) { retval = BADOPEN; goto Close2; } } loop = RecoverTable(handle,&tblSz,&fileHP->tablePos,&fileHP->dataSecs, &fileHP->fileSz); /* if loop is zero the table will be recovered ie.added to the CFS file and the file header variable updated */ if (loop < 0) { retval = loop; /* return error code of recovertable */ goto Close2; /* deallocate file and DS header(s) and close file */ } else /* success in recovering table. write updated header to file */ { if (FileData(handle,fileHP,(CFSLONG)0,fileHP->fileHeadSz) == 0) { retval = WRITERR; goto Close2; } } if (enableWrite == 0) /* need to change file access back to read */ { if (CClose(pfileInfo->DOSHdl.d) != 0) { retval = WRITERR; /* nearset error poss. */ goto Close2; } #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) loop = 0; if (COpen(fname, rMode, &pfileInfo->DOSHdl.d) != 0) loop = -1; #else loop = 0; if (COpen(fname, 0, &pfileInfo->DOSHdl.d) != 0) loop = -1; #endif if (loop < 0) { retval = BADOPEN; goto Close2; } } } /* position CFS file pointer at start of table */ if (CLSeek(pfileInfo->DOSHdl.d,fileHP->tablePos,0) < 0) { retval = DISKPOS; /* couldnt find table data */ goto Close2; } /* if requested and if possible get pointer table in memory */ if (memoryTable != 0) /* request for table to be in memory */ memoryTable = GetMemTable(handle); /* try to get space */ if (memoryTable != 0) /* space in memory allcated for table */ { if (!LoadData(handle, pfileInfo->tableP, fileHP->tablePos, tblSz)) { retval = READERR; /* couldnt read table */ goto Close2; } } else /* table to be accessed from file */ { pfileInfo->tableP = NULL; /* flag pointer table not in memory */ if (enableWrite != 0) { /* editing required so make temp file for table */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) /* make and save name for temp file */ TempName(handle,fname,pfileInfo->tempFName, WHOLEFILECHARS+2); if (CCreat(pfileInfo->tempFName, rwMode, &pfileInfo->DOSHdl.p) != 0) pfileInfo->DOSHdl.p = (fDef)-1; #endif if (&(pfileInfo->DOSHdl.p) < 0) /* create failed */ { retval = BADCREAT; goto Close2; } if (CLSeek(pfileInfo->DOSHdl.p,(CFSLONG)0,0) != 0) { retval = BADCREAT; goto Close3; /* add close and delete of temp file to tiy up */ } exchange = TransferTable(fileHP->dataSecs,pfileInfo->DOSHdl.d, pfileInfo->DOSHdl.p); /* transfer table from CFS to temp file */ if (exchange < 0) { retval = exchange; /* retrun error code of TransferTable */ goto Close3; } } else pfileInfo->DOSHdl.p = pfileInfo->DOSHdl.d; /* for reading only access the table from the CFS file itself */ } /* all is well now set files status */ if (enableWrite != 0) pfileInfo->allowed = editing; else pfileInfo->allowed = reading; pfileInfo->thisSection = 0xFFFF; pfileInfo->DSAltered = 0; return handle; /* return the program file handle */ /* 7. Tidy up in case of failure */ Close3:if (pfileInfo->tableP == NULL) /* is there likely to be a temp table file */ { if (&(pfileInfo->DOSHdl.p) != &(pfileInfo->DOSHdl.d)) /* make sure it isnt the CFS file */ { loop = CCloseAndUnlink(pfileInfo->DOSHdl.p, pfileInfo->tempFName); /* delete file */ } } Close2:if (pfileInfo->tableP != NULL) { CFreeAllcn(pfileInfo->tableP); pfileInfo->tableP = NULL; } if (pfileInfo->extHeadP != NULL) { CFreeAllcn(pfileInfo->extHeadP); pfileInfo->extHeadP = NULL; } CFreeAllcn(pfileInfo->dataHeadP); Close1:CFreeAllcn(pfileInfo->fileHeadP); Close0:loop = CClose(pfileInfo->DOSHdl.d); InternalError(handle,proc,retval); /* InternalError gets the details */ return retval; /* return error code */ } /* end of OpenCFSFile */ /************************** Get Gen Info ******************************* ** ** For CFS file specified by it program file handle, return in the time,date ** and comment arrays the time and date of creation of the CFS file and ** its general comment. ** time and date should point to C strings at least 8 chars long. (This will ** give time/date chars with no NULL.) ** comment should point to a C string at least COMMENTCHARS+1 (73) chars long. ** Error return is via error reord. ** *****************************************************************************/ CFSAPI(void) GetGenInfo(short handle, /* progran file handle */ TpStr time, /* to read back time */ TpStr date, /* to read back date */ TpStr comment) /* to read back general comment */ { short Proc = 6; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) /* function number */ TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); /* check handle specified */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,Proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed == nothing) InternalError(handle,Proc,NOTOPEN); else { fileHP = pfileInfo->fileHeadP; /* for the time and date copy the 8 chars only no NULL */ F_strncpy(time,fileHP->timeStr,8); time[8] = '\0'; F_strncpy(date,fileHP->dateStr,8); date[8] = '\0'; TransferOut(fileHP->commentStr,comment,COMMENTCHARS); } return; } /* end of GetGenInfo */ /*************************** Get File Info ******************************* ** ** For user to get some values from the file header of the file specified ** by its program file handle. ** The values are returned via pointers which on entry should point to ** variables of the correct type. ** Error return is via error record. ** *****************************************************************************/ CFSAPI(void) GetFileInfo(short handle, /* program file handle */ TpShort channels, /* to return number of channels */ TpShort fileVars, /* to return number of file variables */ TpShort DSVars, /* to return number of DS variables */ TpUShort dataSections) /* to retrun no. of DS's */ { short Proc = 7; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) /* function number */ TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,Proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; if (pfileInfo->allowed != nothing) /* if file is open */ { fileHP = pfileInfo->fileHeadP; /* set the thing that each parameter points to to the value in the file */ *channels = fileHP->dataChans; *fileVars = fileHP->filVars; *DSVars = fileHP->datVars; *dataSections= fileHP->dataSecs; } else InternalError(handle,Proc,NOTOPEN); /* file flagged as not open */ return; } /* end of GeTFileInfo */ /************************** Get Var Desc ******************************* ** ** To get from the file, specified by its program handle, information about ** a particular variable description, specified by its varKind (FILEVAR or ** DSVAR) and its number (alloted when first stored ). ** The size and type are returned by variable pointers. ** The units and description are returned by string pointers. ** The pointer for units should point to a string of at least UNITCHARS+1 (9) ** chars and that for the description to a string of at least DESCCHARS+1 (21) ** chars. ** Any error is returned via the error record. ** *****************************************************************************/ CFSAPI(void) GetVarDesc(short handle, /* program file handle */ short varNo, /* file or DS variable number */ short varKind, /* FILEVAR or DSVAR */ TpShort varSize,/* to return variable size in bytes */ TpDType varType, /* to return variable type */ TpStr units, /* to return units as C string */ TpStr description) /* to return variable description as C string */ { short Proc = 8; /* function number */ short size; short maxVarNo; short nextOffset; TVarDesc interDesc; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; /* check program handle */ ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,Proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed != nothing) { fileHP = pfileInfo->fileHeadP; switch (varKind) { case FILEVAR:maxVarNo = (short)(fileHP->filVars-1); break; case DSVAR :maxVarNo = (short)(fileHP->datVars-1); break; default :InternalError(handle,Proc,BADKIND); return; } if ((varNo < 0) || (varNo > maxVarNo)) { InternalError(handle,Proc,BADVARN); return; } if (varKind == FILEVAR) { interDesc = pfileInfo->FVPoint.nameP[varNo]; /* inside program vsize filed stores variable offset in byte list (not the size) */ nextOffset = pfileInfo->FVPoint.nameP[varNo+1].vSize; } else { interDesc = pfileInfo->DSPoint.nameP[varNo]; nextOffset = pfileInfo->DSPoint.nameP[varNo+1].vSize; } *varType = interDesc.vType; /* to return variable type */ /* now sort out the size from the stored offsets */ size = (short)(nextOffset - interDesc.vSize); /* if the variable is an lstring deduct 1 so that what is returned is the length of the C string needed to store it, ie. number of characters + 1 for the NULL */ if (interDesc.vType == LSTR) size = (short)(size-1); *varSize = size; /* return size in bytes */ /* Transfer the units and description from their stored LSTRING format to the C string provided */ TransferOut(interDesc.varUnits,units,UNITCHARS); TransferOut(interDesc.varDesc,description,DESCCHARS); } else InternalError(handle,Proc,NOTOPEN); return; } /* end of GetVarDesc */ /*************************** Get Var Val ******************************** ** ** To get from the file, specified by its program file handle, the actual ** value of a variable specified by its varKind (FILEVAR or DSVAR) and ** number (allocated when stored). ** For DSVAR in the case of files opened by CreatsCFSFile the value for the ** current DS is returned regardless of the parameter dataSection, ** in the case of files opened by OpenCFSFile the value for the ** dataSection specified is returned. ** The value is returned by copying it to the address, varADS, provided. ** The user must ensure that varADS is pointing to a large enough piece ** of free memory to which to copy the variable. ** String variables are returned as NULL terminated C strings (although stored as LSTRING). ** Any error is returned via the error record. ** *****************************************************************************/ CFSAPI(void) GetVarVal(short handle, /* program file handle */ short varNo, /* number of variable required */ short varKind, /* FILEVAR orDSVAR */ WORD dataSection, /* may need to specify DS */ TpVoid varADS) /* for return of variable */ { short Proc = 9; /* function number */ short maxVarNo,size,ecode; TpStr sourceP; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpVDesc pInterDesc,pnext; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); if ((handle < 0) || (handle >= g_maxCfsFiles)) /* check handle */ { InternalError(handle,Proc,BADHANDLE); return; } if ((varKind != FILEVAR) && (varKind != DSVAR)) /* check kind too */ { InternalError(handle,Proc,BADKIND); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* 1. Check file is open */ if (pfileInfo->allowed != nothing) { // // We split into file/DS sections here as the DS var code is getting a bit // complex if (varKind == FILEVAR) { maxVarNo = (short)(pfileInfo->fileHeadP->filVars-1); if ((varNo < 0) || (varNo > maxVarNo)) { InternalError(handle,Proc,BADVARN); return; } pInterDesc = pfileInfo->FVPoint.nameP + varNo;/* vars descript */ size = pInterDesc->vSize; /* actually OFFSET for now */ /* set pointer to next var description */ pnext = pfileInfo->FVPoint.nameP + varNo + 1; /* point to variable in its data (char) array, using its offset, size */ sourceP = (TpStr)pfileInfo->FVPoint.dataP + size; size = (short)(pnext->vSize - size); /* set size from offsets */ /* 4. move the variable to the location specified */ if (pInterDesc->vType == LSTR) { size = (short)(size-2); TransferOut(sourceP,(TpStr)varADS,(BYTE)size); } else CMovel(varADS,sourceP,size); } else // Here we do mostly the same for DS vars. Sorry for the { // duplication of code, but it keeps things much easier to do. maxVarNo = (short)(pfileInfo->fileHeadP->datVars-1); if ((varNo < 0) || (varNo > maxVarNo)) { InternalError(handle,Proc,BADVARN); return; } // If DS 0 on a new file, set to be next DS. if ((pfileInfo->allowed == writing) && (dataSection == 0)) dataSection = (WORD)(pfileInfo->fileHeadP->dataSecs + 1); // Now to check the data section number if ((dataSection < 1) || ((dataSection > pfileInfo->fileHeadP->dataSecs) && (pfileInfo->allowed != writing)) || ((dataSection > pfileInfo->fileHeadP->dataSecs + 1) && (pfileInfo->allowed == writing))) { InternalError(handle, Proc, BADDS); return; } /* 2. Look to see if a different data header is needed. If it is and we are */ /* writing, we will need to save the current header. */ if (dataSection <= pfileInfo->fileHeadP->dataSecs) { if (pfileInfo->allowed == writing) // Save the current header ? CMovel(pfileInfo->extHeadP, pfileInfo->dataHeadP, pfileInfo->fileHeadP->dataHeadSz); ecode = GetHeader(handle, dataSection); /* read new header */ if (ecode != 0) /* could have failed on read or write */ { InternalError(handle,Proc,ecode); goto Restore; } } /* now sort out where the variable is in its array and how many bytes */ pInterDesc = pfileInfo->DSPoint.nameP + varNo; size = pInterDesc->vSize; /* This is offset for now */ pnext = pfileInfo->DSPoint.nameP + varNo + 1; sourceP = (TpStr)pfileInfo->DSPoint.dataP + size; size = (short)(pnext->vSize - size); /* set size from offsets */ /* if variable is lstr things are different */ if (pInterDesc->vType == LSTR) { size = (short)(size-2); TransferOut(sourceP,(TpStr)varADS,(BYTE)size); } else CMovel(varADS,sourceP,size); Restore: /* Restore header for DS being written if required */ if ((pfileInfo->allowed == writing) && (dataSection <= pfileInfo->fileHeadP->dataSecs)) { CMovel(pfileInfo->dataHeadP,pfileInfo->extHeadP, pfileInfo->fileHeadP->dataHeadSz); } } } else InternalError(handle,Proc,NOTOPEN); return; } /* end of GetVarVal */ /************************** Get File Chan ******************************* ** ** To get from file, specified by its program file handle, the fixed ** information on a channel, specified by its number. (ie the order in which ** it appears in the CFS file.) ** The character arrays channelName,yUnits and xUnits must be of sufficient ** size, (DESCCHARS+1 (21), and UNITCHARS+1 (9) characters), for the return ** of the C string. ** The other information is returned via pointers which should on entry ** point to variables of the correct type. ** Any error is returned via the error record. ** *****************************************************************************/ CFSAPI(void) GetFileChan(short handle, /* program file handle */ short channel,/* chan for which info is required */ TpStr channelName, /* to return channel name */ TpStr yUnits, /* to return channel y units */ TpStr xUnits, /* EqualSpaced ot subsidiary to return x units */ TpDType dataTypeP, /* to return 1 of 8 types for channel */ TpDKind dataKindP,/* return equalspaced, matrix or subsidiary */ TpShort spacing, /* to return bytes between successive values for channel */ TpShort other) /* for matrix data rets next chan */ { short Proc = 10; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) /* function number */ TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpChInfo pChInfo; /* check handle */ ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); ASSERT(channel >= 0); ASSERT(channel < g_fileInfo[handle].fileHeadP->dataChans); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,Proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed != nothing) { /* check channel parameter */ if ((channel < 0) || (channel >= pfileInfo->fileHeadP->dataChans)) { InternalError(handle,Proc,BADCHAN); return; } pChInfo = pfileInfo->fileHeadP->FilChArr + channel; /* transfer character arrays for return */ TransferOut(pChInfo->chanName,channelName,DESCCHARS); TransferOut(pChInfo->unitsY,yUnits,UNITCHARS); TransferOut(pChInfo->unitsX,xUnits,UNITCHARS); /* set values to which return pointers point to values from file */ *dataTypeP = pChInfo->dType; *dataKindP = pChInfo->dKind; *spacing = pChInfo->dSpacing; *other = pChInfo->otherChan; } else InternalError(handle,Proc,NOTOPEN); return; } /* end of GetFileChan */ /**************************** Get DS Chan ******************************** ** ** To get from file, specified by its program file handle, the values of the ** data section channel information. User specifies which channel. Data ** section can include the one being written if file opened with ** CreateCFSFile. The values are returned via pointers. ** Any error is returned via the error record. ** *****************************************************************************/ CFSAPI(void) GetDSChan(short handle, /* program file handle */ short channel, /* channel for which info required */ WORD dataSection, /* dataSection required */ TpLong startOffset, /* to return channel start */ TpLong points, /* to return data points for channel */ TpFloat yScale, /* to return yscale for channel */ TpFloat yOffset, /* to return y offset for channel */ TpFloat xScale, /* to return x scale for channel */ TpFloat xOffset) /* to return x offset for channel */ { short Proc = 11; /* function number */ short ecode; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpDsInfo pChInfo; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); ASSERT(channel >= 0); ASSERT(channel < g_fileInfo[handle].fileHeadP->dataChans); /* 1. Check handle */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,Proc,BADHANDLE); return; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* check file status */ if (pfileInfo->allowed != nothing) { /* 2. Check channel specified against range in file */ if ((channel < 0) || (channel >= pfileInfo->fileHeadP->dataChans)) { InternalError(handle,Proc,BADCHAN); return; } /* 3. Check the data section number. We can access the current section if writing */ if ((pfileInfo->allowed == writing) && (dataSection == 0)) dataSection = (WORD)(pfileInfo->fileHeadP->dataSecs + 1); if ((dataSection < 1) || ((dataSection > pfileInfo->fileHeadP->dataSecs) && (pfileInfo->allowed != writing)) || ((dataSection > pfileInfo->fileHeadP->dataSecs + 1) && (pfileInfo->allowed == writing))) { InternalError(handle,Proc,BADDS); return; } /* 4. If writing and looking back in file, preserve the data header */ if ((pfileInfo->allowed == writing) && (dataSection <= pfileInfo->fileHeadP->dataSecs)) { CMovel(pfileInfo->extHeadP,pfileInfo->dataHeadP, pfileInfo->fileHeadP->dataHeadSz); } /* 5. If editing or reading need to load data header of DS specified */ if (dataSection <= pfileInfo->fileHeadP->dataSecs) { ecode = GetHeader(handle,dataSection); /* load data header */ if (ecode < 0) /* error code can be read/write error */ { InternalError(handle,Proc,ecode); goto Restore; } } /* extract information required from DS header */ pChInfo = pfileInfo->dataHeadP->DSChArr + channel; *startOffset = pChInfo->dataOffset; *points = pChInfo->dataPoints; *yScale = pChInfo->scaleY; *yOffset = pChInfo->offsetY; *xScale = pChInfo->scaleX; *xOffset = pChInfo->offsetX; Restore: /* Restore header for DS being written if required */ if ((pfileInfo->allowed == writing) && (dataSection <= pfileInfo->fileHeadP->dataSecs)) { CMovel(pfileInfo->dataHeadP,pfileInfo->extHeadP, pfileInfo->fileHeadP->dataHeadSz); } } else InternalError(handle,Proc,NOTOPEN); return; } /* end of GetDSChan */ /************************** Get Chan Data ******************************* ** ** Return data for a single channel from the CFS file. ** ** User specifies file by its program file handle, ** channel for which data required, ** dataSection for which data required, ** data point in the DS and channel from which to start ** transfer. (first point is 0) ** number of data points to transfer. 0 means transfer from ** point specified to end of DS, (or end of buffer). ** ** The data are returned by transfer to a buffer starting at dataADS. This ** should point to an area large enough for the transfer. ** areaSize should be set to the size of this destination buffer (in bytes). ** The transfer will not exceed this area even if the points requested would ** take it beyond it. ** Return is 0 if parameters passed specify 0 points or if there is any error, ** (this may have occurred part way through transferring). ** If the whole operation was successful return is the number of data points ** actually transferred, (this may not be the number requested in numPoints). ** Any error is returned via the error record. ** *****************************************************************************/ CFSAPI(WORD) GetChanData(short handle, /* program file handle */ short channel, /* channel required */ WORD dataSection, /* DS required */ CFSLONG firstElement, /* data point in channel at which to start */ WORD numberElements, /* points wanted */ TpVoid dataADS, /* address to transfer to */ CFSLONG areaSize) /* bytes allocated for transfer */ { short SizeOfData[NDATATYPE]; /* sizes in bytes of data types */ short ecode; short Proc = 14; /* function number */ WORD elementSize,dataOffset,numSecs; WORD retval; WORD bufferSize,spacing,pointsPerBuffer,buffersNeeded, bufferLoop,residueElements; CFSLONG filePos,totalPoints,numElements,longSpace; TpStr dBufferP; // THandle dummy; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); ASSERT(channel >= 0); ASSERT(channel < g_fileInfo[handle].fileHeadP->dataChans); SizeOfData[INT1] = 1; /* set sizes in bytes of each data type */ SizeOfData[WRD1] = 1; SizeOfData[INT2] = 2; SizeOfData[WRD2] = 2; SizeOfData[INT4] = 4; SizeOfData[RL4] = 4; SizeOfData[RL8] = 8; SizeOfData[LSTR] = 1; retval = 0; /* initialise return value. no points transferred */ dBufferP = NULL; /* ** 1. Check file handle and status */ if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,Proc,BADHANDLE); return retval; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed != nothing) /* Are we allowed to do this ? */ { /* ** 2. check channel number */ if ((channel < 0) || (channel >= pfileInfo->fileHeadP->dataChans)) { InternalError(handle,Proc,BADCHAN); return retval; } /* ** 3. for file just created copy the header for current section to spare place */ if ((pfileInfo->allowed == writing) && (dataSection<=pfileInfo->fileHeadP->dataSecs)) { CMovel(pfileInfo->extHeadP, pfileInfo->dataHeadP, pfileInfo->fileHeadP->dataHeadSz); } /* ** 4. check data section and read in its header */ numSecs = pfileInfo->fileHeadP->dataSecs; /* shorthand for number of DS */ if ((pfileInfo->allowed == writing) && (dataSection == 0)) dataSection = (WORD)(numSecs+1); /* Convert 0 to currently writing */ if ((dataSection < 1) || ((pfileInfo->allowed != writing) && (dataSection>numSecs)) || ((pfileInfo->allowed == writing) && (dataSection>(numSecs+1)))) { InternalError(handle,Proc,BADDS); return retval; } if (dataSection <= numSecs) /* if not the current DS */ { ecode = GetHeader(handle,dataSection); /* get right DS */ if (ecode < 0) /* header not read */ { InternalError(handle,Proc,ecode); return retval; } } /* ** 5. Check space and number of points */ elementSize = SizeOfData[(int)pfileInfo->fileHeadP->FilChArr[channel].dType]; totalPoints = pfileInfo->dataHeadP->DSChArr[channel].dataPoints; if (numberElements == 0) numElements = totalPoints; else numElements = numberElements; /* ** check there are enough points in data section to satisfy request */ if ((numElements + firstElement) >totalPoints) numElements = totalPoints - firstElement; /* check that request does not exceed buffer */ if ((numElements * elementSize) > areaSize) numElements = areaSize/elementSize; /* limit to unsigned short range */ if (numElements > MAXFORWRD) numElements = MAXFORWRD; /* ** 6. extract channels */ if (numElements == 0) goto Restore; spacing = pfileInfo->fileHeadP->FilChArr[channel].dSpacing; /* get as much as poss */ if ((numElements*spacing) > MAXMEMALLOC) bufferSize = (WORD)(MAXMEMALLOC - (MAXMEMALLOC % spacing)); else bufferSize = (WORD)numElements * spacing; /* allocated space must have integral set of channels */ dBufferP = AllocateSpace(&bufferSize, spacing); if (bufferSize == 0) { InternalError(handle,Proc,NOMEMR); goto Restore; } pointsPerBuffer = (WORD)(bufferSize/spacing); buffersNeeded = (WORD)(((numElements-1)/pointsPerBuffer)+1); /* includes last part buffer */ longSpace = spacing; /* keep it like the Pascal version */ filePos = pfileInfo->dataHeadP->dataSt + pfileInfo->dataHeadP->DSChArr[channel]. dataOffset + (longSpace*firstElement); dataOffset = 0; /* deal with complete buffers other than the last one */ if (buffersNeeded > 1) { for (bufferLoop = 0;bufferLoop <= (buffersNeeded-2);bufferLoop++) { if (LoadData(handle,dBufferP,filePos,bufferSize) == 0) { InternalError(handle,Proc,READERR); goto Restore; /* tidy up before exit */ } ExtractBytes((TpStr)dataADS,dataOffset, dBufferP, pointsPerBuffer,spacing,elementSize); dataOffset = (WORD)(dataOffset + pointsPerBuffer*elementSize); filePos = filePos + bufferSize; } } /* ** now whole buffers are done deal with remainder (last Buffer ) */ residueElements = (WORD)(((numElements - 1) % pointsPerBuffer) +1); if (LoadData(handle,dBufferP,filePos,(WORD)((( residueElements-1)*spacing)+elementSize)) == 0) { InternalError(handle,Proc,READERR); goto Restore; } ExtractBytes((TpStr)dataADS,dataOffset, dBufferP, residueElements,spacing,elementSize); retval = (WORD)numElements; /* to return number of points successfully transferred */ /* ** 7. tidy up. if writing copy header back */ Restore: if ((pfileInfo->allowed == writing) && (dataSection <= numSecs)) { CMovel(pfileInfo->dataHeadP, pfileInfo->extHeadP, pfileInfo->fileHeadP->dataHeadSz); } if (dBufferP != NULL) /* free memory allocated for transfer */ CFreeAllcn(dBufferP); } else InternalError(handle,Proc,NOTOPEN); return retval; } /* end of GetChanData */ /***************************** Read Data ********************************* ** ** To read data from a data section. ** CFS File is specified by its program file handle. ** DS is specified by its number. (even if opened by CreateCFSFile). 1 is ** first DS. ** startOffset is byte offset within the DS at which to start. ** bytes specifies how much to read. (error if this is off end of DS ) ** dataADS points to the start of the region into which to read the data. ** The user must allocate at least bytes bytes for this. ** Return is 0 if ok -ve error code if not. ** *****************************************************************************/ CFSAPI(short) ReadData(short handle, /* program file handle */ WORD dataSection, /* data section required */ CFSLONG startOffset, /* offset into DS from which to start reading */ WORD bytes, /* number of bytes to read */ TpVoid dataADS) /* start address to which to read */ { short proc = 23; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpDHead phead; WORD numSecs; short ecode,retval; /* check handle */ ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return BADHANDLE; } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed == nothing) /* check status */ { InternalError(handle,proc,NOTOPEN); return NOTOPEN; } /* 1. for file opened by CreateCFSFile copy current DS header to spare */ numSecs = pfileInfo->fileHeadP->dataSecs; if ((pfileInfo->allowed == writing) && (dataSection <= numSecs)) { CMovel((TpVoid)pfileInfo->extHeadP, (TpVoid)pfileInfo->dataHeadP,pfileInfo->fileHeadP->dataHeadSz); } /* 2. read in header of required DS */ if ((dataSection < 1) || ((pfileInfo->allowed != writing) && (dataSection > numSecs)) || ((pfileInfo->allowed == writing) && (dataSection > (numSecs + 1)))) { InternalError(handle,proc,BADDS); return BADDS; } if (dataSection <= numSecs) /* read in if not current header */ { ecode = GetHeader(handle,dataSection); if (ecode < 0) { InternalError(handle,proc,ecode); return ecode; } } /* right header is now there */ phead = pfileInfo->dataHeadP; /* shorten its pointer */ /* check the read spec against what is in the DS */ retval = BADDSZ; /* in case check fails */ if ((startOffset < 0) || ((startOffset + bytes) > phead->dataSz)) goto Restore; /* clear up before exit */ /* 3. extract data */ retval = READERR; /* in case it fails */ if (LoadData(handle,dataADS,phead->dataSt+startOffset,bytes) == 0) goto Restore; retval = 0; /* transfer requested successfully completed */ /* 4. if CreateCFSFile used make sure current DS header back in place */ Restore: if ((pfileInfo->allowed == writing) && (dataSection <= numSecs)) CMovel((TpVoid)pfileInfo->dataHeadP, (TpVoid)pfileInfo->extHeadP,pfileInfo->fileHeadP->dataHeadSz); return retval; /* 0 or error code */ } /* end of ReadData */ /************************** DS Flag Value ******************************* ** ** Returns initial value of a DS flag, for index supplied from 1 to 16. ** *****************************************************************************/ CFSAPI(WORD) DSFlagValue(int nflag) { const WORD flagVal[16] = {FLAG0,FLAG1,FLAG2,FLAG3,FLAG4,FLAG5,FLAG6, FLAG7,FLAG8,FLAG9,FLAG10,FLAG11,FLAG12, FLAG13,FLAG14,FLAG15}; /* holds DS flags intial values */ if ((nflag <= 15) && (nflag >=0)) return flagVal[nflag]; else return (WORD) 0; } /**************************** DS Flags *********************************** ** ** Either gets or sets (specified by setIt) the flags for a specified data ** section within a CFS file, specified by its program file handle, which ** has been opened with OpenCFSFile. ** ** The flags may only be set if writing was enabled when the file was opened. ** On entry pflagSet should point to a variable in the users program of the ** type TSFlags. If the flags are being set this varaible should have the ** required settingd. ** ** Any error is returned via the error record. ** *****************************************************************************/ CFSAPI(void) DSFlags(short handle, /* program file handle */ WORD dataSection, /* DS for which flags set/get */ short setIt, /* 1 means set 0 means get flags */ TpFlags pflagSet) /* pointer to users flagset variable */ { short proc = 12; /* function number */ short ecode; TFileInfo *pfileInfo; ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed != nothing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return; } /* Check file status. ie OpenCFSFile used */ pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed != nothing) { /* if setting check status is OK */ if ((setIt == 1) && (pfileInfo->allowed == reading)) { InternalError(handle,proc,NOTWORE); return; } /* check datasection is in files range */ if ((pfileInfo->allowed == writing) && (dataSection == 0)) dataSection = (WORD)(pfileInfo->fileHeadP->dataSecs + 1); if ((dataSection < 1) || /* Now check for a legal DS */ ((dataSection > pfileInfo->fileHeadP->dataSecs) && (pfileInfo->allowed != writing)) || ((dataSection > pfileInfo->fileHeadP->dataSecs + 1) && (pfileInfo->allowed == writing))) { InternalError(handle,proc,BADDS); return; } /* If writing and looking back in file, preserve the data header */ if ((pfileInfo->allowed == writing) && (dataSection <= pfileInfo->fileHeadP->dataSecs)) { CMovel(pfileInfo->extHeadP, pfileInfo->dataHeadP, pfileInfo->fileHeadP->dataHeadSz); } /* If editing or reading need to load data header of DS specified */ if (dataSection <= pfileInfo->fileHeadP->dataSecs) { ecode = GetHeader(handle,dataSection); /* load data header */ if (ecode < 0) /* error code can be read/write error */ { InternalError(handle,proc,ecode); goto Restore; } } /* Get or set flags for data section */ if (setIt == 1) { /* If this is the first edit made to a file get it ready for the change */ if ((pfileInfo->allowed == editing) && (pfileInfo->fileHeadP->tablePos != 0)) { ecode = FileUpdate(handle, pfileInfo->fileHeadP); if (ecode != 0) { InternalError(handle, proc, ecode); goto Restore; } } pfileInfo->dataHeadP->flags = *pflagSet; if (pfileInfo->allowed == editing) /* What to do now ? */ pfileInfo->DSAltered = 1; /* flag header has been altered */ } else *pflagSet = pfileInfo->dataHeadP->flags;/* return value in file */ Restore: /* Restore header for DS being written if required */ if ((pfileInfo->allowed == writing) && (dataSection <= pfileInfo->fileHeadP->dataSecs)) { if (setIt == 1) // Did we modify the data ? { // If so, we need to write it back CFSLONG tableValue; tableValue = GetTable(handle, dataSection); if (FileData(handle, pfileInfo->dataHeadP, tableValue, (WORD)pfileInfo->fileHeadP->dataHeadSz) == 0) InternalError(handle, proc, WRITERR); } /* Then copy the old data back into position */ CMovel(pfileInfo->dataHeadP,pfileInfo->extHeadP, pfileInfo->fileHeadP->dataHeadSz); } } else InternalError(handle,proc,NOTWORR); return; } /* end of DSFlags */ /***************************** File Error ******************************* ** ** Error function to collect information on error which is not instantly ** fatal. ** Return of error details is via pointers which on entry should point to ** variables of the right type. ** The values returned via these pointers refer to the first error encountered ** since the function was last called. (If no error was encountered since ** the last time the function was callled the values returned to will refer ** to the previous error ). ** Return value is 1 if an error was encountered since the last time the ** function was called, 0 if not. ** Side effect. ** eFound field of global errorInfo is reinitialised to 0. ** *****************************************************************************/ CFSAPI(short) FileError(TpShort handleNo, /* to return handle number */ TpShort procNo, /* to return procedure number */ TpShort errNo) /* to return error code */ { short retval; /* return current state of error found flag */ retval = errorInfo.eFound; *handleNo = errorInfo.eHandleNo; *procNo = errorInfo.eProcNo; *errNo = errorInfo.eErrNo; errorInfo.eFound = 0; /* reset for next error */ return retval; } /* end of FileError */ /************************** CommitCFSFile ********************************* ** ** CommitCFSFile:- Commits a file to disk, ie ensures that file secure ** on disk. The precise actions will vary with the OS, needless to say, ** but the DOS mechanism is to update the file header on disk, followed ** by duplicating the file handle and closing it, which updates the ** directory information. ** ** fh The handle for the file ** ** returns zero or -ve error code ** *****************************************************************************/ CFSAPI(short) CommitCFSFile(short handle) { short proc = 16; /* function number */ short err = 0; short retCode = 0; short restore = 0; int hand = 0; CFSLONG gtPlace = 0; CFSLONG endPtr = 0; CFSLONG oldDataSz = 0; CFSLONG oldFileSz = 0; CFSLONG oldLastDS = 0; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif ASSERT(handle >= 0); ASSERT(handle < g_maxCfsFiles); ASSERT(g_fileInfo[handle].allowed == writing); if ((handle < 0) || (handle >= g_maxCfsFiles)) { InternalError(handle,proc,BADHANDLE); return BADHANDLE; /* handle out of range */ } pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->allowed != writing) { InternalError(handle,proc,NOTWRIT); return NOTWRIT; /* not for writing */ } if (pfileInfo->fileHeadP->fileSz > pfileInfo->dataHeadP->dataSt) { /* Is there a growing DS ? */ oldDataSz = pfileInfo->dataHeadP->dataSz; oldLastDS = pfileInfo->dataHeadP->lastDS; /* points to header */ oldFileSz = pfileInfo->fileHeadP->fileSz; endPtr = pfileInfo->fileHeadP->endPnt; if (pfileInfo->fileHeadP->dataSecs == 0) pfileInfo->dataHeadP->lastDS = 0; else { pfileInfo->dataHeadP->lastDS = GetTable(handle, pfileInfo->fileHeadP->dataSecs); pfileInfo->dataHeadP->dataSz = pfileInfo->fileHeadP->fileSz - pfileInfo->dataHeadP->dataSt; gtPlace = pfileInfo->dataHeadP->dataSt + BlockRound(handle, pfileInfo->dataHeadP->dataSz); /* pointer to this DS */ if (!FileData(handle,pfileInfo->dataHeadP,gtPlace, (WORD)pfileInfo->fileHeadP->dataHeadSz)) retCode = WRDS; /* error writing DS header */ pfileInfo->fileHeadP->endPnt = gtPlace; pfileInfo->fileHeadP->fileSz = gtPlace + pfileInfo->fileHeadP->dataHeadSz; pfileInfo->fileHeadP->dataSecs++; /* inc data sections */ restore = 1; } } pfileInfo->fileHeadP->tablePos = 0; /* flag no table on disk... */ if (!FileData(handle,pfileInfo->fileHeadP,(CFSLONG)0, (WORD)pfileInfo->fileHeadP->fileHeadSz)) if (retCode == 0) retCode = WRITERR; /* error writing file header */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) /* shut the file for Windows */ if (!FlushFileBuffers(pfileInfo->DOSHdl.d)) retCode = BADHANDLE; #endif if (restore) { pfileInfo->fileHeadP->endPnt = endPtr; pfileInfo->fileHeadP->fileSz = oldFileSz; pfileInfo->dataHeadP->dataSz = oldDataSz; /* size of data */ pfileInfo->dataHeadP->lastDS = oldLastDS; pfileInfo->fileHeadP->dataSecs--; /* dec data sections */ } if (retCode != 0) InternalError(handle,proc,retCode); return retCode; } /****************************************************************************/ /***************** *************************/ /***************** Local function definitions *************************/ /***************** *************************/ /****************************************************************************/ /************************** Find Unused Handle ***************************** ** ** Looks through global array of file information to find first member ** which is not in use. Its index is the local file handle. -1 means none ** available. ** *****************************************************************************/ short FindUnusedHandle(void) { short search; if (g_maxCfsFiles <= 0) /* Do the initial allocation? */ { ASSERT(g_fileInfo == NULL); g_fileInfo = (TFileInfo*)CMemAllcn(INITCEDFILES * sizeof(TFileInfo)); if (g_fileInfo == NULL) return NOMEMR; /* Memory allocation error */ g_maxCfsFiles = INITCEDFILES; /* Number of files we have space for */ for (search = 0; search < g_maxCfsFiles; search++) g_fileInfo[search].allowed = nothing; /* Initialise file info */ } search = g_maxCfsFiles - 1; /* Start index for the search */ while ((search >= 0) && (g_fileInfo[search].allowed != nothing)) search--; if ((search < 0) && (g_maxCfsFiles < MAXCEDFILES)) /* If table is full */ { /* but could be enlarged */ TFileInfo* pNew; int num; num = g_maxCfsFiles * 2; /* Normally, just double the size */ if (num > MAXCEDFILES) num = MAXCEDFILES; /* but limit at the limit */ pNew = (TFileInfo*)CMemAllcn(num * sizeof(TFileInfo));/* Get memory */ if (pNew != NULL) /* and if it suceeded */ { for (search = 0; search < num; search++) /* Initialise memory */ pNew[search].allowed = nothing; /* and copy the data */ memcpy(pNew, g_fileInfo, sizeof(TFileInfo) * g_maxCfsFiles); CFreeAllcn(g_fileInfo); /* Discard old memory area */ g_fileInfo = pNew; /* and save new pointer and count */ g_maxCfsFiles = num; search = num - 1; /* and finally, return the last index */ } } return search; } /* end of FindUnusedHandle */ /***************************** Clean Up Cfs ***************************** ** ** Tries to clean up the CFS library memory prior to the library exiting ** from memory or shutting down. Called as part of Windows DLL cleanup. ** *****************************************************************************/ void CleanUpCfs(void) { int i; for (i = 0; i < g_maxCfsFiles; i++) if (g_fileInfo[i].allowed != nothing)/* Attempt a reliable clean up */ CloseCFSFile((short)i); if (g_fileInfo != NULL) CFreeAllcn(g_fileInfo); /* and final memory release and tidy up */ g_fileInfo = NULL; g_maxCfsFiles = 0; } /************************** Temp Name ************************************* ** ** Make a temporary file name encoding the file handle ** ****************************************************************************/ short TempName(short handle, TpCStr name, TpStr str2, unsigned str2len) { #if defined(_IS_WINDOWS_) short pathstart; short pathend = 0; short search = 0; char fname[WHOLEFILECHARS]; /* To get near variable holding string */ if (strlen(name) < WHOLEFILECHARS) F_strcpy(fname, name); /* Get filename in near var */ pathstart = 0; while (isspace(fname[pathstart])) pathstart++; /* first proper TpStr */ pathend = (short)(pathstart - 1); search = pathstart; /* start at proper start of file name */ while (search <= (short)F_strlen(fname)) { /* scan fname for end of path */ if ((fname[search] == '\\') || (fname[search] == ':')) pathend = search; search++; } /* use path if any to start temporary file name */ if (pathend >= pathstart) { F_strncpy(str2,fname+pathstart,pathend+1-pathstart); /* copy path */ str2[pathend+1-pathstart] = '\0'; /* add null */ } else { if (str2len > 0) F_strcpy(str2,""); /* or initialise to null string */ } F_strcat(str2,"CFS(TMP)."); /* ad standard part of temp file name */ _itoa(handle,gWorkStr,10); /* encode handle into string */ F_strcat(str2,gWorkStr); /* add handle to make complete name */ return 0; #else if (str2len > 12) F_strcpy(str2,"CFSTMPXXXXXX"); return (short)mkstemp(str2); #endif } /************************** Set Sizes ************************************* ** ** Look at array of variable descriptions and using the types add up how ** much space will be needed for all the actual variables in the array ** Return computed space (bytes) or -1 for error. ** *****************************************************************************/ short SetSizes(TpCVDesc theArray, TpShort offsetArray, short numVars) { short SizeOfData[NDATATYPE]; short search,size,runningTotal,errFlag; TpShort pOffsets; TpVDesc pVarDesc; /* set sizes for data types */ SizeOfData[INT1] = 1; SizeOfData[WRD1] = 1; SizeOfData[INT2] = 2; SizeOfData[WRD2] = 2; SizeOfData[INT4] = 4; SizeOfData[RL4] = 4; SizeOfData[RL8] = 8; SizeOfData[LSTR] = 0; errFlag = 0; /* No error */ runningTotal = 0; /* initialise */ for (search = 0;search < numVars;search++) { pOffsets = offsetArray + search; pVarDesc = (TpVDesc)theArray + search; /* Ok to remove const here */ /* check type is in range */ if ((pVarDesc->vType < 0) || (pVarDesc->vType >= NDATATYPE)) return -1; size = SizeOfData[(int)pVarDesc->vType]; if (pVarDesc->vType == LSTR) size = (short)(pVarDesc->vSize + 1); /* allow for NULL */ if ((size < 0) || (size >= MAXSTR)) errFlag = 1; *pOffsets = runningTotal; /* save start offset for each variable */ runningTotal = (short)(runningTotal+size); } if (errFlag) return -1; else return runningTotal; } /* end of setSizes */ /******************** Character handling functions ************************ ** ** TransferIn takes C string format (users storage) ** transfers to CFS storage format (program storage far heap) ** TransferOUT takes CFS storage format (program storage far heap) ** transfers to C string format (users storage). ** NB The length parameter is VITAL for checking strings do not overflow ** their char arrays. ** In both cases the length refers to the number of characters transferred ** neither the length byte nor the NULL are counted in this. ** ****************************************************************************/ /************************** Transfer In *********************************** ** ** Transfer as much as possible, but not more than max characters, of the ** NULL terminated C string old, to the character array new which imitates ** an LSTRING (NULL terminated) ** NB Since the allocated length of new cannot be checked the function relies ** on the parameter max to prevent overflow of new which should be ** declared as char[2+max]. ** new should finish up with new[0] containing the chracter count (0 to 255) ** then new[1] to new[new[0]] containig the characters and new[new[0]+1] ** containing the NULL ** *****************************************************************************/ void TransferIn(TpCStr olds, TpStr pNew, BYTE max) { BYTE lengths; short loop; lengths = (BYTE)F_strlen(olds); /* how many characters to transfer */ if (lengths > max) lengths = max; /* check against specified max */ pNew[0] = lengths; /* assigning an unsigned char to char preserves bit pattern */ /* now copy characters on at a time */ for (loop = 0;loop < (short)lengths;loop++) pNew[loop+1] = olds[loop]; pNew[lengths+1] = '\0'; /* put NULL on end */ } /* end of TransferIn */ /************************* Transfer Out *********************************** ** ** Transfer as much as possible but not more than max characters of the ** Pascal like LSTRING + NULL to an ordinary NULL terminated C string. ** NB new must have been declared at least char[max+1]. ** *****************************************************************************/ void TransferOut(TpCStr olds, TpStr pNew, BYTE max) { BYTE lengths; short loop; lengths = olds[0];/* get the number of chars in the Pascal type LSTRING */ if (lengths > max) lengths = max; /* dont transfer more than max chars */ for (loop = 0;loop < (short)lengths;loop++) pNew[loop] = olds[loop+1]; /* transfer 1 char at a time */ pNew[lengths] = '\0'; /* terminate with NULL */ } /* end of transferOut */ /************************* Set Var Descs ********************************** ** ** NB the useArray will contain its string data as C strings. When strings ** get put into the data structure array in this function they are ** converted to the LSTRING+NULL format required. ** This function sets the data structure variable descriptions and the ** pointers to the corresponding allocated storage positions. ** *****************************************************************************/ void SetVarDescs(short numOfVars, /* number of variable descriptions */ TPointers varPoint, /* pointers to starts of descriptions to be done and data storage places */ TpCVDesc useArray, /* array of values to go in */ TpShort offsets, /* array of computed (setSizes) offsets for data storage */ short vSpace) /* size of data variable area */ { short setloop; TpVDesc p; /* for storage in program use varaible description structs */ for (setloop = 0;setloop < numOfVars;setloop++) { p = varPoint.nameP + setloop; /* point to variable description to set */ p->vSize = offsets[setloop]; /* vsize to hold offset in data array for variable */ p->vType = useArray[setloop].vType; /* copy type from description provided */ p->zeroByte = 0; /* zero extra byte added for MS Pascal compatibility */ TransferIn(useArray[setloop].varUnits,p->varUnits,UNITCHARS); /* units string */ TransferIn(useArray[setloop].varDesc,p->varDesc,DESCCHARS); /* name string */ } /* after the ordinary variable descriptions comes the system one which stores the size of the data space neede for all the variables */ varPoint.nameP[numOfVars].vSize = vSpace; /* now initialise all the variable space to zero */ for (setloop = 0;setloop < vSpace;setloop++) varPoint.dataP[setloop] = 0; } /* end of SetVarDescs */ /************************* Block Round ********************************** ** ** Round up raw (which represents a storage space) to a whole number of blocks ** The block size is to be found in the file info for the program file handle ** specified and is usually 1 or 512. ** *****************************************************************************/ CFSLONG BlockRound(short handle,CFSLONG raw) { CFSLONG retval; short dbs; dbs = g_fileInfo[handle].fileHeadP->diskBlkSize; /* fish out the block size */ if (dbs == 1) retval = raw; else retval = ((raw + dbs - 1) / dbs) * dbs; return retval; } /* end of BlockRound */ /************************* Internal Error ********************************* ** ** Set the global errorInfo values for user to look at, UNLESS it has already ** been used. ** *****************************************************************************/ void InternalError(short handle,short proc,short err) { if (errorInfo.eFound == 0) /* no previous error */ { errorInfo.eFound = 1; errorInfo.eHandleNo = handle; errorInfo.eProcNo = proc; errorInfo.eErrNo = err; } } /* end of Internalerror */ /**************************** File Data *********************************** ** ** Write data to the CFS file corresponding to the program handle. ** Return 1 if ok 0 if not. ** *****************************************************************************/ short FileData(short handle, /* file handle */ TpVoid startP, /* start address from which to transfer */ CFSLONG st, /* file position to which to start writing */ CFSLONG sz) /* number of bytes to transfer */ { WORD res; TpStr pDat = (TpStr)startP; if ((st < 0) || (st >= MAXLSEEK)) return 0; if (CLSeek(g_fileInfo[handle].DOSHdl.d, st, 0) < 0) /* set file pointer */ return 0; if (sz == 0) /* dont try to write 0 bytes it will truncate file */ return 1; while (sz > 0) /* Loop to read the data */ { WORD wr; if (sz > 64000) /* How much to read this time round */ wr = 64000; else wr = (WORD)sz; res = CWriteHandle(g_fileInfo[handle].DOSHdl.d, pDat, wr); /* do write */ if (res == wr) /* keep going if all OK */ { sz -= wr; /* bytes left to do */ pDat += wr; /* pointer to write data */ } else return 0; /* Return failed if not written OK */ } return 1; } /* end of FileData */ /**************************** Load Data *********************************** ** ** Read data from the CFS file corresponding to the program handle. ** Return 1 if ok 0 if not. ** *****************************************************************************/ short LoadData(short handle, /* file handle */ TpVoid startP, /* address in memory to transfer to */ CFSLONG st, /* file position from which to start reading */ CFSLONG sz) /* number of bytes to transfer */ { WORD res; TpStr pDat = (TpStr)startP; if ((st < 0) || (st >= MAXLSEEK)) return 0; if (CLSeek(g_fileInfo[handle].DOSHdl.d,st,0) < 0 ) /* set file pointer */ return 0; while (sz > 0) /* Loop to read the data */ { WORD wr; if (sz > 64000) /* How much to read this time round */ wr = 64000; else wr = (WORD)sz; res = CReadHandle(g_fileInfo[handle].DOSHdl.d, pDat, wr);/* do read */ if (res == wr) /* keep going if all OK */ { sz -= wr; /* bytes left to do */ pDat += wr; /* pointer to read data */ } else return 0; /* Return failed if not read OK */ } return 1; } /* end of LoadData */ /*************************** Get Table *********************************** ** ** Return offset in CFS file for the section,position . ** if the table has been read in then the pointer tableP in g_fileInfo will ** point to it and the entry at (position-1) will correspond to ** the offset for the data section,postiton. ** If the table is not there the offset needs to be read from the ** temporary file. ** *****************************************************************************/ CFSLONG GetTable(short handle, WORD position) { CFSLONG DSPointer; /* return for offset value */ CFSLONG filePosn; /* position in temporary file for offset value */ #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* if table has been read in retrieve offset from it */ if (pfileInfo->tableP != NULL) DSPointer = pfileInfo->tableP[position-1]; else { /* get it from the temporary file */ filePosn = (position-1)*4; /* offset for each DS is CFSLONG ie 4 bytes */ if (pfileInfo->allowed == reading) filePosn=filePosn + pfileInfo->fileHeadP->fileSz - 4*pfileInfo->fileHeadP->dataSecs; CLSeek(pfileInfo->DOSHdl.p, filePosn, 0); /* move to place for read */ CReadHandle(pfileInfo->DOSHdl.p, (TpStr)&DSPointer, 4); /* 4 bytes */ } return DSPointer; } /* end of GetTable */ /*************************** Get Header *********************************** ** ** Reads header of DS requested from CFS file. If current header ** has been altered it is written to the CFS file before being replaced ** by the new one. ** Return value is 0 if all ok and errorcode READERR if failed on reading ** new section or WRITERR if failed when writing current header ** *****************************************************************************/ short GetHeader(short handle, WORD getSection) { CFSLONG tableValue; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif pfileInfo = &g_fileInfo[handle]; /* point to this files information */ if (pfileInfo->thisSection != getSection) /* only get it if different */ { if ((pfileInfo->DSAltered != 0) && /* write changed header to file */ (pfileInfo->allowed != writing)) /* But not if writing */ /* ** can only have DSAltered=1 if GetHeader has already been called and set ** thisSection */ { tableValue = GetTable(handle, pfileInfo->thisSection); if (FileData(handle, pfileInfo->dataHeadP, tableValue, (WORD)pfileInfo->fileHeadP->dataHeadSz) != 0) pfileInfo->DSAltered = 0;/* If saved can clear altered flag */ else return WRITERR; /* error if couldnt save current header */ } tableValue = GetTable(handle, getSection); if (LoadData(handle,pfileInfo->dataHeadP, tableValue, (WORD)pfileInfo->fileHeadP->dataHeadSz) == 0) return READERR; if (pfileInfo->allowed != writing) /* Keep track of actions */ pfileInfo->thisSection = getSection; else pfileInfo->thisSection = 0xFFFF; } return 0; } /* end of getHeader */ /*************************** Store Table *********************************** ** ** Put a CFSLONG offset value into the pointer table or file correspopnding to ** the entry for data section position. ** *****************************************************************************/ void StoreTable(short handle, WORD position, CFSLONG DSPointer) { CFSLONG filePosn; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif pfileInfo = &g_fileInfo[handle]; /* point to this files information */ /* ** look to see if pointer table has been read into memory */ if (pfileInfo->tableP != NULL) { if (position > pfileInfo->fileHeadP->dataSecs) { TpLong pNew; TpVoid pOld = pfileInfo->tableP; /* Previous data pointer */ pNew = (TpLong)CMemAllcn(position*4); if (pNew != NULL) { CMovel(pNew, pfileInfo->tableP, position*4); pfileInfo->tableP = pNew; CFreeAllcn(pOld); } else { /* if (pfileInfo->tableP == NULL) return NOMEMR; BUGBUG what the hell do I do here */ } } pfileInfo->tableP[position-1] = DSPointer; } else { /* table is in temporary file */ filePosn = (CFSLONG)(position-1)*4; /* each entry occupies 4 bytes */ CLSeek(pfileInfo->DOSHdl.p,filePosn,0); CWriteHandle(pfileInfo->DOSHdl.p,(TpStr)&DSPointer,4); } } /* end of storeTable */ /*************************** Recover Table ******************************** ** ** Re-build table holding file offsets of data section headers in the event ** of table size and number of data sections not tallying. ** Uses the information in the file header and individual data section ** headers. ** *****************************************************************************/ short RecoverTable(short handle, /* program file handle */ TpLong relSize, /* location of table size variable */ TpLong tPos, /* location of table position variable this is for return only */ TpUShort dSecs, /* location of number of DS's variable */ TpLong fSize) /* location of file size variable */ { WORD foundSecs,expSecs; CFSLONG secPos,tablePos,maxSecPos,fileSz,tableSz,maxSecs; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif TpFHead fileHP; short retval; THandle pHandle = 0; pfileInfo = &g_fileInfo[handle]; /* point to this files information */ fileHP = pfileInfo->fileHeadP; /* extract values from function parameter pointers */ tableSz = *relSize; /* expected size of table */ fileSz = *fSize; /* expected file size */ expSecs = *dSecs; /* expected number of data sections */ secPos = fileHP->endPnt; /* start place of highest numbered DS */ foundSecs = 0; /* initialise */ maxSecPos = secPos; /* initialise for finding last section in file */ #if 0 if (tableSz > MAXMEMALLOC) return NOMEMR; /* largest memory allocation */ #endif pfileInfo->tableP = (TpLong)CMemAllcn(tableSz); /* allocate space for table */ if (pfileInfo->tableP == NULL) return NOMEMR; maxSecs = tableSz/4; /* memory has been allocated for this number of longs */ if (maxSecs > MAXNODS) maxSecs = MAXNODS; /* dont exceed max */ retval = READERR; while (secPos > 0) /* work back through the data sections */ { foundSecs = (WORD)(foundSecs + 1); /* count how many sections found */ if (foundSecs > (WORD)maxSecs) /* fail if too many */ { retval = XSDS; goto Restore; } pfileInfo->tableP[expSecs-foundSecs] = secPos; /* store the one found starting at end of table */ /* read the DS header into the file info */ if (LoadData(handle,pfileInfo->dataHeadP,secPos, (WORD)fileHP->dataHeadSz) == 0) goto Restore; secPos = pfileInfo->dataHeadP->lastDS; /* extract from header just read in the file position of the previous data section */ if (secPos > maxSecPos) maxSecPos = secPos; /* keep a trace of largest offset found. */ } /* secPos = 0 means that 'previous DS' is in fact the fileheader */ tableSz = 4*foundSecs; /* new value for table size */ tablePos = maxSecPos + fileHP->dataHeadSz; /* end of data header area */ fileSz = tablePos + tableSz; /* new file size */ /* move file pointer to table start position */ if (CLSeek(pfileInfo->DOSHdl.d,tablePos,0) < 0) goto Restore; retval = WRITERR; /* write table to file */ if (CWriteHandle(pfileInfo->DOSHdl.d,(TpStr)&pfileInfo->tableP[expSecs- foundSecs],(WORD)tableSz)< (WORD)tableSz) goto Restore; expSecs = foundSecs; retval = 0; /* all ok */ /* prepare for new value returns via pointer function arguments */ *relSize = tableSz; *tPos = tablePos; *dSecs = expSecs; *fSize = fileSz; Restore:CFreeAllcn(pfileInfo->tableP); pfileInfo->tableP = NULL; return retval; /* error code or 0 */ } /* end of recovertable */ /*************************** Transfer Table ******************************** ** ** Transfer table from current position of file rdHdl to current position ** of file wrHdl in 512 (or 4) byte blocks. ** Return zero or error code ** *****************************************************************************/ short TransferTable(WORD sects, fDef rdHdl, fDef wrHdl) { short retval; TpShort transArr; /* array 512 bytes long */ WORD index,ntran,transSize, lastSize; // THandle pHandle = NULL; CFSLONG lTranBuf; /* last ditch transfer buffer */ retval = 0; /* return value if all ok */ if (sects == 0) return retval; /* Cover our backs */ transSize = 512; /* what we want to transfer */ transArr = (TpShort)CMemAllcn(transSize); if (transArr == NULL) /* have another go with little 4 byte blocks */ { transSize = 4; transArr = (TpShort)&lTranBuf; /* Pointer to stack variable */ } ntran = (WORD)(sects/(transSize/4)); /* number of whole blocks to transfer */ for (index = 1; index <= ntran; index++) { if (CReadHandle(rdHdl,(TpStr)transArr,transSize) < transSize) { retval = READERR; /* retrun error code */ goto Close1; } if (CWriteHandle(wrHdl,(TpStr)transArr,transSize) < transSize) { retval = WRITERR; goto Close1; } } if (ntran * (transSize/4) < sects) /* part of block still to transfer */ { lastSize = (WORD)((sects * 4) - (ntran * transSize)); if (CReadHandle(rdHdl,(TpStr)transArr, lastSize) < lastSize) { retval = READERR; goto Close1; } if (CWriteHandle(wrHdl,(TpStr)transArr, lastSize) < lastSize) retval = WRITERR; } Close1:if (transSize > 4) /* Don't free if using local variable */ CFreeAllcn(transArr); return retval; } /* end of TransferTable */ /*************************** GetMem Table ********************************* ** ** Try to alloacte space for pointer table. ** handle is program file handle, proc is function number from which called. ** Return 1 if alloaction ok 0 if not. ** *****************************************************************************/ short GetMemTable(short handle) { CFSLONG tableSz; #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) TFileInfo _near *pfileInfo; #else TFileInfo *pfileInfo; #endif pfileInfo = &g_fileInfo[handle]; /* point to this files information */ tableSz = 4*(CFSLONG)pfileInfo->fileHeadP->dataSecs; /* 4 bytes per data section */ #if 0 if (tableSz > MAXMEMALLOC) return 0; /* failed */ #endif pfileInfo->tableP = (TpLong)CMemAllcn(tableSz); if (pfileInfo->tableP == NULL) return 0; /* failed */ return 1; /* success */ } /* end of GetMemTable */ /*************************** Allocate Space ******************************** ** ** Function for alloacting space which must be an integral number of steps. ** On entry sizeP points to the variable holding the size of the space ** (in bytes) requested. ** steps is the size in bytes of which the allocated space must be ** an integral multiple. ** On exit the variable pointed to by sizeP is the size of the space ** actually allocated. ** The return value is a pointer to the allocated space, NULL if allocation ** failed. ** *****************************************************************************/ TpStr AllocateSpace(TpUShort sizeP, WORD steps) { WORD buffSize; TpStr buffP; buffSize = *sizeP; /* required buffer size */ buffP = NULL; buffSize = (WORD)((buffSize/steps)*steps); /* truncate to integral number of steps */ while ((buffP == NULL) && (buffSize > 0)) { buffP = (TpStr)CMemAllcn(buffSize); /* do allocation */ if (buffP == NULL) /* want to have another go if failed */ { /* ** try half the size or if this isnt integral number of steps subtract steps */ if (((buffSize/2) % steps) == 0) buffSize = (WORD)(buffSize/2); else buffSize = (WORD)(buffSize - steps); } } /* prepare to return the final size allocated */ *sizeP = buffSize; return buffP; } /* end of AllocateSpace */ /*************************** Extract Bytes ******************************** ** ** Function to extract single channel array from array of interleaved data. ** On entry destP points to the start of array to which to write the ** single channel data. ** dataOffset is the offset in that array at which to start writing. ** srcP points to the start of the interleaved data. ** points is the number of data points to transfer. ** spacing is the number of bytes between data points of ** the channel required in the source array. ** ptSz is the number of bytes per point. ** *****************************************************************************/ void ExtractBytes(TpStr destP,WORD dataOffset,TpStr srcP, WORD points,WORD spacing,WORD ptSz) { WORD index; destP = destP + dataOffset; for (index = 0;index < points;index++) { CMovel(destP,srcP,ptSz); /* Transfer 1 point */ srcP = srcP + spacing; /* move to next point in source */ destP = destP + ptSz; /* move to place for next point */ } } /* end of ExtractBytes */ /*************************** File Update ******************************** ** ** Called when access to file is editing, the file has not yet been changed ** (tablePos != 0) but a real change is about to be made. ** It effectively removes the pointer table from the file and updates the ** file header accordingly. Returns 0 or error code. ** *****************************************************************************/ short FileUpdate(short handle, /* program file handle */ TpFHead fileHP) /* address in memory of file header */ { /* ** 1. Flag that table pointers removed from file */ fileHP->tablePos = 0; /* ** 2. Effect removal of memory table by not including it in file length */ fileHP->fileSz = fileHP->fileSz - 4 * fileHP->dataSecs; /* 4 bytes per DS */ /* ** 3. Write this information to the file as new file header. */ if (FileData(handle, fileHP, 0L, fileHP->fileHeadSz) == 0) return WRITERR; else return 0; } /* end of FileUpdate */ /******************************** E N D **********************************/ stimfit-0.16.7/src/libstfio/cfs/cfslib.cpp0000775000175000017500000005672614752207205014121 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include "./cfslib.h" #include "./cfs.h" #include "../recording.h" namespace stfio { int CFSError(std::string& errorMsg); std::string CFSReadVar(short fHandle,short varNo,short varKind); // Resource management of CFS files // Management of read-only files: class CFS_IFile { public: explicit CFS_IFile(const std::string& filename); ~CFS_IFile(); short myHandle; }; // Management of write-only files: class CFS_OFile { public: explicit CFS_OFile( const std::string& filename, const std::string& comment, std::size_t nChannels=1 ); ~CFS_OFile(); short myHandle; }; const int CFSMAXBYTES=64000; // adopted from FPCfs.ips by U Froebe } stfio::CFS_IFile::CFS_IFile(const std::string& filename) { myHandle = OpenCFSFile(filename.c_str(),0,1); } stfio::CFS_IFile::~CFS_IFile() { if (myHandle>0) { CloseCFSFile(myHandle); } } // Management of write-only files: stfio::CFS_OFile::CFS_OFile(const std::string& filename,const std::string& comment,std::size_t nChannels) { TVarDesc *c_DSArray, *c_fileArray; c_DSArray=NULL; c_fileArray=NULL; myHandle=CreateCFSFile(filename.c_str(), comment.c_str(), 512, (short)nChannels, c_fileArray, c_DSArray, 0/*number of file vars*/, 0/*number of section vars*/); } stfio::CFS_OFile::~CFS_OFile() { CloseCFSFile(myHandle); } int stfio::CFSError(std::string& errorMsg) { short pHandle; short pFunc; short pErr; if (!FileError(&pHandle,&pFunc,&pErr)) return 0; errorMsg = "Error in stfio::"; switch (pFunc) { case (1): errorMsg += "SetFileChan()"; break; case (2): errorMsg += "SetDSChan()"; break; case (3): errorMsg += "SetWriteData()"; break; case (4): errorMsg += "RemoveDS()"; break; case (5): errorMsg += "SetVarVal()"; break; case (6): errorMsg += "GetGenInfo()"; break; case (7): errorMsg += "GetFileInfo()"; break; case (8): errorMsg += "GetVarDesc()"; break; case (9): errorMsg += "GetVarVal()"; break; case (10): errorMsg += "GetFileChan()"; break; case (11): errorMsg += "GetDSChan()"; break; case (12): errorMsg += "DSFlags()"; break; case (13): errorMsg += "OpenCFSFile()"; break; case (14): errorMsg += "GetChanData()"; break; case (15): errorMsg += "SetComment()"; break; case (16): errorMsg += "CommitCFSFile()"; break; case (17): errorMsg += "InsertDS()"; break; case (18): errorMsg += "CreateCFSFile()"; break; case (19): errorMsg += "WriteData()"; break; case (20): errorMsg += "ClearDS()"; break; case (21): errorMsg += "CloseCFSFile()"; break; case (22): errorMsg += "GetDSSize()"; break; case (23): errorMsg += "ReadData()"; break; case (24): errorMsg += "CFSFileSize()"; break; case (25): errorMsg += "AppendDS()"; break; default : errorMsg += ", unknown function"; break; } errorMsg += ":\n"; switch (pErr) { case (-1): errorMsg += "No spare file handles."; break; case (-2): errorMsg += "File handle out of range 0-2."; break; case (-3): errorMsg += " File not open for writing."; break; case (-4): errorMsg += "File not open for editing/writing."; break; case (-5): errorMsg += "File not open for editing/reading."; break; case (-6): errorMsg += "File not open."; break; case (-7): errorMsg += "The specified file is not a CFS file."; break; case (-8): errorMsg += "Unable to allocate the memory needed for the filing system data."; break; case (-11): errorMsg += "Creation of file on disk failed (writing only)."; break; case (-12): errorMsg += "Opening of file on disk failed (reading only)."; break; case (-13): errorMsg += "Error reading from data file."; break; case (-14): errorMsg += "Error writing to data file."; break; case (-15): errorMsg += "Error reading from data section pointer file."; break; case (-16): errorMsg += "Error writing to data section pointer file."; break; case (-17): errorMsg += "Error seeking disk position."; break; case (-18): errorMsg += "Error inserting final data section of the file."; break; case (-19): errorMsg += "Error setting the file length."; break; case (-20): errorMsg += "Invalid variable description."; break; case (-21): errorMsg += "Parameter out of range 0-99."; break; case (-22): errorMsg += "Channel number out of range"; break; case (-24): errorMsg += "Invalid data section number (not in the range 1 to total number of sections)."; break; case (-25): errorMsg += "Invalid variable kind (not 0 for file variable or 1 for DS variable)."; break; case (-26): errorMsg += "Invalid variable number."; break; case (-27): errorMsg += "Data size specified is out of the correct range."; break; case (-30): case (-31): case (-32): case (-33): case (-34): case (-35): case (-36): case (-37): case (-38): case (-39): errorMsg += "Wrong CFS version number in file"; break; default : errorMsg += "An unknown error occurred"; break; } return pErr; } std::string stfio::CFSReadVar(short fHandle,short varNo,short varKind) { std::string errorMsg; std::ostringstream outputstream; TUnits units; std::vector description(DESCCHARS); short varSize=0; TDataType varType; //Get description of a particular file variable //- see manual of CFS file system GetVarDesc(fHandle,varNo,varKind,&varSize,&varType,units,&description[0]); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); //I haven't found a way to directly pass a std::string to GetVarDesc; //passing &s_description[0] won't work correctly. // Added 11/27/06, CSH: Should be possible with vector std::string s_description(description.begin(), description.end()); if (s_description.substr(0,5) != "Spare") { switch (varType) { //Begin switch 'varType' case INT1: case INT2: case INT4: { short shortBuffer=0; //Read the value of the file variable //- see manual of CFS file system GetVarVal(fHandle,varNo,varKind, 1,&shortBuffer); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); outputstream << s_description << " " << shortBuffer << " " << units; break; } case WRD1: case WRD2: { unsigned short ushortBuffer=0; GetVarVal(fHandle,varNo,varKind, 1,&ushortBuffer); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); outputstream << s_description << " " << ushortBuffer << " " << units; break; } case RL4: case RL8: { float floatBuffer=0; GetVarVal(fHandle,varNo,varKind, 1,&floatBuffer); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); outputstream << s_description << " " << floatBuffer << " " << units; break; } case LSTR: { std::vector vc(varSize+2); GetVarVal(fHandle,varNo,varKind, 1, &vc[0]); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); std::string s; s.resize(vc.size()); int ns = 0; for (std::vector::iterator it=vc.begin(); it != vc.end(); ++it) { if ((int)*it == 13) s[ns] = '\n'; else if ((int)*it < 0) s[ns] = '?'; else s[ns] = *it; ns++; } if (s_description.substr(0,11) == "ScriptBlock") { outputstream << s; } else { outputstream << s_description << " " << s; } break; } default: break; } //End switch 'varType' if (s_description.substr(0,11) != "ScriptBlock" ) { outputstream << "\n"; } } return outputstream.str(); } bool stfio::exportCFSFile(const std::string& fName, const Recording& WData, stfio::ProgressInfo& progDlg) { std::string errorMsg; if (fName.length()>1024) { throw std::runtime_error( "Sorry for the inconvenience, but the CFS\n" "library is a bit picky with filenames.\n" "Please restrict yourself to less than\n" "1024 characters.\n" ); } CFS_OFile CFSFile(fName, WData.GetComment(), WData.size()); if (CFSFile.myHandle<0) { std::string errorMsg; CFSError(errorMsg); throw std::runtime_error(errorMsg); } for (std::size_t n_c=0;n_c points(dataSections); TDataType dataType; TCFSKind dataKind; short spacing, other; float xScale=1.0; std::size_t empty_channels=0; for (short n_channel=0; n_channel < channelsAvail; ++n_channel) { //Get constant information for a particular data channel - //see manual of CFS file system. std::vector vchannel_name(22),vyUnits(10),vxUnits(10); CFSLONG startOffset; GetFileChan(CFSFile.myHandle, n_channel, &vchannel_name[0], &vyUnits[0], &vxUnits[0], &dataType, &dataKind, &spacing, &other); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); std::string channel_name(&vchannel_name[0]), xUnits(&vxUnits[0]), yUnits(&vyUnits[0]); //Memory allocation for the current channel float yScale, yOffset, xOffset; //Begin loop: read scaling and offsets //Write the formatted string from 'n_channel' and 'channel_name' to 'buffer' std::ostringstream outputstream; outputstream << "Channel " << n_channel << " (" << channel_name.c_str() << ")\n"; scaling += outputstream.str(); //Get the channel information for a data section or a file //- see manual of CFS file system GetDSChan(CFSFile.myHandle, n_channel /*first channel*/, 1 /*first section*/, &startOffset, &points[0], &yScale, &yOffset,&xScale,&xOffset); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); //Write the formatted string from 'yScale' to 'buffer' outputstream.clear(); outputstream << "Yscale=" << yScale << "\n"; scaling += outputstream.str(); //Write the formatted string from 'xScale' to 'buffer' outputstream.clear(); outputstream << "Xscale=" << xScale << "\n"; scaling += outputstream.str(); //Write the formatted string from 'yOffset' to 'buffer' outputstream.clear(); outputstream << "YOffset=" << yOffset << "\n"; scaling += outputstream.str(); //Write the formatted string from 'xOffset' to 'buffer' outputstream.clear(); outputstream << "XOffset=" << xOffset << "\n"; scaling += outputstream.str(); Channel TempChannel(dataSections); TempChannel.SetChannelName(channel_name); TempChannel.SetYUnits(yUnits); std::size_t empty_sections=0; for (int n_section=0; n_section < dataSections; ++n_section) { int progbar = // Channel contribution: (int)(((double)n_channel/(double)channelsAvail)*100.0+ // Section contribution: (double)n_section/(double)dataSections*(100.0/channelsAvail)); std::ostringstream progStr; progStr << "Reading channel #" << n_channel + 1 << " of " << channelsAvail << ", Section #" << n_section+1 << " of " << dataSections; progDlg.Update(progbar, progStr.str()); //Begin loop: n_sections //Get the channel information for a data section or a file //- see manual of CFS file system CFSLONG startOffset; float yScale, yOffset, xOffset; GetDSChan(CFSFile.myHandle,(short)n_channel,(WORD)n_section+1,&startOffset, &points[n_section],&yScale,&yOffset,&xScale,&xOffset); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); std::ostringstream label; label << fName << ", Section # " << n_section+1; Section TempSection( (int)(points[n_section]), label.str() ); //----------------------------------------------------- //The following part was modified to read data sections //larger than 64 KB as e.g. produced by Igor. //Adopted from FPCfs.ipf by U Froebe //Sections with a size larger than 64 KB have been made //possible by dividing CFS-sections into 'blocks' //----------------------------------------------------- int nBlocks, //number of blocks nBlockBytes; //number of bytes per block //Calculation of the number of blocks depending on the data format: //RL4 - 4 byte floating point numbers (2 byte int numbers otherwise) if (dataType == RL4) nBlocks=(int)(((points[n_section]*4-1)/CFSMAXBYTES) + 1); else nBlocks=(int)(((points[n_section]*2-1)/CFSMAXBYTES) + 1); for (int b=0; b < nBlocks; ++b) { //Begin loop: storage of blocks if (dataType == RL4) { //4 byte data //Read data of the current channel and data section //- see manual of CFS file system //Temporary arrays to store blocks: if (b == nBlocks - 1) nBlockBytes=points[n_section]*4 - b*CFSMAXBYTES; else nBlockBytes=CFSMAXBYTES; Vector_float fTempSection_small(nBlockBytes); GetChanData(CFSFile.myHandle, (short)n_channel, (WORD)n_section+1, b*CFSMAXBYTES/4, (WORD)nBlockBytes/4, &fTempSection_small[0], 4*(points[n_section]+1)); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); for (int n=0; n TempSection_small(nBlockBytes); GetChanData(CFSFile.myHandle, (short)n_channel, (WORD)n_section+1, b*CFSMAXBYTES/2, (WORD)nBlockBytes/2, &TempSection_small[0], 2*(points[n_section]+1)); if (CFSError(errorMsg)) throw std::runtime_error(errorMsg); for (int n=0; n* ** Header file for MSC version of CFS functions. ** Definitions of the structures and routines for the CFS filing * ** system. This is the include file for standard use, all access * ** is by means of functions - no access to the internal CFS data. The file * ** machine.h provides some common definitions across separate platforms, * ** note that the MS variants are designed to accomodate medium model - far * ** pointers are explicitly used where necessary. ** ** CFSAPI Don't declare this to give a pascal type on the Mac, there is a MPW ** compiler bug that corrupts floats passed to pascal functions!!!!!! ** */ #ifndef __CFS__ #define __CFS__ #include "machine.h" #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) #include #define qDebug 0 /* only used to debug Mac stuff */ #define CFSAPI(type) type WINAPI #undef LLIO #undef USEHANDLES #ifdef _MSC_VER #pragma warning( disable : 4251 ) // Disable warning messages #pragma warning( disable : 4996 ) // Disable warning messages #endif #else #define qDebug 0 /* only used to debug Mac stuff */ #if !defined(__APPLE__) && !defined(__MINGW32) #include #endif #include /* MSC I/O function definitions */ #include #include #define CFSAPI(type) type #endif #define FILEVAR 0 /* Constants to indicate whether variable is */ #define DSVAR 1 /* file or data section variable. */ #define INT1 0 /* DATA VARIABLE STORAGE TYPES */ #define WRD1 1 #define INT2 2 #define WRD2 3 #define INT4 4 #define RL4 5 #define RL8 6 #define LSTR 7 #define SUBSIDIARY 2 /* Chan Data Storage types */ #define MATRIX 1 #define EQUALSPACED 0 /* Chan Data Storage types */ #define noFlags 0 /* Declare a default flag */ /* Definitions of bits for DS flags */ #define FLAG7 1 #define FLAG6 2 #define FLAG5 4 #define FLAG4 8 #define FLAG3 16 #define FLAG2 32 #define FLAG1 64 #define FLAG0 128 #define FLAG15 256 #define FLAG14 512 #define FLAG13 1024 #define FLAG12 2048 #define FLAG11 4096 #define FLAG10 8192 #define FLAG9 16384 #define FLAG8 32768 /* define numbers of characters in various string types */ #define DESCCHARS 20 #define FNAMECHARS 12 #define COMMENTCHARS 72 #define UNITCHARS 8 /*character arrays used in data structure */ typedef char TDataType; typedef char TCFSKind; typedef char TDesc[DESCCHARS+2]; /* Names in descriptions, 20 chars */ typedef char TFileName[FNAMECHARS+2]; /* File names, 12 chars */ typedef char TComment[COMMENTCHARS+2]; /* Comment, 72 chars max */ typedef char TUnits[UNITCHARS+2]; /* For units, 8 chars */ /* other types for users benefit */ typedef WORD TSFlags; /* for data and data section variables */ typedef struct { TDesc varDesc; /* users description of variable */ TDataType vType; /* one of 8 types allowed */ char zeroByte; /* for MS Pascal compatibility */ TUnits varUnits; /* users name for units */ short vSize; /* for type lstr gives no. of chars +1 for length byte */ } TVarDesc; #if !defined(_IS_WINDOWS_) || defined(__MINGW32__) typedef char * TpStr; typedef const char * TpCStr; typedef short * TpShort; typedef float * TpFloat; typedef CFSLONG * TpLong; typedef void * TpVoid; typedef TSFlags * TpFlags; typedef TDataType * TpDType; typedef TCFSKind * TpDKind; typedef TVarDesc * TpVDesc; typedef const TVarDesc * TpCVDesc; typedef THandle * TpHandle; typedef signed char * TpSStr; typedef WORD * TpUShort; #else typedef char FAR * TpStr; typedef const char FAR * TpCStr; typedef short FAR * TpShort; typedef float FAR * TpFloat; typedef CFSLONG FAR * TpLong; typedef void FAR * TpVoid; typedef TSFlags FAR * TpFlags; typedef TDataType FAR * TpDType; typedef TCFSKind FAR * TpDKind; typedef TVarDesc FAR * TpVDesc; typedef const TVarDesc FAR * TpCVDesc; typedef THandle FAR * TpHandle; typedef signed char FAR * TpSStr; typedef WORD FAR * TpUShort; #endif #if defined(_IS_WINDOWS_) && !defined(__MINGW32__) typedef HANDLE fDef; /* WIN32 file handle */ #else #ifdef LLIO typedef short fDef; /* file handle */ #else typedef FILE* fDef; /* stream identifier */ #endif #endif #ifdef __cplusplus extern "C" { #endif /* ** Now definitions of the functions defined in the code */ CFSAPI(short) CreateCFSFile(TpCStr fname, TpCStr comment, WORD blocksize, short channels, TpCVDesc fileArray, TpCVDesc DSArray, short fileVars, short DSVars); CFSAPI(void) SetFileChan(short handle, short channel, TpCStr channelName, TpCStr yUnits, TpCStr xUnits, TDataType dataType, TCFSKind dataKind, short spacing, short other); CFSAPI(void) SetDSChan(short handle, short channel, WORD dataSection, CFSLONG startOffset, CFSLONG points, float yScale, float yOffset, float xScale, float xOffset); CFSAPI(short) WriteData(short handle, WORD dataSection, CFSLONG startOffset, WORD bytes, TpVoid dataADS); CFSAPI(short) ClearDS(short handle); CFSAPI(void) SetWriteData(short handle, CFSLONG startOffset, CFSLONG bytes); CFSAPI(CFSLONG) CFSFileSize(short handle); CFSAPI(short) InsertDS(short handle, WORD dataSection, TSFlags flagSet); CFSAPI(short) AppendDS(short handle, CFSLONG lSize, TSFlags flagSet); CFSAPI(void) RemoveDS(short handle, WORD dataSection); CFSAPI(void) SetComment(short handle, TpCStr comment); CFSAPI(void) SetVarVal(short handle, short varNo, short varKind, WORD dataSection, TpVoid varADS); CFSAPI(short) CloseCFSFile(short handle); CFSAPI(short) OpenCFSFile(TpCStr fname, short enableWrite, short memoryTable); CFSAPI(void) GetGenInfo(short handle, TpStr time, TpStr date, TpStr comment); CFSAPI(void) GetFileInfo(short handle, TpShort channels, TpShort fileVars, TpShort DSVars, TpUShort dataSections); CFSAPI(void) GetVarDesc(short handle, short varNo, short varKind, TpShort varSize, TpDType varType, TpStr units, TpStr description); CFSAPI(void) GetVarVal(short handle, short varNo, short varKind, WORD dataSection, TpVoid varADS); CFSAPI(void) GetFileChan(short handle, short channel, TpStr channelName, TpStr yUnits, TpStr xUnits, TpDType dataType, TpDKind dataKind, TpShort spacing, TpShort other); CFSAPI(void) GetDSChan(short handle, short channel, WORD dataSection, TpLong startOffset, TpLong points, TpFloat yScale, TpFloat yOffset, TpFloat xScale, TpFloat xOffset); CFSAPI(WORD) GetChanData(short handle, short channel, WORD dataSection, CFSLONG firstElement, WORD numberElements, TpVoid dataADS, CFSLONG areaSize); CFSAPI(CFSLONG) GetDSSize(short handle, WORD dataSection); CFSAPI(short) ReadData(short handle, WORD dataSection, CFSLONG startOffest, WORD bytes, TpVoid dataADS); CFSAPI(WORD) DSFlagValue(int nflag); CFSAPI(void) DSFlags(short handle, WORD dataSection, short setIt, TpFlags pflagSet); CFSAPI(short) FileError(TpShort handleNo, TpShort procNo, TpShort errNo); CFSAPI(short) CommitCFSFile(short handle); #ifdef __cplusplus } #endif #endif /* __CFS__ */ stimfit-0.16.7/src/libstfio/section.h0000775000175000017500000001215214750344764013210 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file section.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares the Section class. */ /*------------------------------------------------------------------------ * References: * [1] Stroustrup, B.: The C++ Programming Language. 3rd ed. 1997 * [2] Meyers, S.: Effective C++. 3rd ed. 2005 --------------------------------------------------------------------------*/ // only compile once, even if included more often: #ifndef _SECTION_H #define _SECTION_H /*! \addtogroup stfgen * @{ */ //! Represents a continuously sampled sweep of data points class StfioDll Section { public: // Construction/Destruction----------------------------------------------- //! Default constructor. explicit Section(); //! Constructor /*! \param valA A vector of values that will make up the section. * \param label An optional section label string. */ explicit Section( const Vector_double& valA, const std::string& label="\0" ); //! Yet another constructor /*! \param size Number of data points. * \param label An optional section label string. */ explicit Section( std::size_t size, const std::string& label="\0" ); //! Destructor ~Section(); // Operators-------------------------------------------------------------- //! Unchecked access. Returns a non-const reference. /*! \param at Data point index. * \return Copy of the data point with index at. */ double& operator[](std::size_t at) { return data[at]; } //! Unchecked access. Returns a copy. /*! \param at Data point index. * \return Reference to the data point with index at. */ double operator[](std::size_t at) const { return data[at]; } // Public member functions------------------------------------------------ //! Range-checked access. Returns a copy. /*! Throws std::out_of_range if out of range. * \param at_ Data point index. * \return Copy of the data point at index at_ */ double at(std::size_t at_) const; //! Range-checked access. Returns a non-const reference. /*! Throws std::out_of_range if out of range. * \param at_ Data point index. * \return Reference to the data point at index at_ */ double& at(std::size_t at_); //! Low-level access to the valarray (read-only). /*! An explicit function is used instead of implicit type conversion * to access the valarray. * \return The valarray containing the data points. */ const Vector_double& get() const { return data; } //! Low-level access to the valarray (read and write). /*! An explicit function is used instead of implicit type conversion * to access the valarray. * \return The valarray containing the data points. */ Vector_double& get_w() { return data; } //! Resize the Section to a new number of data points; deletes all previously stored data when gcc is used. /*! Note that in the gcc implementation of std::vector, resizing will * delete all the original data. This is different from std::vector::resize(). * \param new_size The new number of data points. */ void resize(std::size_t new_size) { data.resize(new_size); } //! Retrieve the number of data points. /*! \return The number of data points. */ size_t size() const { return data.size(); } //! Sets the x scaling. /*! \param value The x scaling. */ void SetXScale(double value); //! Retrieves the x scaling. /*! \return The x scaling. */ double GetXScale() const { return x_scale; } //! Retrieves a section description. /*! \return A string describing this section. */ const std::string& GetSectionDescription() const { return section_description; } //! Sets a section description. /*! \param value A string describing this section. */ void SetSectionDescription(const std::string& value) { section_description=value; } private: //Private members------------------------------------------------------- // A description that is specific to this section: std::string section_description; // The sampling interval: double x_scale; // The data: Vector_double data; }; /*@}*/ #endif stimfit-0.16.7/src/libstfio/axg/0000775000175000017500000000000014764352501012217 5stimfit-0.16.7/src/libstfio/axg/fileUtils.cpp0000775000175000017500000000312714750344764014620 #include "fileUtils.h" #if defined(_WINDOWS) && !defined(__MINGW32__) #include #include typedef std::wstring wxString; #endif // Mac-specific file access functions // On other platforms, replace the following with equivalent functions /* GetApplicationDirectory returns the volume reference number and directory ID for the demo application's directory. */ filehandle OpenFile( const char *fileName ) { #if defined(_WINDOWS) && !defined(__MINGW32__) std::wstringstream fileNameS; fileNameS << fileName; HANDLE file = CreateFile(fileNameS.str().c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); return file; #else return fopen( fileName, "r" ); #endif } void CloseFile( filehandle dataRefNum ) { #if defined(_WINDOWS) && !defined(__MINGW32__) CloseHandle(dataRefNum); return; #else fclose( dataRefNum ); return; #endif } int SetFilePosition( filehandle dataRefNum, int posn ) { #if defined(_WINDOWS) && !defined(__MINGW32__) if (SetFilePointer(dataRefNum, posn, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) return 1; else return 0; #else return fseek( dataRefNum, posn, SEEK_SET ); #endif } int ReadFromFile( filehandle dataRefNum, AXGLONG *count, void *dataToRead ) { #if defined(_WINDOWS) && !defined(__MINGW32__) DWORD dwRead; short res = ReadFile(dataRefNum, dataToRead, *count, &dwRead, NULL); if (res) return 0; else return 1; #else if ( (AXGLONG)fread( dataToRead, 1, *count, dataRefNum ) == *count ) return 0; else return 1; #endif } stimfit-0.16.7/src/libstfio/axg/axglib.cpp0000775000175000017500000001730514750344764014131 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include #include #include #include "../axg/fileUtils.h" #include "../axg/AxoGraph_ReadWrite.h" #include "../axg/longdef.h" #include "./axglib.h" #include "../recording.h" void stfio::importAXGFile(const std::string &fName, Recording &ReturnData, ProgressInfo& progDlg) { std::string errorMsg("Exception while calling AXG_importAXGFile():\n"); std::string yunits; // ===================================================================================================================== // // Open an AxoGraph file and read in the data // // ===================================================================================================================== progDlg.Update(0, "Opening AXG file..."); filehandle dataRefNum = OpenFile( fName.c_str() ); if ( dataRefNum == 0 ) { errorMsg += "\n\nError: Could not find file."; ReturnData.resize(0); throw std::runtime_error(std::string(errorMsg.c_str())); } // check the AxoGraph header, and get the number of columns to be read int fileFormat = 0; int result = AG_GetFileFormat( dataRefNum, &fileFormat ); if ( result ) { errorMsg += "\nError from AG_GetFileFormat - "; if ( result == kAG_FormatErr ) errorMsg += "file is not in AxoGraph format"; else if ( result == kAG_VersionErr ) errorMsg += "file is of a more recent version than supported by this code"; else errorMsg += "error"; ReturnData.resize(0); CloseFile( dataRefNum ); throw std::runtime_error(errorMsg); } AXGLONG numberOfColumns = 0; result = AG_GetNumberOfColumns( dataRefNum, fileFormat, &numberOfColumns ); if ( result ) { errorMsg += "Error from AG_GetNumberOfColumns"; ReturnData.resize(0); CloseFile( dataRefNum ); throw std::runtime_error(errorMsg); } // Sanity check if ( numberOfColumns <= 0 ) // negative columns { errorMsg += "File format error: number of columns is negative in AxoGraph data file"; ReturnData.resize(0); CloseFile( dataRefNum ); throw std::runtime_error(errorMsg); } // AG_ReadFloatColumn reads column data into a float column structure. int numberOfChannels = 0; std::vector< Section > section_list; std::vector< std::string > channel_names; std::vector< std::string > channel_units; double xscale = 1.0; for ( int columnNumber=0; columnNumber #include #include #include "stringUtils.h" #include "byteswap.h" #include "AxoGraph_ReadWrite.h" int AG_GetFileFormat( filehandle refNum, int *fileFormat ) { *fileFormat = 0; // Read the file header int posn = 0; int result = SetFilePosition( refNum, posn ); // Position the mark at start if ( result ) return result; // Read the 4-byte prefix present in all AxoGraph file formats unsigned char AxoGraphFileID[4]; AXGLONG bytes = 4; // 4 byte identifier result = ReadFromFile( refNum, &bytes, AxoGraphFileID ); if ( result ) return result; // Check the prefix if ( memcmp( AxoGraphFileID, kAxoGraph4DocType, 4 ) == 0 ) { // Got an AxoGraph version 4 format file. Read the file type. short version; bytes = sizeof( short ); result = ReadFromFile( refNum, &bytes, &version ); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapShort( &version ); #endif if ( version != kAxoGraph_Graph_Format && version != kAxoGraph_Digitized_Format ) return kAG_VersionErr; // Return the file format *fileFormat = version; } else if ( memcmp( AxoGraphFileID, kAxoGraphXDocType, 4 ) == 0 ) { // Got an AxoGraph X format file. Check the file version. AXGLONG version = 0; bytes = sizeof( AXGLONG ); result = ReadFromFile( refNum, &bytes, &version ); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapLong( &version ); #endif if ( version < 3 || version > kAxoGraph_X_Format ) { return kAG_VersionErr; } // update to latest version number version = kAxoGraph_X_Format; // Return the file format *fileFormat = version; } else { result = kAG_FormatErr; } // pass back the result ( = 0 if all went well) return result; } int AG_GetNumberOfColumns( filehandle refNum, const int fileFormat, AXGLONG *numberOfColumns ) { *numberOfColumns = 0; if ( fileFormat == kAxoGraph_Digitized_Format || fileFormat == kAxoGraph_Graph_Format ) { // Read the number of columns (short integer in AxoGraph 4 files) short nColumns; AXGLONG bytes = 2; int result = ReadFromFile( refNum, &bytes, &nColumns); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapShort( &nColumns ); #endif *numberOfColumns = nColumns; return result; } else if ( fileFormat == kAxoGraph_X_Format ) { // Read the number of columns (long integer in AxoGraph X files) AXGLONG nColumns; AXGLONG bytes = 4; int result = ReadFromFile( refNum, &bytes, &nColumns); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapLong( &nColumns ); #endif *numberOfColumns = nColumns; return result; } else { return -1; } } int AG_ReadColumn( filehandle refNum, const int fileFormat, const int columnNumber, ColumnData *columnData ) { // Initialize in case of error during read columnData->points = 0; columnData->title = ""; switch ( fileFormat ) { case kAxoGraph_Graph_Format: { // Read the standard column header ColumnHeader columnHeader; AXGLONG bytes = sizeof( ColumnHeader ); int result = ReadFromFile( refNum, &bytes, &columnHeader ); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapLong( &columnHeader.points ); #endif // Retrieve the title and number of points in the column columnData->type = FloatArrayType; columnData->points = columnHeader.points; columnData->title.resize( 80 ); PascalToCString( columnHeader.title ); columnData->title = std::string( (char*)columnHeader.title ); // create a new pointer to receive the data AXGLONG columnBytes = columnHeader.points * sizeof( float ); columnData->floatArray.resize( columnHeader.points ); if ( columnData->floatArray.empty() ) return kAG_MemoryErr; // Read in the column's data result = ReadFromFile( refNum, &columnBytes, &(columnData->floatArray[0]) ); #ifdef __LITTLE_ENDIAN__ ByteSwapFloatArray( &(columnData->floatArray[0]), columnHeader.points ); #endif break; } case kAxoGraph_Digitized_Format: { if ( columnNumber == 0 ) { // Read the column header DigitizedFirstColumnHeader columnHeader; AXGLONG bytes = sizeof( DigitizedFirstColumnHeader ); int result = ReadFromFile( refNum, &bytes, &columnHeader ); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapLong( &columnHeader.points ); ByteSwapFloat( &columnHeader.firstPoint ); ByteSwapFloat( &columnHeader.sampleInterval ); #endif // Retrieve the title, number of points in the column, and sample interval columnData->type = SeriesArrayType; columnData->points = columnHeader.points; columnData->title.resize( 80 ); PascalToCString( columnHeader.title ); columnData->title = std::string( (char*)columnHeader.title ); columnData->seriesArray.firstValue = columnHeader.firstPoint; columnData->seriesArray.increment = columnHeader.sampleInterval; } else { // Read the column header DigitizedColumnHeader columnHeader; AXGLONG bytes = sizeof( DigitizedColumnHeader ); int result = ReadFromFile( refNum, &bytes, &columnHeader ); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapLong( &columnHeader.points ); ByteSwapFloat( &columnHeader.scalingFactor ); #endif // Retrieve the title and number of points in the column columnData->type = ScaledShortArrayType; columnData->points = columnHeader.points; columnData->title.resize( 80 ); PascalToCString( columnHeader.title ); columnData->title = std::string( (char*)columnHeader.title ); columnData->scaledShortArray.scale = columnHeader.scalingFactor; columnData->scaledShortArray.offset = 0; // create a new pointer to receive the data AXGLONG columnBytes = columnHeader.points * sizeof( short ); columnData->scaledShortArray.shortArray.resize( columnHeader.points ); if ( columnData->scaledShortArray.shortArray.empty() ) return kAG_MemoryErr; // Read in the column's data result = ReadFromFile( refNum, &columnBytes, &(columnData->scaledShortArray.shortArray[0]) ); #ifdef __LITTLE_ENDIAN__ ByteSwapShortArray( &(columnData->scaledShortArray.shortArray[0]), columnHeader.points ); #endif } break; } case kAxoGraph_X_Format: { // Read the column header AxoGraphXColumnHeader columnHeader; AXGLONG bytes = sizeof( AxoGraphXColumnHeader ); int result = ReadFromFile( refNum, &bytes, &columnHeader ); if ( result ) return result; #ifdef __LITTLE_ENDIAN__ ByteSwapLong( &columnHeader.points ); ByteSwapLong( &columnHeader.dataType ); ByteSwapLong( &columnHeader.titleLength ); #endif // Retrieve the column type and number of points in the column columnData->type = (ColumnType)columnHeader.dataType; columnData->points = columnHeader.points; // sanity check on column type if ( columnData->type < 0 || columnData->type > 14 ) return -1; // Read the column title columnData->titleLength = columnHeader.titleLength; // columnData->title.resize( columnHeader.titleLength ); std::vector< unsigned char > charBuffer( columnHeader.titleLength, '\0' ); result = ReadFromFile( refNum, &columnHeader.titleLength, &charBuffer[0] ); if ( result ) return result; // Copy characters one by one into title (tedious but safe) for (std::size_t nc=1; nctitle += char(charBuffer[nc]); } // UnicodeToCString( columnData->title, columnData->titleLength ); switch ( columnHeader.dataType ) { case ShortArrayType: { // create a new pointer to receive the data AXGLONG columnBytes = columnHeader.points * sizeof( short ); columnData->shortArray.resize( columnHeader.points ); if ( columnData->shortArray.empty() ) return kAG_MemoryErr; // Read in the column's data result = ReadFromFile( refNum, &columnBytes, &(columnData->shortArray[0]) ); #ifdef __LITTLE_ENDIAN__ ByteSwapShortArray( &(columnData->shortArray[0]), columnHeader.points ); #endif break; } case IntArrayType: { // create a new pointer to receive the data AXGLONG columnBytes = columnHeader.points * sizeof( int ); columnData->intArray.resize( columnHeader.points ); if ( columnData->intArray.empty() ) return kAG_MemoryErr; // Read in the column's data result = ReadFromFile( refNum, &columnBytes, &(columnData->intArray[0]) ); #ifdef __LITTLE_ENDIAN__ ByteSwapLongArray( (AXGLONG *)&(columnData->intArray[0]), columnHeader.points ); #endif break; } case FloatArrayType: { // create a new pointer to receive the data AXGLONG columnBytes = columnHeader.points * sizeof( float ); columnData->floatArray.resize( columnHeader.points ); if ( columnData->floatArray.empty() ) return kAG_MemoryErr; // Read in the column's data result = ReadFromFile( refNum, &columnBytes, &(columnData->floatArray[0]) ); #ifdef __LITTLE_ENDIAN__ ByteSwapFloatArray( &(columnData->floatArray[0]), columnHeader.points ); #endif break; } case DoubleArrayType: { // create a new pointer to receive the data AXGLONG columnBytes = columnHeader.points * sizeof( double ); columnData->doubleArray.resize( columnHeader.points ); if ( columnData->doubleArray.empty() ) return kAG_MemoryErr; // Read in the column's data result = ReadFromFile( refNum, &columnBytes, &(columnData->doubleArray[0]) ); #ifdef __LITTLE_ENDIAN__ ByteSwapDoubleArray( &(columnData->doubleArray[0]), columnHeader.points ); #endif break; } case SeriesArrayType: { SeriesArray seriesParameters; AXGLONG bytes = sizeof( SeriesArray ); result = ReadFromFile( refNum, &bytes, &seriesParameters ); #ifdef __LITTLE_ENDIAN__ ByteSwapDouble( &seriesParameters.firstValue ); ByteSwapDouble( &seriesParameters.increment ); #endif columnData->seriesArray.firstValue = seriesParameters.firstValue; columnData->seriesArray.increment = seriesParameters.increment; break; } case ScaledShortArrayType: { double scale, offset; AXGLONG bytes = sizeof( double ); result = ReadFromFile( refNum, &bytes, &scale ); result = ReadFromFile( refNum, &bytes, &offset ); #ifdef __LITTLE_ENDIAN__ ByteSwapDouble( &scale ); ByteSwapDouble( &offset ); #endif columnData->scaledShortArray.scale = scale; columnData->scaledShortArray.offset = offset; // create a new pointer to receive the data AXGLONG columnBytes = columnHeader.points * sizeof( short ); columnData->scaledShortArray.shortArray.resize( columnHeader.points ); if ( columnData->scaledShortArray.shortArray.empty() ) return kAG_MemoryErr; // Read in the column's data result = ReadFromFile( refNum, &columnBytes, &(columnData->scaledShortArray.shortArray[0]) ); #ifdef __LITTLE_ENDIAN__ ByteSwapShortArray( &(columnData->scaledShortArray.shortArray[0]), columnHeader.points ); #endif break; } } } break; default: { return -1; } } return 0; } std::string AG_ReadComment( filehandle refNum ) { // File comment std::ostringstream comment; comment << "\0"; AXGLONG comment_size = 0; AXGLONG bytes = sizeof(AXGLONG); int result = ReadFromFile( refNum, &bytes, &comment_size ); if ( result ) return comment.str(); #ifdef __LITTLE_ENDIAN__ ByteSwapLong( &comment_size ); #endif if (comment_size > 0) { std::vector< unsigned char > charBuffer( comment_size, '\0' ); result = ReadFromFile( refNum, &comment_size, &charBuffer[0] ); if ( result ) return comment.str(); // Copy characters one by one into title (tedious but safe) for (std::size_t nc=1; nc 0) { std::vector< unsigned char > charBuffer( notes_size, '\0' ); result = ReadFromFile( refNum, ¬es_size, &charBuffer[0] ); if ( result ) return notes.str(); // Copy characters one by one into title (tedious but safe) for (std::size_t nc=1; nctype ) { case ShortArrayType: { // Convert in the column data columnData->floatArray.resize( columnData->shortArray.size() ); std::copy( columnData->shortArray.begin(), columnData->shortArray.end(), columnData->floatArray.begin() ); columnData->shortArray.resize(0); columnData->type = FloatArrayType; return result; } case IntArrayType: { // Convert in the column data columnData->floatArray.resize( columnData->intArray.size() ); std::copy( columnData->intArray.begin(), columnData->intArray.end(), columnData->floatArray.begin() ); columnData->intArray.resize(0); columnData->type = FloatArrayType; return result; } case FloatArrayType: { // Don't need to convert return result; } case DoubleArrayType: { // Convert in the column data columnData->floatArray.resize( columnData->doubleArray.size() ); std::copy( columnData->doubleArray.begin(), columnData->doubleArray.end(), columnData->floatArray.begin() ); columnData->doubleArray.resize(0); columnData->type = FloatArrayType; return result; } case SeriesArrayType: { // create a new pointer to receive the converted data double firstValue = columnData->seriesArray.firstValue; double increment = columnData->seriesArray.increment; columnData->floatArray.resize( columnData->points ); // Convert in the column data for ( AXGLONG i = 0; i < columnData->points; i++ ) { columnData->floatArray[i] = (float)(firstValue + i * increment); } columnData->type = FloatArrayType; return result; } case ScaledShortArrayType: { // create a new pointer to receive the converted data double scale = columnData->scaledShortArray.scale; double offset = columnData->scaledShortArray.offset; columnData->floatArray.resize( columnData->points ); // Convert in the column data for ( AXGLONG i = 0; i < columnData->points; i++ ) { columnData->floatArray[i] = (float)(columnData->scaledShortArray.shortArray[i] * scale + offset); } // free old short array columnData->scaledShortArray.shortArray.resize(0); // pass in new float array columnData->type = FloatArrayType; return result; } default: { return result; } } } stimfit-0.16.7/src/libstfio/axg/byteswap.cpp0000775000175000017500000000402214750344764014511 // ****************************************************************************************** // Graph Document Routines // Copyright 1996 Dr. John Clements. All rights reserved. // ****************************************************************************************** #include "byteswap.h" void ByteSwapShort( short *shortNumber ) { unsigned short *uShortNumber = ( unsigned short * )shortNumber; *uShortNumber = ( ( *uShortNumber >> 8 ) | ( *uShortNumber << 8 ) ); } void ByteSwapLong( AXGLONG *longNumber ) { unsigned int *uLongNumber = ( unsigned int * )longNumber; *uLongNumber = ( ( ( *uLongNumber & 0x000000FF )<<24 ) + ( ( *uLongNumber & 0x0000FF00 )<<8 ) + ( ( *uLongNumber & 0x00FF0000 )>>8 ) + ( ( *uLongNumber & 0xFF000000 )>>24 ) ); } void ByteSwapFloat( float *floatNumber ) { unsigned int *uLongNumber = ( unsigned int * )floatNumber; *uLongNumber = ( ( ( *uLongNumber & 0x000000FF )<<24 ) + ( ( *uLongNumber & 0x0000FF00 )<<8 ) + ( ( *uLongNumber & 0x00FF0000 )>>8 ) + ( ( *uLongNumber & 0xFF000000 )>>24 ) ); } void ByteSwapDouble( double *doubleNumber ) { // cast the double to an array of two unsigned ints unsigned int *uLongArray = ( unsigned int * )doubleNumber; // swap the bytes in each long ByteSwapLong( ( AXGLONG * )&uLongArray[0] ); ByteSwapLong( ( AXGLONG * )&uLongArray[1] ); // swap the two longs unsigned int saveLong0 = uLongArray[0]; uLongArray[0] = uLongArray[1]; uLongArray[1] = saveLong0; } void ByteSwapShortArray( short *shortArray, int arraySize ) { for ( int i = 0; i < arraySize; i++ ) { ByteSwapShort( shortArray++ ); } } void ByteSwapLongArray( AXGLONG *longArray, int arraySize ) { for ( int i = 0; i < arraySize; i++ ) { ByteSwapLong( longArray++ ); } } void ByteSwapFloatArray( float *floatArray, int arraySize ) { for ( int i = 0; i < arraySize; i++ ) { ByteSwapFloat( floatArray++ ); } } void ByteSwapDoubleArray( double *doubleArray, int arraySize ) { for ( int i = 0; i < arraySize; i++ ) { ByteSwapDouble( doubleArray++ ); } } stimfit-0.16.7/src/libstfio/axg/axglib.h0000775000175000017500000000410614750344764013571 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file axglib.h * \author Christoph Schmidt-Hieber * \date 2008-01-23 * \brief Import Axograph X binary files. */ #ifndef _AXGLIB_H #define _AXGLIB_H #include "../stfio.h" class Recording; namespace stfio { //! Open an AXG file and store its contents to a Recording object. /*! \param fName The full path to the file to be opened. * \param ReturnData On entry, an empty Recording object. On exit, * the data stored in \e fName. * \param progress True if the progress dialog should be updated. */ void importAXGFile(const std::string& fName, Recording& ReturnData, ProgressInfo& progDlg); } #endif stimfit-0.16.7/src/libstfio/axg/fileUtils.h0000775000175000017500000000125214750344764014262 #ifndef FILEUTILS_H #define FILEUTILS_H #define kAG_Creator 'AxG2' #define kAG_DocType 'AxGr' #define kAGX_Creator 'AxGX' #define kAGX_DocType 'axgx' #include "longdef.h" #if 0 typedef const int filehandle; #else #if !defined(_WINDOWS) || defined(__MINGW32__) #include typedef FILE* filehandle; #else #include "Windows.h" typedef HANDLE filehandle; #endif #endif #include "stringUtils.h" filehandle OpenFile( const char *fileName ); void CloseFile( filehandle dataRefNum ); int SetFilePosition( filehandle dataRefNum, int posn ); int ReadFromFile( filehandle dataRefNum, AXGLONG *count, void *dataToRead ); #endif stimfit-0.16.7/src/libstfio/axg/stringUtils.h0000775000175000017500000000050014750344764014644 #ifndef STRINGUTILS_H #define STRINGUTILS_H #include "longdef.h" typedef unsigned char axgchar; void PascalToCString( axgchar *string ); void CToPascalString( axgchar *string ); void UnicodeToCString( axgchar *string, const int stringBytes ); void CStringToUnicode( axgchar *string, const int stringBytes ); #endif stimfit-0.16.7/src/libstfio/axg/byteswap.h0000775000175000017500000000160614750344764014163 #ifndef BYTESWAP_H #define BYTESWAP_H #include "longdef.h" //------------------------ Byte Swap Routines ------------------------- // swap bytes in a short (2 byte) variable void ByteSwapShort( short *shortNumber ); // swap bytes in an int (4 byte) variable void ByteSwapLong( AXGLONG *longNumber ); // swap bytes in a float (4 byte) variable void ByteSwapFloat( float *floatNumber ); // swap bytes in a double (8 byte) variable void ByteSwapDouble( double *doubleNumber ); // swap bytes in a short (2 byte) array void ByteSwapShortArray( short *shortArray, int arraySize ); // swap bytes in an int (4 byte) array void ByteSwapLongArray( AXGLONG *longArray, int arraySize ); // swap bytes in a float (4 byte) array void ByteSwapFloatArray( float *floatArray, int arraySize ); // swap bytes in a double (8 byte) array void ByteSwapDoubleArray( double *doubleArray, int arraySize ); #endif stimfit-0.16.7/src/libstfio/axg/AxoGraph_ReadWrite.h0000664000175000017500000003575514750344764016015 #ifndef AXOGRAPH_READEWRITE_H #define AXOGRAPH_READEWRITE_H /* ---------------------------------------------------------------------------------- AxoGraph_ReadWrite : functions for reading and writing AxoGraph data files. See also : the example programs which uses these functions, Demo_AxoGraph_ReadWrite and Simple_AxoGraph_ReadWrite This source code and the AxoGraph data file format are in the public domain. To run on little endian hardware (Intel, etc.) __LITTLE_ENDIAN__ must be defined This is done automatically under OS X / XCode 2008-12-14: Some modifications to avoid unfreed mallocs using std::vector C. Schmidt-Hieber ---------------------------------------------------------------------------------- The three AxoGraph file formats are descibed here for completeness, but this information is not needed in order to use the supplied AxoGraph file functions to read and write binary data. For information about reading and writing graph display information, see the end of the section on the AxoGraph X file format. AxoGraph Data File Format ========================= Header ------ Byte Type Contents 0 char[4] AxoGraph file header identifier = 'AxGr' - same as document type ID 4 short AxoGraph graph file format ID = 1 6 short Number of columns to follow Each column ----------- Byte Type Contents 0 long Number of points in the column ( columnPoints ) 4 char[80] Column title (Pascal 'String' format) - S.I. units should be in brackets e.g. 'Current (pA)' 84 float 1st Data point 88 float 2nd Data point .. .. .... .. .. etc. ---------------------------------------------------------------------------------- AxoGraph Digitized Data File Format =================================== Header ------ Byte Type Contents 0 char[4] AxoGraph file header identifier = 'AxGr' - same as document type ID 4 short AxoGraph file format ID = 2 6 short Number of columns to follow Each column ---------------------- Byte Type Contents 0 long Number of points in the column ( columnPoints ) 4 long Data type 8 char[80] Column title (Pascal 'String' format) - S.I. units should be in brackets e.g. 'Current (pA)' 84 float Scaling Factor 88 short 1st Data point 90 short 2nd Data point .. ... .... .. ... etc. ---------------------------------------------------------------------------------- AxoGraph X Data File Format =================================== Header ------ Byte Type Contents 0 char[4] AxoGraph file header identifier = 'AxGx' - same as filename extension 4 long AxoGraph X file format ID = a number between 3 (earliest version) and 6 (latest version) 8 long Number of columns to follow Each column ---------------------- Byte Type Contents 0 long Number of points in the column ( columnPoints ) 4 long Column type 8 long Length of column title in bytes (Unicode - 2 bytes per character) 12 char* Column title (Unicode 2 byte per char) - S.I. units should be in brackets e.g. 'Current (pA)' ?? ?? Byte offset depends on length of column title string. .. ... Numeric type and layout depend on the column type .. ... .... .. ... etc. Six column types are supported... 4: short 5: long 6: float 7: double 9: 'series' 10: 'scaled short' In the first four column types, data is stored as a simple array of the corresponding type. The 'scaled short' column type stores data as a 'double' scaling factor and offset, and a 'short' array. The 'series' column type stores data as a 'double' first value and a 'double' increment. Prior to AxoGraph X, all graph display information was stored in the 'resource fork' of the file, and the resource fork format was not documented. In contrast, AxoGraph X has a 'flat' format with all display information stored immediately following the data columns. It is safe to simply leave out this information. AxoGraph X will use default parameters when the file is read in. For greater control of graph appearance when creating a file it may be necessary to add display format information. When reading in a file, it may be necessary to access the 'Notes' string. The following is a preliminary description of the file format used to store important elements of graph display information. Reading 'notes' and graph format info is not supported in the AxoGraph_ReadWrite example functions. The Comment and Notes strings are stored immediately after the last data column. Both are stored in Unicode string format.. Unicode string format ---------------------- long Length of string in bytes char* Notes string (Unicode 2 byte per char) For Latin1 strings, every second byte is an ASCII character code Each trace consists of a pair of columns. The trace header specifies the X and Y column numbers, and other trace-specific information. 'bool' header fields are stored as long int: false = 0, true = 1 The number of traces is stored immediately after the comment and notes strings. long Number of trace headers to follow Header for each trace ---------------------- long header version number (currently = 2) long X column number long Y column number long Error bar column number or -1 if no error bars long Negative error bar column number or -1 if no negative error bars long Group number that this column belongs to bool Trace shown? False if trace is hidden double Minimum X data point in this trace double Maximum X data point in this trace (if both are zero, they will be recalculated) double Minimum positive X data point in this trace (used in log-axis format) bool True if X axis data is regularly spaced bool True if X axis data is monotonic (each point > previous point) double Interval between points for regular X axis data double Minimum Y data point in this trace double Maximum Y data point in this trace (if both are zero, they will be recalculated) double Minimum positive Y data point in this trace (used in log-axis format) long Trace color with RGB values serialized into a long int bool True if a line plot joining the data points is displayed double Thickness of the line plot (can be less than 1.0 for fine lines) long Pen style (zero for solid line, non zero for dashed lines) bool True if symbols are displayed long Symbol type long Symbol size (radius in pixels) bool True if some symbols are to be skipped bool True if symbols are to be skipped by distance instead of number of points long Minimum separation of symbols in pixels is previous parameter is true bool True for a histogram plot long Type of histogram (zero for standard solid fill) long Separation between adjacent histogram bars expressed as a percentage of bar width bool True if error bars are displayed bool True if a positive error bar is displayed bool True if a negative error bar is displayed long Error bar width in pixels ---------------------------------------------------------------------------------- */ // uncomment the following line to run on little endian hardware ( byte swaps data before reading or writing ) #ifdef __APPLE__ #include #elif defined(__MINGW32__) #define __LITTLE_ENDIAN__ #elif !defined(_MSC_VER) #include #else #define __LITTLE_ENDIAN__ #endif #ifdef __LITTLE_ENDIAN #define __LITTLE_ENDIAN__ #endif #include "longdef.h" #include "fileUtils.h" #include "./../stfio.h" // errors numbers const short kAG_MemoryErr = -21; const short kAG_FormatErr = -23; const short kAG_VersionErr = -24; // file format id's const short kAxoGraph_Graph_Format = 1; const short kAxoGraph_Digitized_Format = 2; const short kAxoGraph_X_Format = 6; const short kAxoGraph_X_Digitized_Format = 6; const axgchar kAxoGraph4DocType[4] = { 'A', 'x', 'G', 'r' }; const axgchar kAxoGraphXDocType[4] = { 'a', 'x', 'g', 'x' }; // column header for AxoGraph graph files struct ColumnHeader { AXGLONG points; axgchar title[80]; }; // x-axis column header for AxoGraph digitized files struct DigitizedFirstColumnHeader { AXGLONG points; axgchar title[80]; float firstPoint; float sampleInterval; }; // y-axis column header for AxoGraph digitized files struct DigitizedColumnHeader { AXGLONG points; axgchar title[80]; float scalingFactor; }; // column header for AxoGraph X files struct AxoGraphXColumnHeader { AXGLONG points; AXGLONG dataType; AXGLONG titleLength; }; struct AxoGraphXTraceHeader { long nHeaderVersion; // header version number (currently = 2) long nColumnX; // X column number long nColumnY; // Y column number long nError; // Error bar column number or -1 if no error bars long nErrorBarColumn; // Negative error bar column number or -1 if no negative error bars long nGroup; // Group number that this column belongs to bool isShown; // Trace shown? False if trace is hidden double dMinX; // Minimum X data point in this trace double dMaxX; // Maximum X data point in this trace (if both are zero, they will be recalculated) double dMinPosX; // Minimum positive X data point in this trace (used in log-axis format) bool bXEqSpaced; // True if X axis data is regularly spaced bool bXMonotonic; // True if X axis data is monotonic (each point > previous point) double dXInterval; // Interval between points for regular X axis data double dMinY; // Minimum Y data point in this trace double dMaxY; // Maximum Y data point in this trace (if both are zero, they will be recalculated) double dMinPosY; // Minimum positive Y data point in this trace (used in log-axis format) long nRGB; // Trace color with RGB values serialized into a long int bool bLinejoin; // True if a line plot joining the data points is displayed double dLineThickness; // Thickness of the line plot (can be less than 1.0 for fine lines) long nLineStyle; // Pen style (zero for solid line, non zero for dashed lines) bool bSymbol; // True if symbols are displayed long nSymbolType; // Symbol type long nSymbolSize; // Symbol size (radius in pixels) bool bSymbolSkip; // True if some symbols are to be skipped bool bSymbolSkipDist; // True if symbols are to be skipped by distance instead of number of points long nSympolDist; // Minimum separation of symbols in pixes is previous parameter is true bool bHisto; // True for a histogram plot long nHistoType; // Type of histogram (zero for standard solid fill) long nHistoDist; // Separation between adjacent histogram bars expressed as a percentage of bar width bool bError; // True if error bars are displayed bool bErrorPos; // True if a positive error bar is displayed bool bErrorNeg; // True if a negative error bar is displayed long nErrorWidth; // Error bar width in pixels }; //============= ColumnData structure ====================== // This enum is copied from AxoGraph X source code // The only types used for data file columns are... // ShortArrayType = 4 IntArrayType = 5 // FloatArrayType = 6 DoubleArrayType = 7 // SeriesArrayType = 9 ScaledShortArrayType = 10 enum ColumnType { IntType, DoubleType, BoolType, StringType, ShortArrayType, IntArrayType, FloatArrayType, DoubleArrayType, BoolArrayType, SeriesArrayType, ScaledShortArrayType, StringArrayType, ReferenceType }; struct SeriesArray { double firstValue; double increment; }; struct ScaledShortArray { double scale; double offset; std::vector shortArray; }; struct ColumnData { ColumnType type; AXGLONG points; AXGLONG titleLength; std::string title; std::vector shortArray; std::vector intArray; Vector_float floatArray; Vector_double doubleArray; SeriesArray seriesArray; ScaledShortArray scaledShortArray; }; // ----------- AxoGraph Read and Write functions ------------- int AG_GetFileFormat( filehandle refNum, int *fileFormat ); // Check that the file referenced by refNum is an AxoGraph data file // and read in the file format. Legal values are 1, 2, or 3, // corresponding to AxoGraph Graph, Digitized, or AxoGraph X formats. // Called once per file. Returns 0 if all goes well. // If an error occurs, returns the result from the file access functions, // or kAG_FormatErr if file is not in AxoGraph format, // or kAG_VersionErr if the file is of a more recent version than supported by this code. int AG_GetNumberOfColumns( filehandle refNum, const int fileFormat, AXGLONG *numberOfColumns ); // Read in the number of columns to follow in this file. // Called once per file. Returns 0 if all goes well. // If an error occurs, returns the result from the file access functions, int AG_ReadColumn( filehandle refNum, const int fileFormat, const int columnNumber, ColumnData *columnData ); // Read in a column from any AxoGraph data file. // Called once for each column in the file. // Returns data in a pointer in structure that contains the number of points, // the column title, and the column data. // This function allocates new pointers of the appropriate size, reads the data into // them and returns it in columnData. std::string AG_ReadComment( filehandle refNum ); // Read in comment from an AxoGraph X data file. std::string AG_ReadNotes( filehandle refNum ); // Read in notes from an AxoGraph X data file. std::string AG_ReadTraceHeaders( filehandle refNum ); // Read in trace headers from an AxoGraph X data file. std::string AG_ParseDate( const std::string& notes ); std::string AG_ParseTime( const std::string& notes ); int AG_ReadFloatColumn( filehandle refNum, const int fileFormat, const int columnNumber, ColumnData *columnData ); // Read in a column from any AxoGraph data file. // Convert the column data to a float array, regardless of the input column format // Called once for each column in the file. // Returns data in a pointer in structure that contains the number of points, // the column title, and the column data. // This function allocates new pointers of the appropriate size, reads the data into // them and returns it in columnData. #endif stimfit-0.16.7/src/libstfio/axg/stringUtils.cpp0000775000175000017500000000227314750344764015210 #include "stringUtils.h" // In place string converstion functions void PascalToCString( axgchar *string ) { // First byte of pascal string contains string length short stringLength = string[0]; // Shift string left for ( short i = 0; i < stringLength; i++ ) string[i] = string[i+1]; // Append null byte string[stringLength] = 0; } void CToPascalString( axgchar *string ) { // Find first null byte (determine string length) short i = 0; while ( string[i++] ); short stringLength = i - 1; // Shift string right for ( short j = stringLength-1; j >= 0; j-- ) string[j+1] = string[j]; // Insert length byte string[0] = stringLength; } void UnicodeToCString( axgchar *string, const int stringBytes ) { // Construct C string from every second byte int stringLength = stringBytes / 2; for ( int i = 0; i < stringLength; i++ ) string[i] = string[i*2+1]; // Append null byte string[stringLength] = 0; } void CStringToUnicode( axgchar *string, const int stringBytes ) { // Expand C string to every second byte // Set first byte to null int stringLength = stringBytes / 2; for ( int i = stringLength-1; i >= 0; i-- ) { string[i*2+1] = string[i]; string[i*2] = 0; } } stimfit-0.16.7/src/libstfio/axg/longdef.h0000664000175000017500000000033714750344764013740 #ifndef LONGDEF_H #define LONGDEF_H #include #if defined (_WIN64) #define AXGLONG int #elif ( __WORDSIZE == 64 ) || defined (__APPLE__) #define AXGLONG int #else #define AXGLONG long #endif #endif stimfit-0.16.7/src/libstfio/stfio.cpp0000664000175000017500000002747314752207205013222 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file stfio.cpp * \author Christoph Schmidt-Hieber * \date 2011-09-25 * \brief General functions for libstfio * * * Implements some general functions for libstfio */ // Copyright 2012 Alois Schloegl, IST Austria #include #include "stfio.h" // TODO #include "./ascii/asciilib.h" #include "./hdf5/hdf5lib.h" #include "./abf/abflib.h" #include "./atf/atflib.h" #include "./axg/axglib.h" #include "./igor/igorlib.h" #if (defined(WITH_BIOSIG)) #include "./biosig/biosiglib.h" #else #include "./heka/hekalib.h" #endif #include "./cfs/cfslib.h" #include "./intan/intanlib.h" #ifdef _MSC_VER StfioDll long int lround(double x) { int i = (long int) x; if (x >= 0.0) { return ((x-i) >= 0.5) ? (i + 1) : (i); } else { return (-x+i >= 0.5) ? (i - 1) : (i); } } #endif stfio::StdoutProgressInfo::StdoutProgressInfo(const std::string& title, const std::string& message, int maximum, bool verbose) : ProgressInfo(title, message, maximum, verbose), verbosity(verbose) { if (verbosity) { std::cout << title << std::endl; std::cout << message << std::endl; } } bool stfio::StdoutProgressInfo::Update(int value, const std::string& newmsg, bool* skip) { if (verbosity) { std::cout << "\r"; std::cout.width(3); std::cout << value << "% " << newmsg << std::flush; } return true; } #ifndef TEST_MINIMAL stfio::filetype stfio::findType(const std::string& ext) { if (ext=="*.dat;*.cfs") return stfio::cfs; else if (ext=="*.cfs") return stfio::cfs; else if (ext=="*.abf") return stfio::abf; else if (ext=="*.axgd") return stfio::axg; else if (ext=="*.axgx") return stfio::axg; else if (ext=="*.axgd;*.axgx") return stfio::axg; else if (ext=="*.h5") return stfio::hdf5; else if (ext=="*.atf") return stfio::atf; else if (ext=="*.dat") return stfio::heka; else if (ext=="*.smr") return stfio::son; else if (ext=="*.tdms") return stfio::tdms; else if (ext=="*.clp") return stfio::intan; #if defined(WITH_BIOSIG) else if (ext=="*.dat;*.cfs;*.gdf;*.ibw;*.wcp") return stfio::biosig; else if (ext=="*.*") return stfio::biosig; #endif else return stfio::none; } #endif // TEST_MINIMAL std::string stfio::findExtension(stfio::filetype ftype) { switch (ftype) { case stfio::cfs: return ".dat"; case stfio::abf: return ".abf"; case stfio::axg: return ".axg*"; case stfio::igor: return ".ibw"; case stfio::hdf5: return ".h5"; case stfio::atf: return ".atf"; case stfio::heka: return ".dat"; case stfio::son: return ".smr"; case stfio::tdms: return ".tdms"; case stfio::intan: return ".clp"; #if defined(WITH_BIOSIG) case stfio::biosig: return ".gdf"; #endif default: return ".*"; } } bool stfio::importFile( const std::string& fName, stfio::filetype type, Recording& ReturnData, const stfio::txtImportSettings& txtImport, ProgressInfo& progDlg ) { try { #if defined(WITH_BIOSIG) // make use of automated file type identification try { stfio::filetype type1 = stfio::importBiosigFile(fName, ReturnData, progDlg); switch (type1) { case stfio::biosig: return true; // succeeded case stfio::none: break; // do nothing, use input argument for deciding on type default: type = type1; // filetype is recognized and should be used below } } catch (...) { // this should never occur, importBiosigFile should always return without exception std::cout << "importBiosigFile failed with an exception - this is a bug"; } #endif switch (type) { case stfio::hdf5: { stfio::importHDF5File(fName, ReturnData, progDlg); break; } case stfio::abf: { stfio::importABFFile(fName, ReturnData, progDlg); break; } case stfio::atf: { stfio::importATFFile(fName, ReturnData, progDlg); break; } case stfio::axg: { stfio::importAXGFile(fName, ReturnData, progDlg); break; } case stfio::intan: { stfio::importIntanFile(fName, ReturnData, progDlg); break; } case stfio::cfs: { stfio::importCFSFile(fName, ReturnData, progDlg); break; } default: throw std::runtime_error("Unknown or unsupported file type"); } } catch (...) { throw; } return true; } bool stfio::exportFile(const std::string& fName, stfio::filetype type, const Recording& Data, ProgressInfo& progDlg) { try { switch (type) { case stfio::atf: { stfio::exportATFFile(fName, Data); break; } #if defined(WITH_BIOSIG) case stfio::biosig: { stfio::exportBiosigFile(fName, Data, progDlg); break; } #endif case stfio::cfs: { stfio::exportCFSFile(fName, Data, progDlg); break; } case stfio::hdf5: { stfio::exportHDF5File(fName, Data, progDlg); break; } case stfio::igor: { stfio::exportIGORFile(fName, Data, progDlg); break; } default: throw std::runtime_error("Trying to write an unsupported dataformat."); } } catch (...) { throw; } return true; } Vector_double stfio::vec_scal_plus(const Vector_double& vec, double scalar) { Vector_double ret_vec(vec.size(), scalar); std::transform(vec.begin(), vec.end(), ret_vec.begin(), ret_vec.begin(), std::plus()); return ret_vec; } Vector_double stfio::vec_scal_minus(const Vector_double& vec, double scalar) { Vector_double ret_vec(vec.size(), scalar); std::transform(vec.begin(), vec.end(), ret_vec.begin(), ret_vec.begin(), std::minus()); return ret_vec; } Vector_double stfio::vec_scal_mul(const Vector_double& vec, double scalar) { Vector_double ret_vec(vec.size(), scalar); std::transform(vec.begin(), vec.end(), ret_vec.begin(), ret_vec.begin(), std::multiplies()); return ret_vec; } Vector_double stfio::vec_scal_div(const Vector_double& vec, double scalar) { Vector_double ret_vec(vec.size(), scalar); std::transform(vec.begin(), vec.end(), ret_vec.begin(), ret_vec.begin(), std::divides()); return ret_vec; } Vector_double stfio::vec_vec_plus(const Vector_double& vec1, const Vector_double& vec2) { Vector_double ret_vec(vec1.size()); std::transform(vec1.begin(), vec1.end(), vec2.begin(), ret_vec.begin(), std::plus()); return ret_vec; } Vector_double stfio::vec_vec_minus(const Vector_double& vec1, const Vector_double& vec2) { Vector_double ret_vec(vec1.size()); std::transform(vec1.begin(), vec1.end(), vec2.begin(), ret_vec.begin(), std::minus()); return ret_vec; } Vector_double stfio::vec_vec_mul(const Vector_double& vec1, const Vector_double& vec2) { Vector_double ret_vec(vec1.size()); std::transform(vec1.begin(), vec1.end(), vec2.begin(), ret_vec.begin(), std::multiplies()); return ret_vec; } Vector_double stfio::vec_vec_div(const Vector_double& vec1, const Vector_double& vec2) { Vector_double ret_vec(vec1.size()); std::transform(vec1.begin(), vec1.end(), vec2.begin(), ret_vec.begin(), std::divides()); return ret_vec; } Recording stfio::concatenate(const Recording& src, const std::vector& sections, ProgressInfo& progDlg) { size_t nc, NC = src.size(); Recording Concatenated(NC, 1); for (nc = 0; nc < NC; nc++) { int new_size=0; for (c_st_it cit = sections.begin(); cit != sections.end(); cit++) { new_size += (int)src[nc][*cit].size(); } Section TempSection(new_size); std::size_t n_new=0; std::size_t n_s=0; for (c_st_it cit = sections.begin(); cit != sections.end(); cit++) { std::ostringstream progStr; progStr << "Adding section #" << (int)n_s+1 << " of " << (int)sections.size(); progDlg.Update( (int)((double)n_s/(double)sections.size()*100.0), progStr.str() ); if (cit == sections.begin()) { TempSection.SetXScale(src[nc][*cit].GetXScale()); } else if (TempSection.GetXScale() != src[nc][*cit].GetXScale()) { Concatenated.resize(0); throw std::runtime_error("can not concatanate because sampling frequency differs"); } std::size_t secSize=src[nc][*cit].size(); if (n_new+secSize>TempSection.size()) { Concatenated.resize(0); throw std::runtime_error("memory allocation error"); } std::copy(src[nc][*cit].get().begin(), src[nc][*cit].get().end(), &TempSection[n_new]); n_new += secSize; n_s++; } TempSection.SetSectionDescription(src[nc][0].GetSectionDescription() + ", concatenated"); Channel TempChannel(TempSection); TempChannel.SetChannelName(src[nc].GetChannelName()); TempChannel.SetYUnits(src[nc].GetYUnits()); Concatenated.InsertChannel(TempChannel, nc); } // Recording Concatenated(TempChannel); Concatenated.CopyAttributes(src); return Concatenated; } Recording stfio::multiply(const Recording& src, const std::vector& sections, std::size_t channel, double factor) { Channel TempChannel(sections.size(), src[channel][sections[0]].size()); std::size_t n = 0; for (c_st_it cit = sections.begin(); cit != sections.end(); cit++) { // Multiply the valarray in Data: Section TempSection(stfio::vec_scal_mul(src[channel][*cit].get(),factor)); TempSection.SetXScale(src[channel][*cit].GetXScale()); TempSection.SetSectionDescription( src[channel][*cit].GetSectionDescription()+ ", multiplied" ); try { TempChannel.InsertSection(TempSection, n); } catch (const std::out_of_range e) { throw e; } n++; } if (TempChannel.size()>0) { Recording Multiplied(TempChannel); Multiplied.CopyAttributes(src); Multiplied[0].SetYUnits( src.at( channel ).GetYUnits() ); return Multiplied; } else { throw std::runtime_error("Channel empty in stfio::multiply"); } } stimfit-0.16.7/src/libstfio/biosig/0000775000175000017500000000000014764352501012714 5stimfit-0.16.7/src/libstfio/biosig/biosiglib.cpp0000664000175000017500000004315014752207205015303 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Copyright 2012,2013,2017 Alois Schloegl, IST Austria #include #include "../stfio.h" #if defined(WITH_BIOSIGLITE) #include "../../biosig/biosig4c++/biosig2.h" #else #include #endif #if (BIOSIG_VERSION < 10902) #error libbiosig v1.9.2 or later is required #endif #define DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR /* these are internal biosig functions, defined in biosig-dev.h which is not always available */ extern "C" size_t ifwrite(void* buf, size_t size, size_t nmemb, HDRTYPE* hdr); extern "C" uint32_t lcm(uint32_t A, uint32_t B); #if !defined(__MINGW32__) && !defined(_MSC_VER) #if defined (__APPLE__) #include #else #include #endif #endif #include "./biosiglib.h" stfio::filetype stfio_file_type(HDRTYPE* hdr) { switch (biosig_get_filetype(hdr)) { case ABF2: return stfio::abf; case ABF: return stfio::abf; case ATF: return stfio::atf; case CFS: return stfio::cfs; case HEKA: return stfio::heka; case HDF: return stfio::hdf5; case AXG: return stfio::axg; case IBW: return stfio::igor; case SMR: return stfio::son; default: return stfio::none; } } #if defined(WITH_BIOSIG) bool stfio::check_biosig_version(int a, int b, int c) { return (BIOSIG_VERSION >= 10000*a + 100*b + c); } #endif stfio::filetype stfio::importBiosigFile(const std::string &fName, Recording &ReturnData, ProgressInfo& progDlg) { std::string errorMsg("Exception while calling std::importBSFile():\n"); std::string yunits; stfio::filetype type; // ===================================================================================================================== // // importBiosig opens file with libbiosig // - performs an automated identification of the file format // - and decides whether the data is imported through importBiosig (currently CFS, HEKA, ABF1, GDF, and others) // - or handed back to other import*File functions (currently ABF2, AXG, HDF5) // // ===================================================================================================================== #ifdef __LIBBIOSIG2_H__ HDRTYPE* hdr = sopen( fName.c_str(), "r", NULL ); if (hdr==NULL) { ReturnData.resize(0); return stfio::none; } type = stfio_file_type(hdr); if (biosig_check_error(hdr)) { ReturnData.resize(0); destructHDR(hdr); return type; } enum FileFormat biosig_filetype=biosig_get_filetype(hdr); if ( (biosig_filetype==ATF && get_biosig_version() < 0x030001) \ || (biosig_filetype==ABF2 && get_biosig_version() < 0x030002) \ || biosig_filetype==HDF ) { // ATF, ABF2 HDF5 support should be handled by importATF, and importABF, and importHDF5 not importBiosig // with libbiosig v3.0.1 (release 2.3.1) and later, ATF, ABF should be handled by Biosig // with libbiosig v3.0.2 (release 2.5.1) and later, ABF2 should be handled by Biosig ReturnData.resize(0); destructHDR(hdr); return type; } // ensure the event table is in chronological order sort_eventtable(hdr); // allocate local memory for intermediate results; const int strSize=100; char str[strSize]; /* count sections and generate list of indices indicating start and end of sweeps */ int numberOfChannels = biosig_get_number_of_channels(hdr); double fs = biosig_get_eventtable_samplerate(hdr); size_t numberOfEvents = biosig_get_number_of_events(hdr); size_t nsections = numberOfEvents + 1; // worst case, resize when actual number becomes known ReturnData.InitSectionMarkerList(nsections); std::vector SegIndexList(nsections+1); SegIndexList[0] = 0; SegIndexList[nsections] = biosig_get_number_of_samples(hdr); std::string annotationTableDesc = std::string(); size_t SPR = biosig_get_number_of_samples(hdr); size_t n = 0; for (size_t k=0; k < numberOfEvents; k++) { uint32_t pos; uint16_t typ; uint32_t dur; uint16_t chn; const char *desc; /* gdftype timestamp; */ biosig_get_nth_event(hdr, k, &typ, &pos, &chn, &dur, NULL, &desc); if ( (pos <= 1) || (pos > SPR) ) continue; // ignore event, because outside of valid range else if (typ == 0x7ffe) { if (pos != SegIndexList[n]) SegIndexList[++n] = pos; } else if (typ < 256) { snprintf(str, sizeof(str), "%f s:\t%s\n", pos/fs, desc); annotationTableDesc += std::string( str ); size_t currentSectionNumber = (pos < SegIndexList[n]) ? n : (n+1); ReturnData.SetSectionType(currentSectionNumber-1, typ); // TODO: Description of EvenTypes // ReturnData.SetEventDescription( currentSectionNumber-1, desc); } } nsections = n + 1; SegIndexList[nsections] = SPR; SegIndexList.resize(nsections+1); /************************************************************************* rescale data to mV and pA *************************************************************************/ for (int ch=0; ch < numberOfChannels; ++ch) { CHANNEL_TYPE *hc = biosig_get_channel(hdr, ch); switch (biosig_channel_get_physdimcode(hc) & 0xffe0) { case 4256: // Volt //biosig_channel_scale_to_unit(hc, "mV"); biosig_channel_change_scale_to_physdimcode(hc, 4274); break; case 4160: // Ampere //biosig_channel_scale_to_unit(hc, "pA"); biosig_channel_change_scale_to_physdimcode(hc, 4181); break; } } /************************************************************************* read bulk data *************************************************************************/ biosig_data_type *data = biosig_get_data(hdr, 0); #ifdef _STFDEBUG std::cout << "Number of events: " << numberOfEvents << std::endl; /*int res = */ hdr2ascii(hdr, stdout, 4); #endif for (int NS=0; NS < numberOfChannels; ) { CHANNEL_TYPE *hc = biosig_get_channel(hdr, NS); Channel TempChannel(nsections); TempChannel.SetChannelName(biosig_channel_get_label(hc)); TempChannel.SetYUnits(biosig_channel_get_physdim(hc)); for (size_t ns=1; ns<=nsections; ns++) { size_t SPS = SegIndexList[ns]-SegIndexList[ns-1]; // length of segment, samples per segment int progbar = int(100.0 * (1.0 * ns / nsections + NS) / numberOfChannels); std::ostringstream progStr; progStr << "Reading channel #" << NS + 1 << " of " << numberOfChannels << ", Section #" << ns << " of " << nsections; progDlg.Update(progbar, progStr.str()); Section TempSection(SPS, ""); std::copy(&(data[NS*SPR + SegIndexList[ns-1]]), &(data[NS*SPR + SegIndexList[ns]]), TempSection.get_w().begin() ); try { TempChannel.InsertSection(TempSection, ns-1); } catch (...) { ReturnData.resize(0); destructHDR(hdr); return type; } } // end for sections try { if ((int)ReturnData.size() < numberOfChannels) ReturnData.resize(numberOfChannels); ReturnData.InsertChannel(TempChannel, NS++); } catch (...) { ReturnData.resize(0); destructHDR(hdr); return type; } } // end for channels ReturnData.SetComment ( biosig_get_recording_id(hdr) ); snprintf(str, sizeof(str), "v%i.%i.%i (compiled on %s %s)",BIOSIG_VERSION_MAJOR,BIOSIG_VERSION_MINOR,BIOSIG_PATCHLEVEL,__DATE__,__TIME__); std::string Desc = std::string("importBiosig with libbiosig ")+std::string(str) + " "; const char* tmpstr; if ((tmpstr=biosig_get_technician(hdr))) Desc += std::string ("\nTechnician:\t") + std::string (tmpstr) + " "; Desc += std::string( "\nCreated with: "); if ((tmpstr=biosig_get_manufacturer_name(hdr))) Desc += std::string( tmpstr ) + " "; if ((tmpstr=biosig_get_manufacturer_model(hdr))) Desc += std::string( tmpstr ) + " "; if ((tmpstr=biosig_get_manufacturer_version(hdr))) Desc += std::string( tmpstr ) + " "; if ((tmpstr=biosig_get_manufacturer_serial_number(hdr))) Desc += std::string( tmpstr ) + " "; Desc += std::string ("\nUser specified Annotations:\n")+annotationTableDesc; ReturnData.SetFileDescription(Desc); tmpstr = biosig_get_application_specific_information(hdr); if (tmpstr != NULL) /* MSVC2008 can not properly handle std::string( (char*)NULL ) */ ReturnData.SetGlobalSectionDescription(tmpstr); ReturnData.SetXScale(1000.0/biosig_get_samplerate(hdr)); ReturnData.SetXUnits("ms"); ReturnData.SetScaling("biosig scaling factor"); /************************************************************************* Date and time conversion *************************************************************************/ struct tm T; biosig_get_startdatetime(hdr, &T); ReturnData.SetDateTime(T); destructHDR(hdr); #endif //ifdef __LIBBIOSIG2_H__ return stfio::biosig; } // ===================================================================================================================== // // Save file with libbiosig into GDF format // // ===================================================================================================================== bool stfio::exportBiosigFile(const std::string& fName, const Recording& Data, stfio::ProgressInfo& progDlg) { /* converts the internal data structure to libbiosig's internal structure and saves the file as gdf file. The data in converted into the raw data format, and not into the common data matrix. */ #ifdef __LIBBIOSIG2_H__ size_t numberOfChannels = Data.size(); HDRTYPE* hdr = constructHDR(numberOfChannels, 0); /* Initialize all header parameters */ biosig_set_filetype(hdr, GDF); biosig_set_startdatetime(hdr, Data.GetDateTime()); const char *xunits = Data.GetXUnits().c_str(); uint16_t pdc = PhysDimCode(xunits); if ((pdc & 0xffe0) != PhysDimCode("s")) { fprintf(stderr,"Stimfit exportBiosigFile: xunits [%s] has not proper units, assume [ms]\n",Data.GetXUnits().c_str()); pdc = PhysDimCode("ms"); } double fs = 1.0/(PhysDimScale(pdc) * Data.GetXScale()); biosig_set_samplerate(hdr, fs); biosig_reset_flag(hdr, BIOSIG_FLAG_COMPRESSION | BIOSIG_FLAG_UCAL | BIOSIG_FLAG_OVERFLOWDETECTION | BIOSIG_FLAG_ROW_BASED_CHANNELS ); size_t k, m, numberOfEvents=0; size_t NRec=0; // corresponds to hdr->NRec size_t SPR=1; // corresponds to hdr->SPR size_t chSPR=0; // corresponds to hc->SPR /* Initialize all channel parameters */ #ifndef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR size_t *chanSPR = (size_t*)malloc(numberOfChannels*sizeof(size_t)); #endif for (k = 0; k < numberOfChannels; ++k) { CHANNEL_TYPE *hc = biosig_get_channel(hdr, k); biosig_channel_set_datatype_to_double(hc); biosig_channel_set_scaling(hc, 1e9, -1e9, 1e9, -1e9); biosig_channel_set_label(hc, Data[k].GetChannelName().c_str()); biosig_channel_set_physdim(hc, Data[k].GetYUnits().c_str()); biosig_channel_set_filter(hc, NAN, NAN, NAN); biosig_channel_set_timing_offset(hc, 0.0); biosig_channel_set_impedance(hc, NAN); chSPR = SPR; // each segment gets one marker, roughly numberOfEvents += Data[k].size(); size_t m,len = 0; for (len=0, m = 0; m < Data[k].size(); ++m) { unsigned div = lround(Data[k][m].GetXScale()/Data.GetXScale()); chSPR = lcm(chSPR,div); // sampling interval of m-th segment in k-th channel len += div*Data[k][m].size(); } SPR = lcm(SPR, chSPR); /* hc->SPR (i.e. chSPR) is 'abused' to store final hdr->SPR/hc->SPR, this is corrected in the loop below its a hack to avoid the need for another malloc(). */ #ifdef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR biosig_channel_set_samples_per_record(hc, chSPR); #else chanSPR[k]=chSPR; #endif if (k==0) { NRec = len; } else if ((size_t)NRec != len) { destructHDR(hdr); throw std::runtime_error("File can't be exported:\n" "No data or traces have different sizes" ); return false; } } biosig_set_number_of_samples(hdr, NRec, SPR); size_t bpb = 0; for (k = 0; k < numberOfChannels; ++k) { CHANNEL_TYPE *hc = biosig_get_channel(hdr, k); // the 'abuse' of hc->SPR described above is corrected #ifdef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR size_t spr = biosig_channel_get_samples_per_record(hc); spr = SPR / spr; biosig_channel_set_samples_per_record(hc, spr); #else size_t spr = SPR/chanSPR[k]; chanSPR[k] = spr; #endif bpb += spr * 8; /* its always double */ } /*** build Event table for storing segment information pre-allocate memory for even table ***/ numberOfEvents *= 2; // about two events per segment biosig_set_number_of_events(hdr, numberOfEvents); /* check whether all segments have same size */ { char flag = (numberOfChannels > 0); size_t m, POS, pos; for (k=0; k < numberOfChannels; ++k) { pos = Data[k].size(); if (k==0) POS = pos; else flag &= (POS == pos); } for (m=0; flag && (m < Data[(size_t)0].size()); ++m) { for (k=0; k < biosig_get_number_of_channels(hdr); ++k) { pos = Data[k][m].size() * lround(Data[k][m].GetXScale()/Data.GetXScale()); if (k==0) POS = pos; else flag &= (POS == pos); } } if (!flag) { destructHDR(hdr); throw std::runtime_error( "File can't be exported:\n" "Traces have different sizes or no channels found" ); return false; } } size_t N=0; k=0; size_t pos = 0; for (m=0; m < (Data[k].size()); ++m) { if (pos > 0) { uint16_t typ=0x7ffe; uint32_t pos32=pos; uint16_t chn=0; uint32_t dur=0; // set break marker biosig_set_nth_event(hdr, N++, &typ, &pos32, &chn, &dur, NULL, NULL); /* // set annotation const char *Desc = Data[k][m].GetSectionDescription().c_str(); if (Desc != NULL && strlen(Desc)>0) biosig_set_nth_event(hdr, N++, NULL, &pos32, &chn, &dur, NULL, Desc); // TODO */ } pos += Data[k][m].size() * lround(Data[k][m].GetXScale()/Data.GetXScale()); } biosig_set_number_of_events(hdr, N); biosig_set_eventtable_samplerate(hdr, fs); sort_eventtable(hdr); /* convert data into GDF rawdata from */ uint8_t *rawdata = (uint8_t*)malloc(bpb * NRec); size_t bi=0; for (k=0; k < numberOfChannels; ++k) { CHANNEL_TYPE *hc = biosig_get_channel(hdr, k); #ifdef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR size_t chSPR = biosig_channel_get_samples_per_record(hc); #else size_t chSPR = chanSPR[k]; #endif size_t m,n,len=0; for (m=0; m < Data[k].size(); ++m) { size_t div = lround(Data[k][m].GetXScale()/Data.GetXScale()); size_t div2 = SPR/div; // TODO: avoid using hdr->SPR // fprintf(stdout,"k,m,div,div2: %i,%i,%i,%i\n",(int)k,(int)m,(int)div,(int)div2); // for (n=0; n < Data[k][m].size(); ++n) { uint64_t val; double d = Data[k][m][n]; #if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(__APPLE__) val = htole64(*(uint64_t*)&d); #else val = *(uint64_t*)&d; #endif size_t p, spr = (len + n*div) / SPR; for (p=0; p < div2; p++) *(uint64_t*)(rawdata + bi + bpb * spr + p*8) = val; } len += div*Data[k][m].size(); } bi += chSPR*8; } #ifndef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR if (chanSPR) free(chanSPR); #endif /****************************** write to file *******************************/ std::string errorMsg("Exception while calling std::exportBiosigFile():\n"); hdr = sopen( fName.c_str(), "w", hdr ); if (serror2(hdr)) { errorMsg += biosig_get_errormsg(hdr); destructHDR(hdr); throw std::runtime_error(errorMsg.c_str()); return false; } ifwrite(rawdata, bpb, NRec, hdr); sclose(hdr); destructHDR(hdr); free(rawdata); #endif return true; } stimfit-0.16.7/src/libstfio/biosig/biosiglib.h0000664000175000017500000000533214750344764014762 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file biosiglib.h * \author Christoph Schmidt-Hieber * \date 2011-02-18 * \brief Use biosig to read files */ #ifndef _BIOSIGLIB_H #define _BIOSIGLIB_H #include "../stfio.h" namespace stfio { #if defined(WITH_BIOSIG) //! return version of libbiosig e.g. 10403 correspond to version 1.4.3 StfioDll bool check_biosig_version(int a, int b, int c); #endif //! Open an BIOSIG file and store its contents to a Recording object. /*! \param fName The full path to the file to be opened. * \param ReturnData On entry, an empty Recording object. On exit, * the data stored in \e fName. * \param progress True if the progress dialog should be updated. * * Return value: in case of success stfio::biosig is returned, * if the file format is recognized, the corresponding filetype is returned, * if the filetype is not recognized or not supported. stfio::none is returned. */ stfio::filetype importBiosigFile(const std::string& fName, Recording& ReturnData, ProgressInfo& progDlg); //! Export a Recording to a GDF file using biosig. /*! \param fName Full path to the file to be written. * \param WData The data to be exported. */ StfioDll bool exportBiosigFile(const std::string& fName, const Recording& WData, ProgressInfo& progDlg); } #endif stimfit-0.16.7/src/libstfio/channel.cpp0000775000175000017500000000420714750344764013511 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "./stfio.h" #include "./channel.h" Channel::Channel(void) : name("\0"), yunits( "\0" ), SectionArray(0) {} Channel::Channel(const Section& c_Section) : name("\0"), yunits( "\0" ), SectionArray(1, c_Section) {} Channel::Channel(const std::deque
& SectionList) : name("\0"), yunits( "\0" ), SectionArray(SectionList) {} Channel::Channel(std::size_t c_n_sections, std::size_t section_size) : name("\0"), yunits( "\0" ), SectionArray(c_n_sections, Section(section_size)) {} Channel::~Channel(void) {} void Channel::InsertSection(const Section& c_Section, std::size_t pos) { try { if (SectionArray.at(pos).size() != c_Section.size()) { SectionArray.at(pos).resize(c_Section.size()); } SectionArray.at(pos) = c_Section; } catch (...) { throw; } } const Section& Channel::at(std::size_t at_) const { try { return SectionArray.at(at_); } catch (...) { // Forward all exceptions, can't deal with them here: throw; } } Section& Channel::at(std::size_t at_) { try { return SectionArray.at(at_); } catch (...) { // Forward all exceptions, can't deal with them here: throw; } } void Channel::resize(std::size_t newSize) { SectionArray.resize(newSize); } void Channel::reserve(std::size_t resSize) { /* SectionArray.reserve(resSize); */ } stimfit-0.16.7/src/libstfio/abf/0000775000175000017500000000000014764352501012170 5stimfit-0.16.7/src/libstfio/abf/axon2/0000775000175000017500000000000014764352501013217 5stimfit-0.16.7/src/libstfio/abf/axon2/ProtocolReaderABF2.hpp0000664000175000017500000000412314750344764017176 //*********************************************************************************************** // // Copyright (c) 2005 Molecular Devices Corporation. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** #ifndef INC_ABF2PROTOCOLREADER_H #define INC_ABF2PROTOCOLREADER_H #include "abf2headr.h" #include "SimpleStringCache.hpp" #include "ProtocolStructs.h" // Struct definitions for actual file contents #include "../axon/AxAbfFio32/AxAbffio32.h" #include "../axon/AxAbfFio32/filedesc.hpp" #if (__cplusplus < 201103) #include #else #include #endif //=============================================================================================== class CABF2ProtocolReader { private: ABF2_FileInfo m_FileInfo; CSimpleStringCache m_Strings; // The string writing object. CFileDescriptor* m_pFI; int nFile; #if (__cplusplus < 201103) boost::shared_ptr m_pFH; #else std::shared_ptr m_pFH; #endif BOOL ReadFileInfo(); BOOL ReadProtocolInfo(); BOOL ReadADCInfo(); BOOL ReadDACInfo(); BOOL ReadEpochs(); BOOL ReadStats(); BOOL ReadUserList(); BOOL ReadMathInfo(); BOOL GetString( UINT uIndex, LPSTR pszText, UINT uBufSize ); public: CABF2ProtocolReader( ); virtual ~CABF2ProtocolReader(); virtual BOOL Open( LPCTSTR fName ); virtual BOOL Close( ); static BOOL CanOpen( const void *pFirstBlock, UINT uBytes ); virtual BOOL Read( int* pnError); virtual const ABF2_FileInfo *GetFileInfo() const { return &m_FileInfo; } virtual const ABF2FileHeader* GetFileHeader() const { return m_pFH.get(); } virtual ABF2FileHeader* GetFileHeaderW() { return m_pFH.get(); } virtual int GetFileNumber() const { return nFile; } // virtual BOOL ValidateCRC(); }; #endif // INC_ABF2PROTOCOLREADER_H stimfit-0.16.7/src/libstfio/abf/axon2/ProtocolReaderABF2.cpp0000664000175000017500000010543014750344764017174 //*********************************************************************************************** // // Copyright (c) 2005 Molecular Devices. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // // MODULE: ProtocolReader.CPP // PURPOSE: ReadsABF 2 protocols from an ABF file. // #include "../axon/Common/wincpp.hpp" #include "../axon/Common/axodefn.h" #include "ProtocolReaderABF2.hpp" #include "../axon/AxAbfFio32/abfutil.h" #include "../axon/AxAbfFio32/abffiles.h" #include #if !defined(_WINDOWS) || defined(__MINGW32__) || defined(__STF__) #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif extern BOOL GetNewFileDescriptor(CFileDescriptor **ppFI, int *pnFile, int *pnError); extern BOOL GetFileDescriptor(CFileDescriptor **ppFI, int nFile, int *pnError); extern void ReleaseFileDescriptor(int nFile); static BOOL ErrorReturn(int *pnError, int nErrorNum) { if (pnError) *pnError = nErrorNum; return FALSE; } //=============================================================================================== //=============================================================================================== // FUNCTION: FlattenGearShift // PURPOSE: Converts a header with gear shift enabled to the equivalent with the gear shift flattened. // static BOOL FlattenGearShift(ABF2FileHeader *pFH) { ASSERT( pFH ); if( pFH->nOperationMode != ABF_WAVEFORMFILE ) return FALSE; if( pFH->uFileCompressionRatio == 1 ) return FALSE; return TRUE; } #if 0 //=============================================================================================== // FUNCTION: RemoveExtraChannels // PURPOSE: Removes "extra" channels when P/N is enabled and files are opened as protocols. // NOTES: This function allows Clampex 10 data files (with P/N enabled) to be opened as a protocol. // These files have an extra channel that stores the raw data (in addition to the corrected data). // Therefore there is some tweaking and scaling of header parameters. // static BOOL RemoveExtraChannels( ABF2FileHeader *pFH, UINT uFlags ) { WPTRASSERT( pFH ); // Must be episodic stimulation mode. if( pFH->nOperationMode != ABF_WAVEFORMFILE ) return FALSE; // P/N must be enabled. if( !ABF2H_IsPNEnabled( pFH ) ) return FALSE; // This fix only applies to files with one ADC channel and one P/N channel. if( pFH->nADCNumChannels != 2 ) return FALSE; // Must be a data file (i.e. not a protocol). if( pFH->lActualAcqLength == 0 ) return FALSE; bool bFudge = false; if( uFlags & ABF_PARAMFILE ) bFudge = true; else { ABFLONG lActualSamplesPerEpisode = pFH->lActualAcqLength / pFH->lActualEpisodes; if( lActualSamplesPerEpisode != pFH->lNumSamplesPerEpisode ) bFudge = true; } if( !bFudge ) return FALSE; int nIndex = ABF_UNUSED_CHANNEL; for( UINT i=0; inADCSamplingSeq[i] == ABF_UNUSED_CHANNEL ) { nIndex = i - 1; // i.e. the previous channel is the last valid channel. break; } } if( nIndex == ABF_UNUSED_CHANNEL ) return FALSE; // There are extra channels to be stripped. short nOldChans = pFH->nADCNumChannels; short nNewChans = nOldChans - 1; pFH->nADCNumChannels = nNewChans; pFH->lNumSamplesPerEpisode = MulDiv( pFH->lNumSamplesPerEpisode, nNewChans, nOldChans ); // Adjust the statistics search regions. pFH->lStatsBaselineStart = MulDiv( pFH->lStatsBaselineStart, nNewChans, nOldChans ); pFH->lStatsBaselineEnd = MulDiv( pFH->lStatsBaselineEnd, nNewChans, nOldChans ); for( UINT i=0; ilStatsStart[i] = MulDiv( pFH->lStatsStart[i], nNewChans, nOldChans ); pFH->lStatsEnd[i] = MulDiv( pFH->lStatsEnd[i], nNewChans, nOldChans ); } return TRUE; } #endif //=============================================================================================== // CABF2ProtocolReader implementation // // NOTE: Any changes made here will require complementary changes to ProtocolWriter.cpp //=============================================================================================== // Constructor. // CABF2ProtocolReader::CABF2ProtocolReader( ) : m_pFI( NULL ) { m_pFH.reset( new ABF2FileHeader ); ABF2H_Initialize( m_pFH.get() ); MEMBERASSERT(); } //=============================================================================================== // Destructor. // CABF2ProtocolReader::~CABF2ProtocolReader() { if (m_pFI != NULL ) { Close(); } MEMBERASSERT(); } //=============================================================================================== // FUNCTION: Read // PURPOSE: Reads the complete protocol from the data file. // BOOL CABF2ProtocolReader::Read( int* pnError ) { MEMBERASSERT(); if (m_pFI == NULL) return FALSE; BOOL bOK = TRUE; bOK &= m_pFI->Seek( 0L, FILE_BEGIN); if( !bOK ) return FALSE; bOK &= m_pFI->Read( &m_FileInfo, sizeof( m_FileInfo ) ); if( m_FileInfo.StringsSection.uBlockIndex ) { // Read the protocol strings into the cache. UINT uSeekPos = m_FileInfo.StringsSection.uBlockIndex * ABF_BLOCKSIZE; if( !m_Strings.Read( m_pFI->GetFileHandle(), uSeekPos ) ) return FALSE; //SetLastError( ABF_ENOSTRINGS ); } bOK &= ReadFileInfo(); bOK &= ReadProtocolInfo(); bOK &= ReadADCInfo(); bOK &= ReadDACInfo(); bOK &= ReadEpochs(); bOK &= ReadStats(); bOK &= ReadUserList(); bOK &= ReadMathInfo(); // modified from ABF_ReadOpen int nError = 0; // Check that the data file actually contains data. if ((m_pFH->lActualAcqLength <= 0) || (m_pFH->nADCNumChannels <= 0)) { nError = ABF_EBADPARAMETERS; Close(); nFile = (int)ABF_INVALID_HANDLE; ERRORRETURN(pnError, nError); } // Set header variable for the number of episodes in the file. if( m_pFH->nOperationMode == ABF2_GAPFREEFILE ) { double fdiv = (double)m_pFH->lActualAcqLength / m_pFH->lNumSamplesPerEpisode; DWORD dwMaxEpi = ceil(fdiv); #ifdef _STFDEBUG std::cout << "Total number of samples " << m_pFH->lActualAcqLength << std::endl; #endif m_pFH->lActualEpisodes = dwMaxEpi; } m_pFI->SetAcquiredEpisodes(m_pFH->lActualEpisodes); m_pFI->SetAcquiredSamples(m_pFH->lActualAcqLength); // CSH RemoveExtraChannels( m_pFH, fFlags ); FlattenGearShift( m_pFH.get() ); return bOK; } //=============================================================================================== // FUNCTION: GetString // PURPOSE: Read a single ProtocolString into the buffer. // BOOL CABF2ProtocolReader::GetString( UINT uIndex, LPSTR pszText, UINT uBufSize ) { MEMBERASSERT(); // LPSZASSERT( pszText ); WARRAYASSERT( pszText, uBufSize ); ABFU_SetABFString( pszText, "", uBufSize ); // Just return an empty string if the index is invalid. if( uIndex == 0 ) return TRUE; // or if we do not have the requested string available. if( uIndex > m_Strings.GetNumStrings() ) return TRUE; LPCSTR pszString = m_Strings.Get( uIndex - 1 ); if( pszString ) { UINT uLen = strlen( pszString ); if( uLen > uBufSize ) return FALSE; ABFU_SetABFString( pszText, pszString, uLen ); return TRUE; } return FALSE; } #define MAJOR( n ) HIBYTE( HIWORD( (n) ) ) #define MINOR( n ) LOBYTE( HIWORD( (n) ) ) #define BUGFIX( n ) HIBYTE( LOWORD( (n) ) ) #define BUILD( n ) LOBYTE( LOWORD( (n) ) ) //=============================================================================================== // FUNCTION: ReadFileInfo // PURPOSE: Reads the file info from the data file. // BOOL CABF2ProtocolReader::ReadFileInfo() { MEMBERASSERT(); BOOL bOK = TRUE; short nMajor = MAJOR( m_FileInfo.uFileVersionNumber ); short nMinor = MINOR( m_FileInfo.uFileVersionNumber ); m_pFH->fFileVersionNumber = nMajor + nMinor/100.0F; m_pFH->fHeaderVersionNumber = ABF_CURRENTVERSION; m_pFH->nFileType = m_FileInfo.nFileType; m_pFH->nDataFormat = m_FileInfo.nDataFormat; m_pFH->nSimultaneousScan = m_FileInfo.nSimultaneousScan; m_pFH->FileGUID = m_FileInfo.FileGUID; m_pFH->ulFileCRC = m_FileInfo.uFileCRC; m_pFH->nCRCEnable = m_FileInfo.nCRCEnable; m_pFH->nCreatorMajorVersion = MAJOR ( m_FileInfo.uCreatorVersion ); m_pFH->nCreatorMinorVersion = MINOR ( m_FileInfo.uCreatorVersion ); m_pFH->nCreatorBugfixVersion = BUGFIX( m_FileInfo.uCreatorVersion ); m_pFH->nCreatorBuildVersion = BUILD ( m_FileInfo.uCreatorVersion ); bOK &= GetString( m_FileInfo.uCreatorNameIndex, m_pFH->sCreatorInfo, ELEMENTS_IN( m_pFH->sCreatorInfo ) ); m_pFH->nModifierMajorVersion = MAJOR ( m_FileInfo.uModifierVersion ); m_pFH->nModifierMinorVersion = MINOR ( m_FileInfo.uModifierVersion ); m_pFH->nModifierBugfixVersion = BUGFIX( m_FileInfo.uModifierVersion ); m_pFH->nModifierBuildVersion = BUILD ( m_FileInfo.uModifierVersion ); bOK &= GetString( m_FileInfo.uModifierNameIndex, m_pFH->sModifierInfo, ELEMENTS_IN( m_pFH->sModifierInfo ) ); m_pFH->nNumPointsIgnored = 0; m_pFH->uFileStartDate = m_FileInfo.uFileStartDate; m_pFH->uFileStartTimeMS = m_FileInfo.uFileStartTimeMS; m_pFH->lStopwatchTime = m_FileInfo.uStopwatchTime; m_pFH->lActualEpisodes = m_FileInfo.uActualEpisodes; m_pFH->lActualAcqLength = m_FileInfo.DataSection.GetNumEntries(); m_pFH->lDataSectionPtr = m_FileInfo.DataSection.uBlockIndex; m_pFH->lScopeConfigPtr = m_FileInfo.ScopeSection.uBlockIndex; m_pFH->lNumScopes = m_FileInfo.ScopeSection.GetNumEntries(); m_pFH->lStatisticsConfigPtr = m_FileInfo.StatsSection.uBlockIndex; m_pFH->lTagSectionPtr = m_FileInfo.TagSection.uBlockIndex; m_pFH->lNumTagEntries = m_FileInfo.TagSection.GetNumEntries(); m_pFH->lDeltaArrayPtr = m_FileInfo.DeltaSection.uBlockIndex; m_pFH->lNumDeltas = m_FileInfo.DeltaSection.GetNumEntries(); m_pFH->lVoiceTagPtr = m_FileInfo.VoiceTagSection.uBlockIndex; m_pFH->lVoiceTagEntries = m_FileInfo.VoiceTagSection.GetNumEntries(); m_pFH->lSynchArrayPtr = m_FileInfo.SynchArraySection.uBlockIndex; m_pFH->lSynchArraySize = m_FileInfo.SynchArraySection.GetNumEntries(); m_pFH->lAnnotationSectionPtr = m_FileInfo.AnnotationSection.uBlockIndex; m_pFH->lNumAnnotations = m_FileInfo.AnnotationSection.GetNumEntries(); bOK &= GetString( m_FileInfo.uProtocolPathIndex, m_pFH->sProtocolPath, ELEMENTS_IN( m_pFH->sProtocolPath ) ); return bOK; } //=============================================================================================== // FUNCTION: ReadProtocolInfo // PURPOSE: Reads the protocol info from the data file. // BOOL CABF2ProtocolReader::ReadProtocolInfo() { MEMBERASSERT(); BOOL bOK = TRUE; ABF_ProtocolInfo Protocol; bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.ProtocolSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; bOK &= m_pFI->Read( &Protocol, sizeof( Protocol ) ); ASSERT( bOK ); m_pFH->nADCNumChannels = short( m_FileInfo.ADCSection.llNumEntries ); m_pFH->nOperationMode = Protocol.nOperationMode; m_pFH->fADCSequenceInterval = Protocol.fADCSequenceInterval; m_pFH->uFileCompressionRatio = max( Protocol.uFileCompressionRatio, 1 ); m_pFH->bEnableFileCompression = Protocol.bEnableFileCompression; m_pFH->fSynchTimeUnit = Protocol.fSynchTimeUnit; m_pFH->fSecondsPerRun = Protocol.fSecondsPerRun; m_pFH->lNumSamplesPerEpisode = Protocol.lNumSamplesPerEpisode; m_pFH->lPreTriggerSamples = Protocol.lPreTriggerSamples; m_pFH->lEpisodesPerRun = Protocol.lEpisodesPerRun; m_pFH->lRunsPerTrial = Protocol.lRunsPerTrial; m_pFH->lNumberOfTrials = Protocol.lNumberOfTrials; m_pFH->nAveragingMode = Protocol.nAveragingMode; m_pFH->nUndoRunCount = Protocol.nUndoRunCount; m_pFH->nFirstEpisodeInRun = Protocol.nFirstEpisodeInRun; m_pFH->fTriggerThreshold = Protocol.fTriggerThreshold; m_pFH->nTriggerSource = Protocol.nTriggerSource; m_pFH->nTriggerAction = Protocol.nTriggerAction; m_pFH->nTriggerPolarity = Protocol.nTriggerPolarity; m_pFH->fScopeOutputInterval = Protocol.fScopeOutputInterval; m_pFH->fEpisodeStartToStart = Protocol.fEpisodeStartToStart; m_pFH->fRunStartToStart = Protocol.fRunStartToStart; m_pFH->lAverageCount = Protocol.lAverageCount; m_pFH->fTrialStartToStart = Protocol.fTrialStartToStart; m_pFH->nAutoTriggerStrategy = Protocol.nAutoTriggerStrategy; m_pFH->fFirstRunDelayS = Protocol.fFirstRunDelayS; m_pFH->nChannelStatsStrategy = Protocol.nChannelStatsStrategy; m_pFH->lSamplesPerTrace = Protocol.lSamplesPerTrace; m_pFH->lStartDisplayNum = Protocol.lStartDisplayNum; m_pFH->lFinishDisplayNum = Protocol.lFinishDisplayNum; m_pFH->nShowPNRawData = Protocol.nShowPNRawData; m_pFH->fStatisticsPeriod = Protocol.fStatisticsPeriod; m_pFH->lStatisticsMeasurements = Protocol.lStatisticsMeasurements; m_pFH->nStatisticsSaveStrategy = Protocol.nStatisticsSaveStrategy; m_pFH->fADCRange = Protocol.fADCRange; m_pFH->fDACRange = Protocol.fDACRange; m_pFH->lADCResolution = Protocol.lADCResolution; m_pFH->lDACResolution = Protocol.lDACResolution; m_pFH->nDigitizerADCs = Protocol.nDigitizerADCs; m_pFH->nDigitizerDACs = Protocol.nDigitizerDACs; m_pFH->nDigitizerTotalDigitalOuts = Protocol.nDigitizerTotalDigitalOuts; m_pFH->nDigitizerSynchDigitalOuts = Protocol.nDigitizerSynchDigitalOuts; m_pFH->nDigitizerType = Protocol.nDigitizerType; m_pFH->nExperimentType = Protocol.nExperimentType; m_pFH->nManualInfoStrategy = Protocol.nManualInfoStrategy; m_pFH->fCellID1 = Protocol.fCellID[0]; m_pFH->fCellID2 = Protocol.fCellID[1]; m_pFH->fCellID3 = Protocol.fCellID[2]; m_pFH->nCommentsEnable = Protocol.nCommentsEnable; m_pFH->nAutoAnalyseEnable = Protocol.nAutoAnalyseEnable; m_pFH->nSignalType = Protocol.nSignalType; m_pFH->nDigitalEnable = Protocol.nDigitalEnable; m_pFH->nActiveDACChannel = Protocol.nActiveDACChannel; m_pFH->nDigitalHolding = Protocol.nDigitalHolding; m_pFH->nDigitalInterEpisode = Protocol.nDigitalInterEpisode; m_pFH->nDigitalDACChannel = Protocol.nDigitalDACChannel; m_pFH->nDigitalTrainActiveLogic = Protocol.nDigitalTrainActiveLogic; m_pFH->nStatsEnable = Protocol.nStatsEnable; m_pFH->nLevelHysteresis = Protocol.nLevelHysteresis; m_pFH->lTimeHysteresis = Protocol.lTimeHysteresis; m_pFH->nAllowExternalTags = Protocol.nAllowExternalTags; m_pFH->nAverageAlgorithm = Protocol.nAverageAlgorithm; m_pFH->fAverageWeighting = Protocol.fAverageWeighting; m_pFH->nUndoPromptStrategy = Protocol.nUndoPromptStrategy; m_pFH->nTrialTriggerSource = Protocol.nTrialTriggerSource; m_pFH->nStatisticsDisplayStrategy = Protocol.nStatisticsDisplayStrategy; m_pFH->nExternalTagType = Protocol.nExternalTagType; m_pFH->nStatisticsClearStrategy = Protocol.nStatisticsClearStrategy; m_pFH->nLTPType = Protocol.nLTPType; m_pFH->nScopeTriggerOut = Protocol.nScopeTriggerOut; m_pFH->nAlternateDACOutputState = Protocol.nAlternateDACOutputState; m_pFH->nAlternateDigitalOutputState = Protocol.nAlternateDigitalOutputState; bOK &= GetString( Protocol.lFileCommentIndex, m_pFH->sFileComment, ELEMENTS_IN( m_pFH->sFileComment ) ); return bOK; } //=============================================================================================== // FUNCTION: ReadADCInfo // PURPOSE: Reads the ADC info from the data file. // BOOL CABF2ProtocolReader::ReadADCInfo() { MEMBERASSERT(); short ch = 0; BOOL bOK = TRUE; ABF_ADCInfo ADCInfo; ASSERT( m_FileInfo.ADCSection.llNumEntries ); ASSERT( m_FileInfo.ADCSection.uBytes == sizeof( ADCInfo ) ); bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.ADCSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; for( int a=0; aRead( &ADCInfo, sizeof( ADCInfo ) ); // Read the channel. ch = ADCInfo.nADCNum; if( ADCInfo.nADCNum >= 0 ) { // Setup the sampling sequence array, using the channel sequence index. m_pFH->nADCSamplingSeq[a] = ADCInfo.nADCNum; // Everything else use the channel index. m_pFH->nTelegraphEnable[ch] = ADCInfo.nTelegraphEnable; m_pFH->nTelegraphInstrument[ch] = ADCInfo.nTelegraphInstrument; m_pFH->fTelegraphAdditGain[ch] = ADCInfo.fTelegraphAdditGain; m_pFH->fTelegraphFilter[ch] = ADCInfo.fTelegraphFilter; m_pFH->fTelegraphMembraneCap[ch] = ADCInfo.fTelegraphMembraneCap; m_pFH->nTelegraphMode[ch] = ADCInfo.nTelegraphMode; m_pFH->fTelegraphAccessResistance[ch] = ADCInfo.fTelegraphAccessResistance; m_pFH->nADCPtoLChannelMap[ch] = ADCInfo.nADCPtoLChannelMap; m_pFH->fADCProgrammableGain[ch] = ADCInfo.fADCProgrammableGain; m_pFH->fADCDisplayAmplification[ch] = ADCInfo.fADCDisplayAmplification; m_pFH->fADCDisplayOffset[ch] = ADCInfo.fADCDisplayOffset; m_pFH->fInstrumentScaleFactor[ch] = ADCInfo.fInstrumentScaleFactor; m_pFH->fInstrumentOffset[ch] = ADCInfo.fInstrumentOffset; m_pFH->fSignalGain[ch] = ADCInfo.fSignalGain; m_pFH->fSignalOffset[ch] = ADCInfo.fSignalOffset; m_pFH->fSignalLowpassFilter[ch] = ADCInfo.fSignalLowpassFilter; m_pFH->fSignalHighpassFilter[ch] = ADCInfo.fSignalHighpassFilter; m_pFH->nLowpassFilterType[ch] = ADCInfo.nLowpassFilterType; m_pFH->nHighpassFilterType[ch] = ADCInfo.nHighpassFilterType; m_pFH->fPostProcessLowpassFilter[ch] = ADCInfo.fPostProcessLowpassFilter; m_pFH->nPostProcessLowpassFilterType[ch] = ADCInfo.nPostProcessLowpassFilterType; m_pFH->nStatsChannelPolarity[ch] = ADCInfo.nStatsChannelPolarity; // Set the DAC index if an old P/N file is read. // CSH if( ADCInfo.bEnabledDuringPN ) // CSH m_pFH->nLeakSubtractADCIndex[0] = ch; bOK &= GetString( ADCInfo.lADCChannelNameIndex, m_pFH->sADCChannelName[ADCInfo.nADCNum], ABF_ADCNAMELEN ); bOK &= GetString( ADCInfo.lADCUnitsIndex, m_pFH->sADCUnits[ADCInfo.nADCNum], ABF_ADCUNITLEN ); } } return bOK; } //=============================================================================================== // FUNCTION: ReadDACInfo // PURPOSE: Reads the DAC info from the data file. // BOOL CABF2ProtocolReader::ReadDACInfo() { MEMBERASSERT(); BOOL bOK = TRUE; ABF_DACInfo DACInfo; ASSERT( m_FileInfo.DACSection.llNumEntries <= ABF2_DACCOUNT ); ASSERT( m_FileInfo.DACSection.uBytes == sizeof( DACInfo ) ); bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.DACSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; for( UINT d=0; dRead( &DACInfo, sizeof( DACInfo ) ); //DACInfo.nDACNum = d; m_pFH->nTelegraphDACScaleFactorEnable[d] = DACInfo.nTelegraphDACScaleFactorEnable; m_pFH->fInstrumentHoldingLevel[d] = DACInfo.fInstrumentHoldingLevel; m_pFH->fDACScaleFactor[d] = DACInfo.fDACScaleFactor; m_pFH->fDACHoldingLevel[d] = DACInfo.fDACHoldingLevel; m_pFH->fDACCalibrationFactor[d] = DACInfo.fDACCalibrationFactor; m_pFH->fDACCalibrationOffset[d] = DACInfo.fDACCalibrationOffset; m_pFH->lDACFilePtr[d] = DACInfo.lDACFilePtr; m_pFH->lDACFileNumEpisodes[d] = DACInfo.lDACFileNumEpisodes; m_pFH->nWaveformEnable[d] = DACInfo.nWaveformEnable; m_pFH->nWaveformSource[d] = DACInfo.nWaveformSource; m_pFH->nInterEpisodeLevel[d] = DACInfo.nInterEpisodeLevel; m_pFH->fDACFileScale[d] = DACInfo.fDACFileScale; m_pFH->fDACFileOffset[d] = DACInfo.fDACFileOffset; m_pFH->lDACFileEpisodeNum[d] = DACInfo.lDACFileEpisodeNum; m_pFH->nDACFileADCNum[d] = DACInfo.nDACFileADCNum; m_pFH->nConditEnable[d] = DACInfo.nConditEnable; m_pFH->lConditNumPulses[d] = DACInfo.lConditNumPulses; m_pFH->fBaselineDuration[d] = DACInfo.fBaselineDuration; m_pFH->fBaselineLevel[d] = DACInfo.fBaselineLevel; m_pFH->fStepDuration[d] = DACInfo.fStepDuration; m_pFH->fStepLevel[d] = DACInfo.fStepLevel; m_pFH->fPostTrainPeriod[d] = DACInfo.fPostTrainPeriod; m_pFH->fPostTrainLevel[d] = DACInfo.fPostTrainLevel; m_pFH->nMembTestEnable[d] = DACInfo.nMembTestEnable; m_pFH->fMembTestPreSettlingTimeMS[d] = DACInfo.fMembTestPreSettlingTimeMS; m_pFH->fMembTestPostSettlingTimeMS[d] = DACInfo.fMembTestPostSettlingTimeMS; m_pFH->nLeakSubtractType[d] = DACInfo.nLeakSubtractType; m_pFH->nPNPosition = DACInfo.nPNPosition; m_pFH->nPNNumPulses = DACInfo.nPNNumPulses; m_pFH->fPNSettlingTime = DACInfo.fPNSettlingTime; m_pFH->fPNInterpulse = DACInfo.fPNInterpulse; m_pFH->nPNPolarity = DACInfo.nPNPolarity; m_pFH->fPNHoldingLevel[d] = DACInfo.fPNHoldingLevel; // CSH m_pFH->nLeakSubtractADCIndex[d] = DACInfo.nLeakSubtractADCIndex; m_pFH->nLTPUsageOfDAC[d] = DACInfo.nLTPUsageOfDAC; m_pFH->nLTPPresynapticPulses[d] = DACInfo.nLTPPresynapticPulses; bOK &= GetString( DACInfo.lDACChannelNameIndex, m_pFH->sDACChannelName[d], ABF_DACNAMELEN ); bOK &= GetString( DACInfo.lDACChannelUnitsIndex, m_pFH->sDACChannelUnits[d], ABF_DACUNITLEN ); bOK &= GetString( DACInfo.lDACFilePathIndex, m_pFH->sDACFilePath[d], ABF_PATHLEN ); } return bOK; } //=============================================================================================== // FUNCTION: ReadEpochs // PURPOSE: Reads the epochs from the data file. // BOOL CABF2ProtocolReader::ReadEpochs() { MEMBERASSERT(); BOOL bOK = TRUE; // Analog Epochs ... one set for each DAC in use. if( m_FileInfo.EpochPerDACSection.uBlockIndex ) { ABF_EpochInfoPerDAC Epoch; ASSERT( m_FileInfo.EpochPerDACSection.uBytes == sizeof( Epoch ) ); ASSERT( m_FileInfo.EpochPerDACSection.llNumEntries ); bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.EpochPerDACSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; for( long i=0; iRead( &Epoch, sizeof( Epoch ) ); ASSERT( Epoch.nEpochType != ABF_EPOCHDISABLED ); short e = Epoch.nEpochNum; short d = Epoch.nDACNum; m_pFH->nEpochType[d][e] = Epoch.nEpochType; m_pFH->fEpochInitLevel[d][e] = Epoch.fEpochInitLevel; m_pFH->fEpochLevelInc[d][e] = Epoch.fEpochLevelInc; m_pFH->lEpochInitDuration[d][e] = Epoch.lEpochInitDuration; m_pFH->lEpochDurationInc[d][e] = Epoch.lEpochDurationInc; m_pFH->lEpochPulsePeriod[d][e] = Epoch.lEpochPulsePeriod; m_pFH->lEpochPulseWidth[d][e] = Epoch.lEpochPulseWidth; } } // Digital Epochs ... one set only. if( m_FileInfo.EpochSection.uBlockIndex ) { ABF_EpochInfo Epoch; ASSERT( m_FileInfo.EpochSection.uBytes == sizeof( Epoch ) ); ASSERT( m_FileInfo.EpochSection.llNumEntries ); bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.EpochSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; for( long i=0; iRead( &Epoch, sizeof( Epoch ) ); short e = Epoch.nEpochNum; m_pFH->nDigitalValue[e] = Epoch.nDigitalValue; m_pFH->nDigitalTrainValue[e] = Epoch.nDigitalTrainValue; m_pFH->nAlternateDigitalValue[e] = Epoch.nAlternateDigitalValue; m_pFH->nAlternateDigitalTrainValue[e] = Epoch.nAlternateDigitalTrainValue; m_pFH->bEpochCompression[e] = Epoch.bEpochCompression; } } return bOK; } //=============================================================================================== // FUNCTION: ReadStats // PURPOSE: Reads the Stats regions from the data file. // BOOL CABF2ProtocolReader::ReadStats() { MEMBERASSERT(); BOOL bOK = TRUE; if( m_FileInfo.StatsRegionSection.uBlockIndex ) { bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.StatsRegionSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; for( long i=0; iRead( &Stats, sizeof( Stats ) ); short r = Stats.nRegionNum; UINT uBitMask = 0x01 << r; m_pFH->nStatsSearchRegionFlags |= uBitMask; m_pFH->lStatsMeasurements[r] = Stats.lStatsMeasurements; m_pFH->lStatsStart[r] = Stats.lStatsStart; m_pFH->lStatsEnd[r] = Stats.lStatsEnd; m_pFH->nRiseTopPercentile[r] = Stats.nRiseTopPercentile; m_pFH->nRiseBottomPercentile[r] = Stats.nRiseBottomPercentile; m_pFH->nDecayBottomPercentile[r] = Stats.nDecayBottomPercentile; m_pFH->nDecayTopPercentile[r] = Stats.nDecayTopPercentile; m_pFH->nStatsSearchMode[r] = Stats.nStatsSearchMode; m_pFH->nStatsSearchDAC[r] = Stats.nStatsSearchDAC; m_pFH->nStatsActiveChannels = Stats.nStatsActiveChannels; m_pFH->nStatsSearchRegionFlags = Stats.nStatsSearchRegionFlags; m_pFH->nStatsSmoothing = Stats.nStatsSmoothing; m_pFH->nStatsSmoothingEnable = Stats.nStatsSmoothingEnable; m_pFH->nStatsBaseline = Stats.nStatsBaseline; m_pFH->nStatsBaselineDAC = Stats.nStatsBaselineDAC; m_pFH->lStatsBaselineStart = Stats.lStatsBaselineStart; m_pFH->lStatsBaselineEnd = Stats.lStatsBaselineEnd; // Some early ABF 2 protocols did not use the "DAC" field, so coerce these. if( Stats.nStatsSearchMode >= ABF_EPOCHCOUNT ) { m_pFH->nStatsSearchMode[r] = Stats.nStatsSearchMode % ABF_EPOCHCOUNT; m_pFH->nStatsSearchDAC[r] = Stats.nStatsSearchMode / ABF_EPOCHCOUNT; } if( Stats.nStatsBaseline >= ABF_EPOCHCOUNT ) { m_pFH->nStatsBaseline = Stats.nStatsBaseline % ABF_EPOCHCOUNT; m_pFH->nStatsBaselineDAC = Stats.nStatsBaseline / ABF_EPOCHCOUNT; } } } return bOK; } //=============================================================================================== // FUNCTION: ReadUserList // PURPOSE: Reads the user list from the data file. // BOOL CABF2ProtocolReader::ReadUserList() { MEMBERASSERT(); BOOL bOK = TRUE; if( m_FileInfo.UserListSection.uBlockIndex ) { ABF_UserListInfo UserList; ASSERT( m_FileInfo.UserListSection.uBytes == sizeof( UserList ) ); ASSERT( m_FileInfo.UserListSection.llNumEntries ); bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.UserListSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; for( long i=0; iRead( &UserList, sizeof( UserList ) ); short u = UserList.nListNum; m_pFH->nULEnable[u] = 1; m_pFH->nULParamToVary[u] = UserList.nULParamToVary; m_pFH->nULRepeat[u] = UserList.nULRepeat; bOK &= GetString( UserList.lULParamValueListIndex, m_pFH->sULParamValueList[u], ABF_USERLISTLEN ); } } return bOK; } //=============================================================================================== // FUNCTION: ReadMathInfo // PURPOSE: Read the math channel info to the data file. // NOTES: We currently only support one math channel, but the file can support any number. // BOOL CABF2ProtocolReader::ReadMathInfo() { MEMBERASSERT(); BOOL bOK = TRUE; if( m_FileInfo.MathSection.uBlockIndex ) { ABF_MathInfo Math; ASSERT( m_FileInfo.MathSection.uBytes == sizeof( ABF_MathInfo ) ); ASSERT( m_FileInfo.MathSection.llNumEntries ); bOK &= m_pFI->Seek( LONGLONG(m_FileInfo.MathSection.uBlockIndex) * ABF_BLOCKSIZE, FILE_BEGIN ); if( !bOK ) return FALSE; bOK &= m_pFI->Read( &Math, sizeof( Math ) ); m_pFH->nArithmeticEnable = Math.nMathEnable; m_pFH->nArithmeticExpression = Math.nMathExpression; m_pFH->fArithmeticUpperLimit = Math.fMathUpperLimit; m_pFH->fArithmeticLowerLimit = Math.fMathLowerLimit; m_pFH->nArithmeticADCNumA = Math.nMathADCNum[0]; m_pFH->nArithmeticADCNumB = Math.nMathADCNum[1]; m_pFH->fArithmeticK1 = Math.fMathK[0]; m_pFH->fArithmeticK2 = Math.fMathK[1]; m_pFH->fArithmeticK3 = Math.fMathK[2]; m_pFH->fArithmeticK4 = Math.fMathK[3]; m_pFH->fArithmeticK5 = Math.fMathK[4]; m_pFH->fArithmeticK6 = Math.fMathK[5]; GetString( Math.uMathOperatorIndex, m_pFH->sArithmeticOperator, sizeof( m_pFH->sArithmeticOperator ) ); GetString( Math.uMathUnitsIndex, m_pFH->sArithmeticUnits, sizeof( m_pFH->sArithmeticUnits ) ); } return bOK; } #if 0 //=============================================================================================== // FUNCTION: ValidateCRC // PURPOSE: Validates the CRC in the FileInfo matches the CRC of the file. // BOOL CABF2ProtocolReader::ValidateCRC() { MEMBERASSERT(); if( m_pFH->nCRCEnable != ABF_CRC_ENABLED ) return TRUE; // CRC checking required. Read( 0 ); #if _DEBUG // Get the total length of the file. #ifdef _DEBUG LONGLONG llFileLength = m_pFI->GetFileSize(); UINT uHeaderSize = sizeof( m_FileInfo ); ASSERT( llFileLength > uHeaderSize ); #endif // _DEBUG #endif // Keep expected CRC value from header and Zero the lFileCRC. UINT uExpectedCRC = m_FileInfo.uFileCRC; m_FileInfo.uFileCRC = 0; UINT uFileCRC = CalculateCRC( &m_FileInfo, sizeof( m_FileInfo ) ); // Restore the original CRC. m_FileInfo.uFileCRC = uExpectedCRC; // Compare expected CRC with file CRC. if ( uFileCRC != uExpectedCRC ) { TRACE2( "File CRC Validation Failed: Expected %X, Calculated %X\n", uExpectedCRC, uFileCRC ); return FALSE; } TRACE1( "File CRC Validation OK: %X\n", uFileCRC); return TRUE; } #endif BOOL CABF2ProtocolReader::Open( LPCTSTR fName ) { int nError = 0; // Get a new file descriptor if available. if (!GetNewFileDescriptor(&m_pFI, &nFile, &nError)) return FALSE; // Now open the file for reading. if (!m_pFI->Open(fName, TRUE)) { return FALSE; } return TRUE; } BOOL CABF2ProtocolReader::Close( ) { int nError = 0; CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, &nError)) { return FALSE; } ReleaseFileDescriptor( nFile ); return TRUE; } //=============================================================================================== // FUNCTION: CanOpen // PURPOSE: Returns TRUE if this reader can open the file // BOOL CABF2ProtocolReader::CanOpen( const void *pFirstBlock, UINT uBytes ) { ASSERT( pFirstBlock ); ASSERT( uBytes >= sizeof( ABF2_FileInfo ) ); ABF2_FileInfo *pInfo = (ABF2_FileInfo *)pFirstBlock; // Check if it has the correct signature. if( pInfo->uFileSignature != ABF2_FILESIGNATURE ) return FALSE; // Check the major file version BYTE byMajorVersion = HIBYTE( HIWORD( pInfo->uFileVersionNumber ) ); if( byMajorVersion == 2 ) return TRUE; return FALSE; } stimfit-0.16.7/src/libstfio/abf/axon2/abf2headr.cpp0000664000175000017500000003212214752207205015456 //*********************************************************************************************** // // Copyright (c) 1993-2000 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // This is ABF2HEADR.CPP; the routines that cope with reading the data file // parameters block for all AXON pCLAMP binary file formats. // // An ANSI C compiler should be used for compilation. // Compile with the large memory model option. // (e.g. CL -c -AL ABFHEADR.C) #include "../axon/Common/wincpp.hpp" #include "abf2headr.h" #include "../axon/AxAbfFio32/abfheadr.h" #include "../axon/AxAbfFio32/abfutil.h" //=============================================================================================== // FUNCTION: ABFH_Initialize // PURPOSE: Initialize an ABFFileHeader structure to a consistent set of parameters // void WINAPI ABF2H_Initialize( ABF2FileHeader *pFH ) { int i; // Zero fill all to start with. memset(pFH, '\0', sizeof(*pFH)); // Blank fill all strings. ABF_BLANK_FILL(pFH->sADCChannelName); ABF_BLANK_FILL(pFH->sADCUnits); ABF_BLANK_FILL(pFH->sDACChannelName); ABF_BLANK_FILL(pFH->sDACChannelUnits); ABF_BLANK_FILL(pFH->sDACFilePath[0]); ABF_BLANK_FILL(pFH->sDACFilePath[1]); ABF_SET_STRING(pFH->sArithmeticOperator, "+"); ABF_BLANK_FILL(pFH->sArithmeticUnits); pFH->fFileVersionNumber = ABF2_CURRENTVERSION; pFH->fHeaderVersionNumber = ABF2_CURRENTVERSION; pFH->nOperationMode = ABF2_GAPFREEFILE; pFH->nADCNumChannels = 1; pFH->fADCSequenceInterval = 100.0F; pFH->lNumSamplesPerEpisode = 512; pFH->lEpisodesPerRun = 1; pFH->lDataSectionPtr = sizeof(ABFFileHeader) / ABF2_BLOCKSIZE; pFH->nDataDisplayMode = ABF2_DRAW_LINES; pFH->nFileType = ABF2_ABFFILE; pFH->nAutoTriggerStrategy = 1; // Allow auto triggering. pFH->nChannelStatsStrategy = 0; // Don't calculate channel statistics. pFH->fStatisticsPeriod = 1.0F; pFH->lStatisticsMeasurements = ABF2_STATISTICS_ABOVETHRESHOLD | ABF2_STATISTICS_MEANOPENTIME; pFH->lSamplesPerTrace = 16384; pFH->lPreTriggerSamples = 16; // default to 16 pFH->fADCRange = 10.24F; pFH->fDACRange = 10.24F; pFH->lADCResolution = 32768L; pFH->lDACResolution = 32768L; pFH->nExperimentType = ABF2_SIMPLEACQUISITION; ABF_BLANK_FILL(pFH->sCreatorInfo); ABF_BLANK_FILL(pFH->sModifierInfo); ABF_BLANK_FILL(pFH->sFileComment); // ADC channel data for (i=0; isADCChannelName[i], szName, ABF2_ADCNAMELEN); strncpy(pFH->sADCUnits[i], "pA ", ABF2_ADCUNITLEN); pFH->nADCPtoLChannelMap[i] = short(i); pFH->nADCSamplingSeq[i] = ABF2_UNUSED_CHANNEL; pFH->fADCProgrammableGain[i] = 1.0F; pFH->fADCDisplayAmplification[i] = 1.0F; pFH->fInstrumentScaleFactor[i] = 0.1F; pFH->fSignalGain[i] = 1.0F; pFH->fSignalLowpassFilter[i] = ABF2_FILTERDISABLED; // FIX FIX FIX PRC DEBUG Telegraph changes - check ! pFH->fTelegraphAdditGain[i] = 1.0F; pFH->fTelegraphFilter[i] = 100000.0F; } pFH->nADCSamplingSeq[0] = 0; // DAC channel data for (i=0; isDACChannelName[i], szName, ABF2_DACNAMELEN); strncpy(pFH->sDACChannelUnits[i], "mV ", ABF2_ADCUNITLEN); pFH->fDACScaleFactor[i] = 20.0F; } // DAC file settings for (i=0; ifDACFileScale[i] = 1.0F; } pFH->nPNPolarity = ABF2_PN_SAME_POLARITY; pFH->nPNNumPulses = 2; pFH->fPNInterpulse = 0; // Initialize as non-zero to avoid glitch in first holding pFH->fPNSettlingTime = 10; for (i=0; ifPostTrainPeriod[i] = 10; // Initialize statistics variables. pFH->nStatsSearchRegionFlags = ABF2_PEAK_SEARCH_REGION0; pFH->nStatsBaseline = ABF2_PEAK_BASELINE_SPECIFIED; pFH->nStatsSmoothing = 1; pFH->nStatsActiveChannels = 0; for( int nStatsRegionID = 0; nStatsRegionID < ABF2_STATS_REGIONS; nStatsRegionID++ ) { pFH->nStatsSearchMode[ nStatsRegionID ] = ABF2_PEAK_SEARCH_SPECIFIED; pFH->lStatsMeasurements[ nStatsRegionID ] = ABF2_PEAK_MEASURE_PEAK | ABF2_PEAK_MEASURE_PEAKTIME; pFH->nRiseBottomPercentile[ nStatsRegionID ] = 10; pFH->nRiseTopPercentile[ nStatsRegionID ] = 90; pFH->nDecayBottomPercentile[ nStatsRegionID ] = 10; pFH->nDecayTopPercentile[ nStatsRegionID ] = 90; } for ( UINT uChannel = 0; uChannel < ABF2_ADCCOUNT; uChannel++ ) pFH->nStatsChannelPolarity[uChannel] = ABF2_PEAK_ABSOLUTE; pFH->fArithmeticUpperLimit = 100.0F; pFH->fArithmeticLowerLimit = -100.0F; pFH->fArithmeticK1 = 1.0F; pFH->fArithmeticK3 = 1.0F; pFH->nLevelHysteresis = 64; // Two LSBits of level hysteresis. pFH->lTimeHysteresis = 1; // Two sequences of time hysteresis. pFH->fAverageWeighting = 0.1F; // Add 10% of trace to 90% of average. pFH->nTrialTriggerSource = ABF2_TRIALTRIGGER_NONE; pFH->nExternalTagType = ABF2_EXTERNALTAG; pFH->nAutoAnalyseEnable = ABF2_AUTOANALYSE_DEFAULT; for( i=0; isULParamValueList[i] ); // DAC Calibration Factors. for( i=0; ifDACCalibrationFactor[i] = 1.0F; pFH->fDACCalibrationOffset[i] = 0.0F; } // Digital train params. pFH->nDigitalTrainActiveLogic = 1; for( i = 0; i < ABF2_EPOCHCOUNT; i ++ ) { pFH->nDigitalTrainValue[ i ] = 0; } // Initialize LTP type. pFH->nLTPType = ABF2_LTP_TYPE_NONE; for( i=0; inLTPUsageOfDAC[ i ] = ABF2_LTP_DAC_USAGE_NONE; pFH->nLTPPresynapticPulses[ i ] = 0; } // Alternating Outputs pFH->nAlternateDACOutputState = 0; pFH->nAlternateDigitalOutputState = 0; for( int nEpoch = 0; nEpoch < ABF2_EPOCHCOUNT; nEpoch ++ ) { pFH->nAlternateDigitalValue[ nEpoch ] = 0; pFH->nAlternateDigitalTrainValue[ nEpoch ] = 0; } //Post-processing values. for( i=0; ifPostProcessLowpassFilter[i] = ABF2_FILTERDISABLED; pFH->nPostProcessLowpassFilterType[i] = ABF2_POSTPROCESS_FILTER_NONE; } } //=============================================================================================== // FUNCTION: ABFH_GetChannelOffset // PURPOSE: Get the offset in the sampling sequence for the given physical channel. // BOOL WINAPI ABF2H_GetChannelOffset( const ABF2FileHeader *pFH, int nChannel, UINT *puChannelOffset ) { // ABFH_ASSERT(pFH); // WPTRASSERT(puChannelOffset); int nOffset; // check the ADC channel number, -1 refers to the math channel if (nChannel < 0) { if (!pFH->nArithmeticEnable) { if (puChannelOffset) *puChannelOffset = 0; // return the offset to this channel return FALSE; // channel not found in sampling sequence } nChannel = pFH->nArithmeticADCNumA; } for (nOffset = 0; nOffset < pFH->nADCNumChannels; nOffset++) { if (pFH->nADCSamplingSeq[nOffset] == nChannel) { if (puChannelOffset) *puChannelOffset = UINT(nOffset); // return the offset to this channel return TRUE; } } if (puChannelOffset) *puChannelOffset = 0; // return the offset to this channel return FALSE; } //============================================================================================== // FUNCTION: GetADCtoUUFactors // PURPOSE: Calculates the scaling factors used to convert ADC values to UserUnits. // PARAMETERS: // nChannel - The physical channel number to get the factors for. // pfADCToUUFactor - Pointers to return locations for scale and offset. // pfADCToUUShift UserUnits = ADCValue * fADCToUUFactor + fADCToUUShift; // void WINAPI ABF2H_GetADCtoUUFactors( const ABF2FileHeader *pFH, int nChannel, float *pfADCToUUFactor, float *pfADCToUUShift ) { ASSERT(nChannel < ABF2_ADCCOUNT); float fTotalScaleFactor = pFH->fInstrumentScaleFactor[nChannel] * pFH->fADCProgrammableGain[nChannel]; if (pFH->nSignalType != 0) fTotalScaleFactor *= pFH->fSignalGain[nChannel]; // Adjust for the telegraphed gain. if( pFH->nTelegraphEnable[nChannel] ) fTotalScaleFactor *= pFH->fTelegraphAdditGain[nChannel]; ASSERT(fTotalScaleFactor != 0.0F); if (fTotalScaleFactor==0.0F) fTotalScaleFactor = 1.0F; // InputRange and InputOffset is the range and offset of the signal in // user units when it hits the Analog-to-Digital converter float fInputRange = pFH->fADCRange / fTotalScaleFactor; float fInputOffset= -pFH->fInstrumentOffset[nChannel]; if (pFH->nSignalType != 0) fInputOffset += pFH->fSignalOffset[nChannel]; *pfADCToUUFactor = fInputRange / pFH->lADCResolution; *pfADCToUUShift = -fInputOffset; } #define AVERYBIGNUMBER 3.402823466E+38 //=============================================================================================== // FUNCTION: ABFH_GetMathValue // PURPOSE: Evaluate the Math expression for the given UU values. // RETURNS: TRUE if the expression could be evaluated OK. // FALSE if a divide by zero occurred. // BOOL WINAPI ABF2H_GetMathValue(const ABF2FileHeader *pFH, float fA, float fB, float *pfRval) { // ABFH_ASSERT(pFH); // WPTRASSERT(pfRval); double dResult = 0.0; // default return response double dLeftVal, dRightVal; BOOL bRval = TRUE; if (pFH->nArithmeticExpression == ABF2_SIMPLE_EXPRESSION) { dLeftVal = pFH->fArithmeticK1 * fA + pFH->fArithmeticK2; dRightVal = pFH->fArithmeticK3 * fB + pFH->fArithmeticK4; } else { double dRatio; if (fB + pFH->fArithmeticK6 != 0.0F) dRatio = (fA + pFH->fArithmeticK5) / (fB + pFH->fArithmeticK6); else if (fA + pFH->fArithmeticK5 > 0.0F) { dRatio = AVERYBIGNUMBER; bRval = FALSE; } else { dRatio = -AVERYBIGNUMBER; bRval = FALSE; } dLeftVal = pFH->fArithmeticK1 * dRatio + pFH->fArithmeticK2; dRightVal = pFH->fArithmeticK3 * dRatio + pFH->fArithmeticK4; } switch (pFH->sArithmeticOperator[0]) { case '+': dResult = dLeftVal + dRightVal; break; case '-': dResult = dLeftVal - dRightVal; break; case '*': dResult = dLeftVal * dRightVal; break; case '/': if (dRightVal != 0.0) dResult = dLeftVal / dRightVal; else if (dLeftVal > 0) { dResult = pFH->fArithmeticUpperLimit; bRval = FALSE; } else { dResult = pFH->fArithmeticLowerLimit; bRval = FALSE; } break; default: //ERRORMSG1("Unexpected operator '%c'.", pFH->sArithmeticOperator[0]); break; } if (dResult < pFH->fArithmeticLowerLimit) dResult = pFH->fArithmeticLowerLimit; else if (dResult > pFH->fArithmeticUpperLimit) dResult = pFH->fArithmeticUpperLimit; if (pfRval) *pfRval = (float)dResult; return bRval; } //=============================================================================================== // FUNCTION: GetSampleInterval // PURPOSE: Gets the sample interval expressed as a double. // This prevents round off errors in modifiable ABF files, // where sample intervals are not constrained to be in multiples of 0.5 us. // static double GetSampleInterval( const ABF2FileHeader *pFH, const UINT uInterval ) { // ABFH_ASSERT( pFH ); ASSERT( uInterval == 1 || uInterval == 2 ); float fInterval = 0; if( uInterval == 1 ) fInterval = pFH->fLegacyADCSequenceInterval; else if( uInterval == 2 ) fInterval = pFH->fLegacyADCSecondSequenceInterval; else ; //ERRORMSG( "ABFH_GetSampleInterval called with invalid parameters !\n" ); // Modifiable ABF allows sample intervals which are not multiples of 0.5 us // Attempt to reconstruct the original sample interval to 0.1 us resolution // This has no adverse effect for acquisition files and prevents rounding errors in modifable ABF files. double dInterval = int((fInterval * pFH->nADCNumChannels) * 10 + 0.5); dInterval /= 10 * pFH->nADCNumChannels; return dInterval; } //=============================================================================================== // FUNCTION: ABFH_GetFirstSampleInterval // PURPOSE: Gets the first sample interval expressed as a double. double WINAPI ABF2H_GetFirstSampleInterval( const ABF2FileHeader *pFH ) { return GetSampleInterval( pFH, 1 ); } stimfit-0.16.7/src/libstfio/abf/axon2/abf2headr.h0000664000175000017500000014273014750344764015144 //*********************************************************************************************** // // Copyright (c) 1993-2004 Molecular Devices Corporation. // All rights reserved. // Permission is granted to freely use, modify and copy the code in this file. // //*********************************************************************************************** // HEADER: ABFHEADR.H. // PURPOSE: Defines the ABFFileHeader structure, and provides prototypes for // functions implemented in ABFHEADR.CPP for reading and writing // ABFFileHeader's. // REVISIONS: // 2.0 - This version separates the data in the file from the struct passed around within the application. #ifndef INC_ABFHEADR2_H #define INC_ABFHEADR2_H #include "../axon/AxAbfFio32/AxAbffio32.h" #ifdef __cplusplus extern "C" { #endif // // Constants used in defining the ABF file header // #define ABF2_ADCCOUNT 16 // number of ADC channels supported. #define ABF2_DACCOUNT 8 // number of DAC channels supported. #define ABF2_EPOCHCOUNT 10 // number of waveform epochs supported. #define ABF2_ADCUNITLEN 8 // length of ADC units strings #define ABF2_ADCNAMELEN 10 // length of ADC channel name strings #define ABF2_ADCNAMELEN_USER 8 // length of user-entered ADC channel name strings #define ABF2_DACUNITLEN 8 // length of DAC units strings #define ABF2_DACNAMELEN 10 // length of DAC channel name strings #define ABF2_USERLISTLEN 256 // length of the user list (V1.6) //#define ABF2_USERLISTCOUNT 4 // number of independent user lists (V1.6) #define ABF2_USERLISTCOUNT ABF2_DACCOUNT // number of independent user lists (V1.6) #define ABF2_OLDFILECOMMENTLEN 56 // length of file comment string (pre V1.6) #define ABF2_FILECOMMENTLEN 128 // length of file comment string (V1.6) #define ABF2_PATHLEN 256 // length of full path, used for DACFile and Protocol name. #define ABF2_CREATORINFOLEN 16 // length of file creator info string #define ABF2_ARITHMETICOPLEN 2 // length of the Arithmetic operator field #define ABF2_ARITHMETICUNITSLEN 8 // length of arithmetic units string #define ABF2_TAGCOMMENTLEN 56 // length of tag comment string #define ABF2_BLOCKSIZE 512 // Size of block alignment in ABF files. #define PCLAMP6_MAXSWEEPLENGTH 16384 // Maximum multiplexed sweep length supported by pCLAMP6 apps. #define PCLAMP7_MAXSWEEPLEN_PERCHAN 1032258 // Maximum per channel sweep length supported by pCLAMP7 apps. #define ABF2_MAX_SWEEPS_PER_AVERAGE 65500 // The maximum number of sweeps that can be combined into a // cumulative average (nAverageAlgorithm=ABF2_INFINITEAVERAGE). #define ABF2_MAX_TRIAL_SAMPLES 0x7FFFFFFF // Maximum length of acquisition supported (samples) // INT_MAX is used instead of UINT_MAX because of the signed // values in the ABF header. // // Constants for nDigitizerType // // // Constants for nDigitizerType // #define ABF2_DIGI_UNKNOWN 0 #define ABF2_DIGI_DEMO 1 #define ABF2_DIGI_MINIDIGI 2 #define ABF2_DIGI_DD132X 3 #define ABF2_DIGI_OPUS 4 #define ABF2_DIGI_PATCH 5 #define ABF2_DIGI_DD1440 6 #define ABF2_DIGI_MINIDIGI2 7 #define ABF2_DIGI_DD1550 8 // // Constants for nDrawingStrategy // #define ABF2_DRAW_NONE 0 #define ABF2_DRAW_REALTIME 1 #define ABF2_DRAW_FULLSCREEN 2 #define ABF2_DRAW_ENDOFRUN 3 // // Constants for nTiledDisplay // #define ABF2_DISPLAY_SUPERIMPOSED 0 #define ABF2_DISPLAY_TILED 1 // // Constants for nDataDisplayMode // #define ABF2_DRAW_POINTS 0 #define ABF2_DRAW_LINES 1 // Constants for the ABF2_ReadOpen and ABF2_WriteOpen functions #define ABF2_DATAFILE 0 #define ABF2_PARAMFILE 1 #define ABF2_ALLOWOVERLAP 2 // If this flag is not set, overlapping data in fixed-length // event-detected data will be edited out by adjustment of // the synch array. (ABF2_ReadOpen only!) #define ABF2_DATAFILE_ABF1 4 #define ABF2_PARAMFILE_ABF1 8 // // Constants for lParameterID in the ABFDelta structure. // // NOTE: If any changes are made to this list, the code in ABF2_UpdateHeader must // be updated to include the new items. #define ABF2_DELTA_HOLDING0 0 #define ABF2_DELTA_HOLDING1 1 #define ABF2_DELTA_HOLDING2 2 #define ABF2_DELTA_HOLDING3 3 #define ABF2_DELTA_DIGITALOUTS 4 #define ABF2_DELTA_THRESHOLD 5 #define ABF2_DELTA_PRETRIGGER 6 #define ABF2_DELTA_HOLDING4 7 #define ABF2_DELTA_HOLDING5 8 #define ABF2_DELTA_HOLDING6 9 #define ABF2_DELTA_HOLDING7 10 // Because of lack of space, the Autosample Gain ID also contains the ADC number. #define ABF2_DELTA_AUTOSAMPLE_GAIN 100 // +ADC channel. // Because of lack of space, the Signal Gain ID also contains the ADC number. #define ABF2_DELTA_SIGNAL_GAIN 200 // +ADC channel. // // Constants for nAveragingMode // #define ABF2_NOAVERAGING 0 #define ABF2_SAVEAVERAGEONLY 1 #define ABF2_AVERAGESAVEALL 2 // // Constants for nAverageAlgorithm // #define ABF2_INFINITEAVERAGE 0 #define ABF2_SLIDINGAVERAGE 1 // // Constants for nUndoPromptStrategy // #define ABF2_UNDOPROMPT_ONABORT 0 #define ABF2_UNDOPROMPT_ALWAYS 1 // // Constants for nTriggerAction // #define ABF2_TRIGGER_STARTEPISODE 0 #define ABF2_TRIGGER_STARTRUN 1 #define ABF2_TRIGGER_STARTTRIAL 2 // N.B. Discontinued in favor of nTrialTriggerSource // // Constants for nTriggerPolarity. // #define ABF2_TRIGGER_RISINGEDGE 0 #define ABF2_TRIGGER_FALLINGEDGE 1 // // Constants for nDACFileEpisodeNum // #define ABF2_DACFILE_SKIPFIRSTSWEEP -1 #define ABF2_DACFILE_USEALLSWEEPS 0 // >0 = The specific sweep number. // // Constants for nInterEpisodeLevel & nDigitalInterEpisode // #define ABF2_INTEREPI_USEHOLDING 0 #define ABF2_INTEREPI_USELASTEPOCH 1 // // Constants for nArithmeticExpression // #define ABF2_SIMPLE_EXPRESSION 0 #define ABF2_RATIO_EXPRESSION 1 // // Constants for nLowpassFilterType & nHighpassFilterType // #define ABF2_FILTER_NONE 0 #define ABF2_FILTER_EXTERNAL 1 #define ABF2_FILTER_SIMPLE_RC 2 #define ABF2_FILTER_BESSEL 3 #define ABF2_FILTER_BUTTERWORTH 4 // // Constants for post nPostprocessLowpassFilterType // #define ABF2_POSTPROCESS_FILTER_NONE 0 #define ABF2_POSTPROCESS_FILTER_ADAPTIVE 1 #define ABF2_POSTPROCESS_FILTER_BESSEL 2 #define ABF2_POSTPROCESS_FILTER_BOXCAR 3 #define ABF2_POSTPROCESS_FILTER_BUTTERWORTH 4 #define ABF2_POSTPROCESS_FILTER_CHEBYSHEV 5 #define ABF2_POSTPROCESS_FILTER_GAUSSIAN 6 #define ABF2_POSTPROCESS_FILTER_RC 7 #define ABF2_POSTPROCESS_FILTER_RC8 8 #define ABF2_POSTPROCESS_FILTER_NOTCH 9 // // The output sampling sequence identifier for a separate digital out channel. // #define ABF2_DIGITAL_OUT_CHANNEL -1 #define ABF2_PADDING_OUT_CHANNEL -2 // // Constants for nAutoAnalyseEnable // #define ABF2_AUTOANALYSE_DISABLED 0 #define ABF2_AUTOANALYSE_DEFAULT 1 #define ABF2_AUTOANALYSE_RUNMACRO 2 // // Constants for nAutopeakSearchMode // #define ABF2_PEAK_SEARCH_SPECIFIED -2 #define ABF2_PEAK_SEARCH_ALL -1 // nAutopeakSearchMode 0..9 = epoch in waveform 0's epoch table // nAutopeakSearchMode 10..19 = epoch in waveform 1's epoch table // // Constants for nAutopeakBaseline // #define ABF2_PEAK_BASELINE_SPECIFIED -3 #define ABF2_PEAK_BASELINE_NONE -2 #define ABF2_PEAK_BASELINE_FIRSTHOLDING -1 #define ABF2_PEAK_BASELINE_LASTHOLDING -4 // Bit flag settings for nStatsSearchRegionFlags // #define ABF2_PEAK_SEARCH_REGION0 0x01 #define ABF2_PEAK_SEARCH_REGION1 0x02 #define ABF2_PEAK_SEARCH_REGION2 0x04 #define ABF2_PEAK_SEARCH_REGION3 0x08 #define ABF2_PEAK_SEARCH_REGION4 0x10 #define ABF2_PEAK_SEARCH_REGION5 0x20 #define ABF2_PEAK_SEARCH_REGION6 0x40 #define ABF2_PEAK_SEARCH_REGION7 0x80 #define ABF2_PEAK_SEARCH_REGIONALL 0xFF // All of the above OR'd together. // // Constants for nStatsActiveChannels // #define ABF2_PEAK_SEARCH_CHANNEL0 0x0001 #define ABF2_PEAK_SEARCH_CHANNEL1 0x0002 #define ABF2_PEAK_SEARCH_CHANNEL2 0x0004 #define ABF2_PEAK_SEARCH_CHANNEL3 0x0008 #define ABF2_PEAK_SEARCH_CHANNEL4 0x0010 #define ABF2_PEAK_SEARCH_CHANNEL5 0x0020 #define ABF2_PEAK_SEARCH_CHANNEL6 0x0040 #define ABF2_PEAK_SEARCH_CHANNEL7 0x0080 #define ABF2_PEAK_SEARCH_CHANNEL8 0x0100 #define ABF2_PEAK_SEARCH_CHANNEL9 0x0200 #define ABF2_PEAK_SEARCH_CHANNEL10 0x0400 #define ABF2_PEAK_SEARCH_CHANNEL11 0x0800 #define ABF2_PEAK_SEARCH_CHANNEL12 0x1000 #define ABF2_PEAK_SEARCH_CHANNEL13 0x2000 #define ABF2_PEAK_SEARCH_CHANNEL14 0x4000 #define ABF2_PEAK_SEARCH_CHANNEL15 0x8000 #define ABF2_PEAK_SEARCH_CHANNELSALL 0xFFFF // All of the above OR'd together. // // Constants for nLeakSubtractType // #define ABF2_LEAKSUBTRACT_NONE 0 #define ABF2_LEAKSUBTRACT_PN 1 #define ABF2_LEAKSUBTRACT_RESISTIVE 2 // // Constants for nPNPolarity // #define ABF2_PN_OPPOSITE_POLARITY -1 #define ABF2_PN_SAME_POLARITY 1 // // Constants for nPNPosition // #define ABF2_PN_BEFORE_EPISODE 0 #define ABF2_PN_AFTER_EPISODE 1 // // Constants for nAutosampleEnable // #define ABF2_AUTOSAMPLEDISABLED 0 #define ABF2_AUTOSAMPLEAUTOMATIC 1 #define ABF2_AUTOSAMPLEMANUAL 2 // // Constants for nAutosampleInstrument // #define ABF2_INST_UNKNOWN 0 // Unknown instrument (manual or user defined telegraph table). #define ABF2_INST_AXOPATCH1 1 // Axopatch-1 with CV-4-1/100 #define ABF2_INST_AXOPATCH1_1 2 // Axopatch-1 with CV-4-0.1/100 #define ABF2_INST_AXOPATCH1B 3 // Axopatch-1B(inv.) CV-4-1/100 #define ABF2_INST_AXOPATCH1B_1 4 // Axopatch-1B(inv) CV-4-0.1/100 #define ABF2_INST_AXOPATCH201 5 // Axopatch 200 with CV 201 #define ABF2_INST_AXOPATCH202 6 // Axopatch 200 with CV 202 #define ABF2_INST_GENECLAMP 7 // GeneClamp #define ABF2_INST_DAGAN3900 8 // Dagan 3900 #define ABF2_INST_DAGAN3900A 9 // Dagan 3900A #define ABF2_INST_DAGANCA1_1 10 // Dagan CA-1 Im=0.1 #define ABF2_INST_DAGANCA1 11 // Dagan CA-1 Im=1.0 #define ABF2_INST_DAGANCA10 12 // Dagan CA-1 Im=10 #define ABF2_INST_WARNER_OC725 13 // Warner OC-725 #define ABF2_INST_WARNER_OC725C 14 // Warner OC-725 #define ABF2_INST_AXOPATCH200B 15 // Axopatch 200B #define ABF2_INST_DAGANPCONE0_1 16 // Dagan PC-ONE Im=0.1 #define ABF2_INST_DAGANPCONE1 17 // Dagan PC-ONE Im=1.0 #define ABF2_INST_DAGANPCONE10 18 // Dagan PC-ONE Im=10 #define ABF2_INST_DAGANPCONE100 19 // Dagan PC-ONE Im=100 #define ABF2_INST_WARNER_BC525C 20 // Warner BC-525C #define ABF2_INST_WARNER_PC505 21 // Warner PC-505 #define ABF2_INST_WARNER_PC501 22 // Warner PC-501 #define ABF2_INST_DAGANCA1_05 23 // Dagan CA-1 Im=0.05 #define ABF2_INST_MULTICLAMP700 24 // MultiClamp 700 #define ABF2_INST_TURBO_TEC 25 // Turbo Tec #define ABF2_INST_OPUSXPRESS6000 26 // OpusXpress 6000A #define ABF2_INST_AXOCLAMP900 27 // Axoclamp 900 // // Constants for nTagType in the ABFTag structure. // #define ABF2_TIMETAG 0 #define ABF2_COMMENTTAG 1 #define ABF2_EXTERNALTAG 2 #define ABF2_VOICETAG 3 #define ABF2_NEWFILETAG 4 #define ABF2_ANNOTATIONTAG 5 // Same as a comment tag except that nAnnotationIndex holds // the index of the annotation that holds extra information. // Comment inserted for externally acquired tags (expanded with spaces to ABF2_TAGCOMMENTLEN). #define ABF2_EXTERNALTAGCOMMENT "" #define ABF2_VOICETAGCOMMENT "" // // Constants for nManualInfoStrategy // #define ABF2_ENV_DONOTWRITE 0 #define ABF2_ENV_WRITEEACHTRIAL 1 #define ABF2_ENV_PROMPTEACHTRIAL 2 // // Constants for nAutopeakPolarity // #define ABF2_PEAK_NEGATIVE -1 #define ABF2_PEAK_ABSOLUTE 0 #define ABF2_PEAK_POSITIVE 1 // // LTP Types - Reflects whether the header is used for LTP as baseline or induction. // #define ABF2_LTP_TYPE_NONE 0 #define ABF2_LTP_TYPE_BASELINE 1 #define ABF2_LTP_TYPE_INDUCTION 2 // // LTP Usage of DAC - Reflects whether the analog output will be used presynaptically or postsynaptically. // #define ABF2_LTP_DAC_USAGE_NONE 0 #define ABF2_LTP_DAC_USAGE_PRESYNAPTIC 1 #define ABF2_LTP_DAC_USAGE_POSTSYNAPTIC 2 // Values for the wScopeMode field in ABFScopeConfig. #define ABF2_EPISODICMODE 0 #define ABF2_CONTINUOUSMODE 1 //#define ABF2_XYMODE 2 // // Constants for nExperimentType // #define ABF2_VOLTAGECLAMP 0 #define ABF2_CURRENTCLAMP 1 #define ABF2_SIMPLEACQUISITION 2 // // Miscellaneous constants // #define ABF2_FILTERDISABLED 100000.0F // Large frequency to disable lowpass filters #define ABF2_UNUSED_CHANNEL -1 // Unused ADC and DAC channels. #define ABF2_ANY_CHANNEL (UINT)-1 // Any ADC or DAC channel. // // Constant definitions for nDataFormat // #define ABF2_INTEGERDATA 0 #define ABF2_FLOATDATA 1 // // Constant definitions for nOperationMode // #define ABF2_VARLENEVENTS 1 #define ABF2_FIXLENEVENTS 2 // (ABF2_FIXLENEVENTS == ABF2_LOSSFREEOSC) #define ABF2_LOSSFREEOSC 2 #define ABF2_GAPFREEFILE 3 #define ABF2_HIGHSPEEDOSC 4 #define ABF2_WAVEFORMFILE 5 // // Constants for nEpochType // #define ABF2_EPOCHDISABLED 0 // disabled epoch #define ABF2_EPOCHSTEPPED 1 // stepped waveform #define ABF2_EPOCHRAMPED 2 // ramp waveform #define ABF2_EPOCH_TYPE_RECTANGLE 3 // rectangular pulse train #define ABF2_EPOCH_TYPE_TRIANGLE 4 // triangular waveform #define ABF2_EPOCH_TYPE_COSINE 5 // cosinusoidal waveform #define ABF2_EPOCH_TYPE_UNUSED 6 // was ABF2_EPOCH_TYPE_RESISTANCE #define ABF2_EPOCH_TYPE_BIPHASIC 7 // biphasic pulse train #define ABF2_EPOCHSLOPE 8 // IonWorks style ramp waveform // // Constants for epoch resistance // #define ABF2_MIN_EPOCH_RESISTANCE_DURATION 8 // // Constants for nWaveformSource // #define ABF2_WAVEFORMDISABLED 0 // disabled waveform #define ABF2_EPOCHTABLEWAVEFORM 1 #define ABF2_DACFILEWAVEFORM 2 // // Constant definitions for nFileType // #define ABF2_ABFFILE 1 #define ABF2_FETCHEX 2 #define ABF2_CLAMPEX 3 // // maximum values for various parameters (used by ABFH1_CheckUserList). // #define ABF2_CTPULSECOUNT_MAX 10000 #define ABF2_CTBASELINEDURATION_MAX 1000000.0F #define ABF2_CTSTEPDURATION_MAX 1000000.0F #define ABF2_CTPOSTTRAINDURATION_MAX 1000000.0F #define ABF2_SWEEPSTARTTOSTARTTIME_MAX 1000000.0F #define ABF2_PNPULSECOUNT_MAX 8 #define ABF2_DIGITALVALUE_MAX 0xFF #define ABF2_EPOCHDIGITALVALUE_MAX 0xFF // // Constants for nTriggerSource // #define ABF2_TRIGGERLINEINPUT -5 // Start on line trigger (DD1320 only) #define ABF2_TRIGGERTAGINPUT -4 #define ABF2_TRIGGERFIRSTCHANNEL -3 #define ABF2_TRIGGEREXTERNAL -2 #define ABF2_TRIGGERSPACEBAR -1 // >=0 = ADC channel to trigger off. // // Constants for nTrialTriggerSource // #define ABF2_TRIALTRIGGER_SWSTARTONLY -6 // Start on software message, end when protocol ends. #define ABF2_TRIALTRIGGER_SWSTARTSTOP -5 // Start and end on software messages. #define ABF2_TRIALTRIGGER_LINEINPUT -4 // Start on line trigger (DD1320 only) #define ABF2_TRIALTRIGGER_SPACEBAR -3 // Start on spacebar press. #define ABF2_TRIALTRIGGER_EXTERNAL -2 // Start on external trigger high #define ABF2_TRIALTRIGGER_NONE -1 // Start immediately (default). // >=0 = ADC channel to trigger off. // Not implemented as yet... // // Constants for lStatisticsMeasurements // #define ABF2_STATISTICS_ABOVETHRESHOLD 0x00000001 #define ABF2_STATISTICS_EVENTFREQUENCY 0x00000002 #define ABF2_STATISTICS_MEANOPENTIME 0x00000004 #define ABF2_STATISTICS_MEANCLOSEDTIME 0x00000008 #define ABF2_STATISTICS_ALL 0x0000000F // All the above OR'd together. // // Constants for nStatisticsSaveStrategy // #define ABF2_STATISTICS_NOAUTOSAVE 0 #define ABF2_STATISTICS_AUTOSAVE 1 #define ABF2_STATISTICS_AUTOSAVE_AUTOCLEAR 2 // // Constants for nStatisticsDisplayStrategy // #define ABF2_STATISTICS_DISPLAY 0 #define ABF2_STATISTICS_NODISPLAY 1 // // Constants for nStatisticsClearStrategy // determines whether to clear statistics after saving. // #define ABF2_STATISTICS_NOCLEAR 0 #define ABF2_STATISTICS_CLEAR 1 #define ABF2_STATS_REGIONS 8 // The number of independent statistics regions. #define ABF2_BASELINE_REGIONS 1 // The number of independent baseline regions. #define ABF2_STATS_NUM_MEASUREMENTS 18 // The total number of supported statistcs measurements. // // Constants for lAutopeakMeasurements // #define ABF2_PEAK_MEASURE_PEAK 0x00000001 #define ABF2_PEAK_MEASURE_PEAKTIME 0x00000002 #define ABF2_PEAK_MEASURE_ANTIPEAK 0x00000004 #define ABF2_PEAK_MEASURE_ANTIPEAKTIME 0x00000008 #define ABF2_PEAK_MEASURE_MEAN 0x00000010 #define ABF2_PEAK_MEASURE_STDDEV 0x00000020 #define ABF2_PEAK_MEASURE_INTEGRAL 0x00000040 #define ABF2_PEAK_MEASURE_MAXRISESLOPE 0x00000080 #define ABF2_PEAK_MEASURE_MAXRISESLOPETIME 0x00000100 #define ABF2_PEAK_MEASURE_MAXDECAYSLOPE 0x00000200 #define ABF2_PEAK_MEASURE_MAXDECAYSLOPETIME 0x00000400 #define ABF2_PEAK_MEASURE_RISETIME 0x00000800 #define ABF2_PEAK_MEASURE_DECAYTIME 0x00001000 #define ABF2_PEAK_MEASURE_HALFWIDTH 0x00002000 #define ABF2_PEAK_MEASURE_BASELINE 0x00004000 #define ABF2_PEAK_MEASURE_RISESLOPE 0x00008000 #define ABF2_PEAK_MEASURE_DECAYSLOPE 0x00010000 #define ABF2_PEAK_MEASURE_REGIONSLOPE 0x00020000 #define ABF2_PEAK_MEASURE_DURATION 0x00040000 #define ABF2_PEAK_NORMAL_PEAK 0x00100000 #define ABF2_PEAK_NORMAL_ANTIPEAK 0x00400000 #define ABF2_PEAK_NORMAL_MEAN 0x01000000 #define ABF2_PEAK_NORMAL_STDDEV 0x02000000 #define ABF2_PEAK_NORMAL_INTEGRAL 0x04000000 #define ABF2_PEAK_NORMALISABLE 0x00000075 #define ABF2_PEAK_NORMALISED 0x07500000 #define ABF2_PEAK_MEASURE_ALL 0x0752FFFF // All of the above OR'd together. // // Constant definitions for nParamToVary // #define ABF2_CONDITNUMPULSES 0 #define ABF2_CONDITBASELINEDURATION 1 #define ABF2_CONDITBASELINELEVEL 2 #define ABF2_CONDITSTEPDURATION 3 #define ABF2_CONDITSTEPLEVEL 4 #define ABF2_CONDITPOSTTRAINDURATION 5 #define ABF2_CONDITPOSTTRAINLEVEL 6 #define ABF2_EPISODESTARTTOSTART 7 #define ABF2_INACTIVEHOLDING 8 #define ABF2_DIGITALHOLDING 9 #define ABF2_PNNUMPULSES 10 #define ABF2_PARALLELVALUE 11 #define ABF2_EPOCHINITLEVEL (ABF2_PARALLELVALUE + ABF2_EPOCHCOUNT) #define ABF2_EPOCHINITDURATION (ABF2_EPOCHINITLEVEL + ABF2_EPOCHCOUNT) #define ABF2_EPOCHTRAINPERIOD (ABF2_EPOCHINITDURATION + ABF2_EPOCHCOUNT) #define ABF2_EPOCHTRAINPULSEWIDTH (ABF2_EPOCHTRAINPERIOD + ABF2_EPOCHCOUNT) // Next value is (ABF2_EPOCHINITDURATION + ABF2_EPOCHCOUNT) // Values for the nEraseStrategy field in ABFScopeConfig. #define ABF2_ERASE_EACHSWEEP 0 #define ABF2_ERASE_EACHRUN 1 #define ABF2_ERASE_EACHTRIAL 2 #define ABF2_ERASE_DONTERASE 3 // Indexes into the rgbColor field of ABFScopeConfig. #define ABF2_BACKGROUNDCOLOR 0 #define ABF2_GRIDCOLOR 1 #define ABF2_THRESHOLDCOLOR 2 #define ABF2_EVENTMARKERCOLOR 3 #define ABF2_SEPARATORCOLOR 4 #define ABF2_AVERAGECOLOR 5 #define ABF2_OLDDATACOLOR 6 #define ABF2_TEXTCOLOR 7 #define ABF2_AXISCOLOR 8 #define ABF2_ACTIVEAXISCOLOR 9 #define ABF2_LASTCOLOR ABF2_ACTIVEAXISCOLOR #define ABF2_SCOPECOLORS (ABF2_LASTCOLOR+1) // Extended colors for rgbColorEx field in ABFScopeConfig #define ABF2_STATISTICS_REGION0 0 #define ABF2_STATISTICS_REGION1 1 #define ABF2_STATISTICS_REGION2 2 #define ABF2_STATISTICS_REGION3 3 #define ABF2_STATISTICS_REGION4 4 #define ABF2_STATISTICS_REGION5 5 #define ABF2_STATISTICS_REGION6 6 #define ABF2_STATISTICS_REGION7 7 #define ABF2_BASELINE_REGION 8 #define ABF2_STOREDSWEEPCOLOR 9 #define ABF2_LASTCOLOR_EX ABF2_STOREDSWEEPCOLOR #define ABF2_SCOPECOLORS_EX (ABF2_LASTCOLOR+1) // // Constants for nCompressionType in the ABFVoiceTagInfo structure. // #define ABF2_COMPRESSION_NONE 0 #define ABF2_COMPRESSION_PKWARE 1 #define ABF2_CURRENTVERSION ABF2_V203 // Current file format version number // // Header Version Numbers // #define ABF2_V200 2.00F // Alpha versions of pCLAMP 10 and DataXpress 2 #define ABF2_V201 2.01F // DataXpress 2.0.0.16 and later // pCLAMP 10.0.0.6 and later #define ABF2_V202 2.02F // Barracuda 1.0 and later #define ABF2_V203 2.03F // pCLAMP 10.4.0.7 and later // Retired constants. #undef ABF2_AUTOANALYSE_RUNMACRO #undef ABF2_MACRONAMELEN // // pack structure on byte boundaries // #ifndef RC_INVOKED #pragma pack(push, 1) #endif // // Definition of the ABF header structure. // struct ABF2FileHeader { public: // GROUP #1 - File ID and size information float fFileVersionNumber; short nOperationMode; ABFLONG lActualAcqLength; short nNumPointsIgnored; ABFLONG lActualEpisodes; UINT uFileStartDate; // YYYYMMDD UINT uFileStartTimeMS; ABFLONG lStopwatchTime; float fHeaderVersionNumber; short nFileType; // GROUP #2 - File Structure ABFLONG lDataSectionPtr; ABFLONG lTagSectionPtr; ABFLONG lNumTagEntries; ABFLONG lScopeConfigPtr; ABFLONG lNumScopes; ABFLONG lDeltaArrayPtr; ABFLONG lNumDeltas; ABFLONG lVoiceTagPtr; ABFLONG lVoiceTagEntries; ABFLONG lSynchArrayPtr; ABFLONG lSynchArraySize; short nDataFormat; short nSimultaneousScan; ABFLONG lStatisticsConfigPtr; ABFLONG lAnnotationSectionPtr; ABFLONG lNumAnnotations; ABFLONG lDACFilePtr[ABF2_DACCOUNT]; ABFLONG lDACFileNumEpisodes[ABF2_DACCOUNT]; // GROUP #3 - Trial hierarchy information short nADCNumChannels; float fADCSequenceInterval; UINT uFileCompressionRatio; bool bEnableFileCompression; float fSynchTimeUnit; float fSecondsPerRun; ABFLONG lNumSamplesPerEpisode; ABFLONG lPreTriggerSamples; ABFLONG lEpisodesPerRun; ABFLONG lRunsPerTrial; ABFLONG lNumberOfTrials; short nAveragingMode; short nUndoRunCount; short nFirstEpisodeInRun; float fTriggerThreshold; short nTriggerSource; short nTriggerAction; short nTriggerPolarity; float fScopeOutputInterval; float fEpisodeStartToStart; float fRunStartToStart; float fTrialStartToStart; ABFLONG lAverageCount; short nAutoTriggerStrategy; float fFirstRunDelayS; // GROUP #4 - Display Parameters short nDataDisplayMode; short nChannelStatsStrategy; ABFLONG lSamplesPerTrace; ABFLONG lStartDisplayNum; ABFLONG lFinishDisplayNum; short nShowPNRawData; float fStatisticsPeriod; ABFLONG lStatisticsMeasurements; short nStatisticsSaveStrategy; // GROUP #5 - Hardware information float fADCRange; float fDACRange; ABFLONG lADCResolution; ABFLONG lDACResolution; short nDigitizerADCs; short nDigitizerDACs; short nDigitizerTotalDigitalOuts; short nDigitizerSynchDigitalOuts; short nDigitizerType; // GROUP #6 Environmental Information short nExperimentType; short nManualInfoStrategy; float fCellID1; float fCellID2; float fCellID3; char sProtocolPath[ABF2_PATHLEN]; char sCreatorInfo[ABF2_CREATORINFOLEN]; char sModifierInfo[ABF2_CREATORINFOLEN]; short nCommentsEnable; char sFileComment[ABF2_FILECOMMENTLEN]; short nTelegraphEnable[ABF2_ADCCOUNT]; short nTelegraphInstrument[ABF2_ADCCOUNT]; float fTelegraphAdditGain[ABF2_ADCCOUNT]; float fTelegraphFilter[ABF2_ADCCOUNT]; float fTelegraphMembraneCap[ABF2_ADCCOUNT]; float fTelegraphAccessResistance[ABF2_ADCCOUNT]; short nTelegraphMode[ABF2_ADCCOUNT]; short nTelegraphDACScaleFactorEnable[ABF2_DACCOUNT]; short nAutoAnalyseEnable; GUID FileGUID; float fInstrumentHoldingLevel[ABF2_DACCOUNT]; unsigned ABFLONG ulFileCRC; short nCRCEnable; // GROUP #7 - Multi-channel information short nSignalType; // why is this only single channel ? short nADCPtoLChannelMap[ABF2_ADCCOUNT]; short nADCSamplingSeq[ABF2_ADCCOUNT]; float fADCProgrammableGain[ABF2_ADCCOUNT]; float fADCDisplayAmplification[ABF2_ADCCOUNT]; float fADCDisplayOffset[ABF2_ADCCOUNT]; float fInstrumentScaleFactor[ABF2_ADCCOUNT]; float fInstrumentOffset[ABF2_ADCCOUNT]; float fSignalGain[ABF2_ADCCOUNT]; float fSignalOffset[ABF2_ADCCOUNT]; float fSignalLowpassFilter[ABF2_ADCCOUNT]; float fSignalHighpassFilter[ABF2_ADCCOUNT]; char nLowpassFilterType[ABF2_ADCCOUNT]; char nHighpassFilterType[ABF2_ADCCOUNT]; bool bHumFilterEnable[ABF2_ADCCOUNT]; char sADCChannelName[ABF2_ADCCOUNT][ABF2_ADCNAMELEN]; char sADCUnits[ABF2_ADCCOUNT][ABF2_ADCUNITLEN]; float fDACScaleFactor[ABF2_DACCOUNT]; float fDACHoldingLevel[ABF2_DACCOUNT]; float fDACCalibrationFactor[ABF2_DACCOUNT]; float fDACCalibrationOffset[ABF2_DACCOUNT]; char sDACChannelName[ABF2_DACCOUNT][ABF2_DACNAMELEN]; char sDACChannelUnits[ABF2_DACCOUNT][ABF2_DACUNITLEN]; // GROUP #9 - Epoch Waveform and Pulses short nDigitalEnable; short nActiveDACChannel; // should retire ! short nDigitalDACChannel; short nDigitalHolding; short nDigitalInterEpisode; short nDigitalTrainActiveLogic; short nDigitalValue[ABF2_EPOCHCOUNT]; short nDigitalTrainValue[ABF2_EPOCHCOUNT]; bool bEpochCompression[ABF2_EPOCHCOUNT]; short nWaveformEnable[ABF2_DACCOUNT]; short nWaveformSource[ABF2_DACCOUNT]; short nInterEpisodeLevel[ABF2_DACCOUNT]; short nEpochType[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; float fEpochInitLevel[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; float fEpochFinalLevel[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; // Only used for ABF_EPOCHSLOPE. float fEpochLevelInc[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; ABFLONG lEpochInitDuration[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; ABFLONG lEpochDurationInc[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; short nEpochTableRepetitions[ABF2_DACCOUNT]; float fEpochTableStartToStartInterval[ABF2_DACCOUNT]; // GROUP #10 - DAC Output File float fDACFileScale[ABF2_DACCOUNT]; float fDACFileOffset[ABF2_DACCOUNT]; ABFLONG lDACFileEpisodeNum[ABF2_DACCOUNT]; short nDACFileADCNum[ABF2_DACCOUNT]; char sDACFilePath[ABF2_DACCOUNT][ABF2_PATHLEN]; // GROUP #11a - Presweep (conditioning) pulse train short nConditEnable[ABF2_DACCOUNT]; ABFLONG lConditNumPulses[ABF2_DACCOUNT]; float fBaselineDuration[ABF2_DACCOUNT]; float fBaselineLevel[ABF2_DACCOUNT]; float fStepDuration[ABF2_DACCOUNT]; float fStepLevel[ABF2_DACCOUNT]; float fPostTrainPeriod[ABF2_DACCOUNT]; float fPostTrainLevel[ABF2_DACCOUNT]; float fCTStartLevel[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; float fCTEndLevel[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; float fCTIntervalDuration[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; float fCTStartToStartInterval[ABF2_DACCOUNT]; // GROUP #11b - Membrane Test Between Sweeps short nMembTestEnable[ABF2_DACCOUNT]; float fMembTestPreSettlingTimeMS[ABF2_DACCOUNT]; float fMembTestPostSettlingTimeMS[ABF2_DACCOUNT]; // GROUP #11c - PreSignal test pulse short nPreSignalEnable[ABF2_DACCOUNT]; float fPreSignalPreStepDuration[ABF2_DACCOUNT]; float fPreSignalPreStepLevel[ABF2_DACCOUNT]; float fPreSignalStepDuration[ABF2_DACCOUNT]; float fPreSignalStepLevel[ABF2_DACCOUNT]; float fPreSignalPostStepDuration[ABF2_DACCOUNT]; float fPreSignalPostStepLevel[ABF2_DACCOUNT]; // GROUP #12 - Variable parameter user list short nULEnable[ABF2_USERLISTCOUNT]; short nULParamToVary[ABF2_USERLISTCOUNT]; short nULRepeat[ABF2_USERLISTCOUNT]; char sULParamValueList[ABF2_USERLISTCOUNT][ABF2_USERLISTLEN]; // GROUP #13 - Statistics measurements short nStatsEnable; unsigned short nStatsActiveChannels; // Active stats channel bit flag unsigned short nStatsSearchRegionFlags; // Active stats region bit flag short nStatsSmoothing; short nStatsSmoothingEnable; short nStatsBaseline; short nStatsBaselineDAC; // If mode is epoch, then this holds the DAC ABFLONG lStatsBaselineStart; ABFLONG lStatsBaselineEnd; ABFLONG lStatsMeasurements[ABF2_STATS_REGIONS]; // Measurement bit flag for each region ABFLONG lStatsStart[ABF2_STATS_REGIONS]; ABFLONG lStatsEnd[ABF2_STATS_REGIONS]; short nRiseBottomPercentile[ABF2_STATS_REGIONS]; short nRiseTopPercentile[ABF2_STATS_REGIONS]; short nDecayBottomPercentile[ABF2_STATS_REGIONS]; short nDecayTopPercentile[ABF2_STATS_REGIONS]; short nStatsChannelPolarity[ABF2_ADCCOUNT]; short nStatsSearchMode[ABF2_STATS_REGIONS]; // Stats mode per region: mode is cursor region, epoch etc short nStatsSearchDAC[ABF2_STATS_REGIONS]; // If mode is epoch, then this holds the DAC // GROUP #14 - Channel Arithmetic short nArithmeticEnable; short nArithmeticExpression; float fArithmeticUpperLimit; float fArithmeticLowerLimit; short nArithmeticADCNumA; short nArithmeticADCNumB; float fArithmeticK1; float fArithmeticK2; float fArithmeticK3; float fArithmeticK4; float fArithmeticK5; float fArithmeticK6; char sArithmeticOperator[ABF2_ARITHMETICOPLEN]; char sArithmeticUnits[ABF2_ARITHMETICUNITSLEN]; // GROUP #15 - Leak subtraction short nPNPosition; short nPNNumPulses; short nPNPolarity; float fPNSettlingTime; float fPNInterpulse; short nLeakSubtractType[ABF2_DACCOUNT]; float fPNHoldingLevel[ABF2_DACCOUNT]; short nLeakSubtractADCIndex[ABF2_DACCOUNT]; // GROUP #16 - Miscellaneous variables short nLevelHysteresis; ABFLONG lTimeHysteresis; short nAllowExternalTags; short nAverageAlgorithm; float fAverageWeighting; short nUndoPromptStrategy; short nTrialTriggerSource; short nStatisticsDisplayStrategy; short nExternalTagType; ABFLONG lHeaderSize; short nStatisticsClearStrategy; short nEnableFirstLastHolding; // First & Last Holding are now optional. // GROUP #17 - Trains parameters ABFLONG lEpochPulsePeriod[ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; ABFLONG lEpochPulseWidth [ABF2_DACCOUNT][ABF2_EPOCHCOUNT]; // GROUP #18 - Application version data short nCreatorMajorVersion; short nCreatorMinorVersion; short nCreatorBugfixVersion; short nCreatorBuildVersion; short nModifierMajorVersion; short nModifierMinorVersion; short nModifierBugfixVersion; short nModifierBuildVersion; // GROUP #19 - LTP protocol short nLTPType; short nLTPUsageOfDAC[ABF2_DACCOUNT]; short nLTPPresynapticPulses[ABF2_DACCOUNT]; // GROUP #20 - Digidata 132x Trigger out flag short nScopeTriggerOut; // GROUP #22 - Alternating episodic mode short nAlternateDACOutputState; short nAlternateDigitalOutputState; short nAlternateDigitalValue[ABF2_EPOCHCOUNT]; short nAlternateDigitalTrainValue[ABF2_EPOCHCOUNT]; // GROUP #23 - Post-processing actions float fPostProcessLowpassFilter[ABF2_ADCCOUNT]; char nPostProcessLowpassFilterType[ABF2_ADCCOUNT]; // GROUP #24 - Legacy gear shift info float fLegacyADCSequenceInterval; float fLegacyADCSecondSequenceInterval; ABFLONG lLegacyClockChange; ABFLONG lLegacyNumSamplesPerEpisode; ABF2FileHeader(); }; inline ABF2FileHeader::ABF2FileHeader() { // Set everything to 0. memset( this, 0, sizeof(ABF2FileHeader) ); // Set critical parameters so we can determine the version. fFileVersionNumber = ABF2_CURRENTVERSION; fHeaderVersionNumber = ABF2_CURRENTVERSION; lHeaderSize = sizeof(ABF2FileHeader); } // // Scope descriptor format. // #define ABF2_FACESIZE 32 struct ABFLogFont { short nHeight; // Height of the font in pixels. // short lWidth; // use 0 // short lEscapement; // use 0 // short lOrientation; // use 0 short nWeight; // MSWindows font weight value. // char bItalic; // use 0 // char bUnderline; // use 0 // char bStrikeOut; // use 0 // char cCharSet; // use ANSI_CHARSET (0) // char cOutPrecision; // use OUT_TT_PRECIS // char cClipPrecision; // use CLIP_DEFAULT_PRECIS // char cQuality; // use PROOF_QUALITY char cPitchAndFamily; // MSWindows pitch and family mask. char Unused[3]; // Unused space to maintain 4-byte packing. char szFaceName[ABF2_FACESIZE];// Face name of the font. }; // Size = 40 struct ABFSignal { char szName[ABF2_ADCNAMELEN+2]; // ABF name length + '\0' + 1 for alignment. short nMxOffset; // Offset of the signal in the sampling sequence. DWORD rgbColor; // Pen color used to draw trace. char nPenWidth; // Pen width in pixels. char bDrawPoints; // TRUE = Draw disconnected points char bHidden; // TRUE = Hide the trace. char bFloatData; // TRUE = Floating point pseudo channel float fVertProportion; // Relative proportion of client area to use float fDisplayGain; // Display gain of trace in UserUnits float fDisplayOffset; // Display offset of trace in UserUnits // float fUUTop; // Top of window in UserUnits // float fUUBottom; // Bottom of window in UserUnits }; // Size = 34 struct ABFScopeConfig { // Section 1 scope configurations DWORD dwFlags; // Flags that are meaningful to the scope. DWORD rgbColor[ABF2_SCOPECOLORS]; // Colors for the components of the scope. float fDisplayStart; // Start of the display area in ms. float fDisplayEnd; // End of the display area in ms. WORD wScopeMode; // Mode that the scope is in. char bMaximized; // TRUE = Scope parent is maximized. char bMinimized; // TRUE = Scope parent is minimized. short xLeft; // Coordinate of the left edge. short yTop; // Coordinate of the top edge. short xRight; // Coordinate of the right edge. short yBottom; // Coordinate of the bottom edge. ABFLogFont LogFont; // Description of current font. ABFSignal TraceList[ABF2_ADCCOUNT]; // List of traces in current use. short nYAxisWidth; // Width of the YAxis region. short nTraceCount; // Number of traces described in TraceList. short nEraseStrategy; // Erase strategy. short nDockState; // Docked position. // Size 656 // * Do not insert any new members above this point! * // Section 2 scope configurations for file version 1.68. short nSizeofOldStructure; // Unused byte to determine the offset of the version 2 data. DWORD rgbColorEx[ ABF2_SCOPECOLORS_EX ]; // New color settings for stored sweep and cursors. short nAutoZeroState; // Status of the autozero selection. DWORD dwCursorsVisibleState; // Flag for visible status of cursors. DWORD dwCursorsLockedState; // Flag for enabled status of cursors. char sUnasigned[61]; // Size 113 ABFScopeConfig(); }; // Size = 769 inline ABFScopeConfig::ABFScopeConfig() { // Set everything to 0. memset( this, 0, sizeof(ABFScopeConfig) ); // Set critical parameters so we can determine the version. nSizeofOldStructure = 656; } // // Definition of the ABF Tag structure // struct ABFTag { ABFLONG lTagTime; // Time at which the tag was entered in fSynchTimeUnit units. char sComment[ABF2_TAGCOMMENTLEN]; // Optional tag comment. short nTagType; // Type of tag ABF2_TIMETAG, ABF2_COMMENTTAG, ABF2_EXTERNALTAG, ABF2_VOICETAG, ABF2_NEWFILETAG or ABF2_ANNOTATIONTAG union { short nVoiceTagNumber; // If nTagType=ABF2_VOICETAG, this is the number of this voice tag. short nAnnotationIndex; // If nTagType=ABF2_ANNOTATIONTAG, this is the index of the corresponding annotation. }; }; // Size = 64 // // Definition of the ABFVoiceTagInfo structure. // struct ABFVoiceTagInfo { ABFLONG lTagNumber; // The tag number that corresponds to this VoiceTag ABFLONG lFileOffset; // Offset to this tag within the VoiceTag block ABFLONG lUncompressedSize; // Size of the voice tag expanded. ABFLONG lCompressedSize; // Compressed size of the tag. short nCompressionType; // Compression method used. short nSampleSize; // Size of the samples acquired. ABFLONG lSamplesPerSecond; // Rate at which the sound was acquired. DWORD dwCRC; // CRC used to check data integrity. WORD wChannels; // Number of channels in the tag (usually 1). WORD wUnused; // Unused space. }; // Size 32 // // Definition of the ABF Delta structure. // struct ABFDelta { ABFLONG lDeltaTime; // Time at which the parameter was changed in fSynchTimeUnit units. ABFLONG lParameterID; // Identifier for the parameter changed union { ABFLONG lNewParamValue; // Depending on the value of lParameterID float fNewParamValue; // this entry may be either a float or a long. }; }; // Size = 12 // // Definition of the ABF synch array structure // struct ABF2Synch { ABFLONG lStart; // Start of the episode/event in fSynchTimeUnit units. ABFLONG lLength; // Length of the episode/event in multiplexed samples. }; // Size = 8 #ifndef RC_INVOKED #pragma pack(pop) // return to default packing #endif // ============================================================================================ // Function prototypes for functions in ABFHEADR.C // ============================================================================================ void WINAPI ABF2H_Initialize( ABF2FileHeader *pFH ); #if 0 void WINAPI ABF2H_InitializeScopeConfig(const ABF2FileHeader *pFH, ABFScopeConfig *pCfg); BOOL WINAPI ABF2H_CheckScopeConfig(const ABF2FileHeader *pFH, ABFScopeConfig *pCfg); void WINAPI ABF2H_GetADCDisplayRange( const ABF2FileHeader *pFH, int nChannel, float *pfUUTop, float *pfUUBottom); #endif void WINAPI ABF2H_GetADCtoUUFactors( const ABF2FileHeader *pFH, int nChannel, float *pfADCToUUFactor, float *pfADCToUUShift ); #if 0 void WINAPI ABF2H_ClipADCUUValue(const ABF2FileHeader *pFH, int nChannel, float *pfUUValue); void WINAPI ABF2H_GetDACtoUUFactors( const ABF2FileHeader *pFH, int nChannel, float *pfDACToUUFactor, float *pfDACToUUShift ); void WINAPI ABF2H_ClipDACUUValue(const ABF2FileHeader *pFH, int nChannel, float *pfUUValue); #endif BOOL WINAPI ABF2H_GetMathValue(const ABF2FileHeader *pFH, float fA, float fB, float *pfRval); #if 0 int WINAPI ABF2H_GetMathChannelName(LPSTR psz, UINT uLen); BOOL WINAPI ABF2H_ParamReader( HANDLE hFile, ABF2FileHeader *pFH, int *pnError ); BOOL WINAPI ABF2H_ParamWriter( HANDLE hFile, ABF2FileHeader *pFH, int *pnError ); BOOL WINAPI ABF2H_GetErrorText( int nError, char *pszBuffer, UINT nBufferSize ); BOOL WINAPI ABF2H_GetCreatorInfo(const ABF2FileHeader *pFH, char *pszName, UINT uNameSize, char *pszVersion, UINT uVersionSize); BOOL WINAPI ABF2H_GetModifierInfo(const ABF2FileHeader *pFH, char *pszName, UINT uNameSize, char *pszVersion, UINT uVersionSize); // ABF 1 conversion functions - use with care. struct ABF2FileHeader1; BOOL WINAPI ABF2H_ConvertFromABF1( const ABF2FileHeader1 *pIn, ABF2FileHeader *pOut, int *pnError ); BOOL WINAPI ABF2H_ConvertABF2ToABF1Header( const ABF2FileHeader *pNewFH, ABF2FileHeader1 *pOldFH, int *pnError ); // ABFHWAVE.CPP // Constants for ABF2H_GetEpochLimits #define ABF2H_FIRSTHOLDING -1 #define ABF2H_LASTHOLDING ABF2_EPOCHCOUNT // Return the bounds of a given epoch in a given episode. Values returned are ZERO relative. BOOL WINAPI ABF2H_GetEpochLimits(const ABF2FileHeader *pFH, int nADCChannel, UINT uDACChannel, DWORD dwEpisode, int nEpoch, UINT *puEpochStart, UINT *puEpochEnd, int *pnError); #endif // Get the offset in the sampling sequence for the given physical channel. BOOL WINAPI ABF2H_GetChannelOffset( const ABF2FileHeader *pFH, int nChannel, UINT *puChannelOffset ); // Gets the first sample interval, expressed as a double. double WINAPI ABF2H_GetFirstSampleInterval( const ABF2FileHeader *pFH ); #if 0 // This function forms the de-multiplexed DAC output waveform for the // particular channel in the pfBuffer, in DAC UserUnits. BOOL WINAPI ABF2H_GetWaveform( const ABF2FileHeader *pFH, UINT uDACChannel, DWORD dwEpisode, float *pfBuffer, int *pnError); // This function forms the de-multiplexed Digital output waveform for the // particular channel in the pdwBuffer, as a bit mask. Digital OUT 0 is in bit 0. BOOL WINAPI ABF2H_GetDigitalWaveform( const ABF2FileHeader *pFH, int nChannel, DWORD dwEpisode, DWORD *pdwBuffer, int *pnError); // Calculates the timebase array for the file. void WINAPI ABF2H_GetTimebase(const ABF2FileHeader *pFH, double dTimeOffset, double *pdBuffer, UINT uBufferSize); // Constant for ABF2H_GetHoldingDuration #define ABF2H_HOLDINGFRACTION 64 // Get the duration of the first holding period. UINT WINAPI ABF2H_GetHoldingDuration(const ABF2FileHeader *pFH); // Checks whether the waveform varies from episode to episode. BOOL WINAPI ABF2H_IsConstantWaveform(const ABF2FileHeader *pFH, UINT uDACChannel); // Get the full sweep length given the length available to epochs or vice-versa. int WINAPI ABF2H_SweepLenFromUserLen(int nUserLength, int nNumChannels); int WINAPI ABF2H_UserLenFromSweepLen(int nSweepLength, int nNumChannels); // Converts a display range to the equivalent gain and offset factors. void WINAPI ABF2H_GainOffsetToDisplayRange( const ABF2FileHeader *pFH, int nChannel, float fDisplayGain, float fDisplayOffset, float *pfUUTop, float *pfUUBottom); // Converts a display range to the equivalent gain and offset factors. void WINAPI ABF2H_DisplayRangeToGainOffset( const ABF2FileHeader *pFH, int nChannel, float fUUTop, float fUUBottom, float *pfDisplayGain, float *pfDisplayOffset); // Converts a time value to a synch time count or vice-versa. void WINAPI ABF2H_SynchCountToMS(const ABF2FileHeader *pFH, UINT uCount, double *pdTimeMS); UINT WINAPI ABF2H_MSToSynchCount(const ABF2FileHeader *pFH, double dTimeMS); // Gets the duration of the Waveform Episode (in us), allowing for split clock etc. void WINAPI ABF2H_GetEpisodeDuration(const ABF2FileHeader *pFH, double *pdEpisodeDuration); // Returns TRUE is P/N is enabled on any output channel. BOOL WINAPI ABF2H_IsPNEnabled(const ABF2FileHeader *pFH, UINT uDAC=ABF2_ANY_CHANNEL); // Gets the duration of a P/N sequence (in us), including settling times. void WINAPI ABF2H_GetPNDuration(const ABF2FileHeader *pFH, double *pdPNDuration); // Gets the duration of a pre-sweep train in us. void WINAPI ABF2H_GetTrainDuration (const ABF2FileHeader *pFH, UINT uDAC, double *pdTrainDuration); // Gets the duration of a post-train portion of the pre-sweep train in us. void WINAPI ABF2H_GetPostTrainDuration (const ABF2FileHeader *pFH, UINT uDAC, UINT uEpisode, double *pdDuration); // Gets the level of a post-train portion of the pre-sweep train. void WINAPI ABF2H_GetPostTrainLevel (const ABF2FileHeader *pFH, UINT uDAC, UINT uEpisode, double *pdLevel); // Gets the duration of a whole meta-episode (in us). void WINAPI ABF2H_GetMetaEpisodeDuration(const ABF2FileHeader *pFH, double *pdMetaEpisodeDuration); // Gets the start to start period for the episode in us. void WINAPI ABF2H_GetEpisodeStartToStart(const ABF2FileHeader *pFH, double *pdEpisodeStartToStart); // Checks that the user list contains valid entries for the protocol. BOOL WINAPI ABF2H_CheckUserList(const ABF2FileHeader *pFH, UINT uListNum, int *pnError); // Counts the number of changing sweeps. UINT WINAPI ABF2H_GetNumberOfChangingSweeps( const ABF2FileHeader *pFH ); // // Checks whether the digital output varies from episode to episode. BOOL WINAPI ABF2H_IsConstantDigitalOutput(const ABF2FileHeader *pFH, UINT uDACChannel); int WINAPI ABF2H_GetEpochDuration(const ABF2FileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch); float WINAPI ABF2H_GetEpochLevel(const ABF2FileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch); BOOL WINAPI ABF2H_GetEpochLevelRange(const ABF2FileHeader *pFH, UINT uDACChannel, int nEpoch, float *pfMin, float *pfMax); UINT WINAPI ABF2H_GetMaxPNSubsweeps(const ABF2FileHeader *pFH, UINT uDACChannel); #endif // // Error return values that may be returned by the ABF2H_xxx functions. // #define ABF2H_FIRSTERRORNUMBER 2001 #define ABF2H_EHEADERREAD 2001 #define ABF2H_EHEADERWRITE 2002 #define ABF2H_EINVALIDFILE 2003 #define ABF2H_EUNKNOWNFILETYPE 2004 #define ABF2H_CHANNELNOTSAMPLED 2005 #define ABF2H_EPOCHNOTPRESENT 2006 #define ABF2H_ENOWAVEFORM 2007 #define ABF2H_EDACFILEWAVEFORM 2008 #define ABF2H_ENOMEMORY 2009 #define ABF2H_BADSAMPLEINTERVAL 2010 #define ABF2H_BADSECONDSAMPLEINTERVAL 2011 #define ABF2H_BADSAMPLEINTERVALS 2012 #define ABF2H_ENOCONDITTRAINS 2013 #define ABF2H_EMETADURATION 2014 #define ABF2H_ECONDITNUMPULSES 2015 #define ABF2H_ECONDITBASEDUR 2016 #define ABF2H_ECONDITBASELEVEL 2017 #define ABF2H_ECONDITPOSTTRAINDUR 2018 #define ABF2H_ECONDITPOSTTRAINLEVEL 2019 #define ABF2H_ESTART2START 2020 #define ABF2H_EINACTIVEHOLDING 2021 #define ABF2H_EINVALIDCHARS 2022 #define ABF2H_ENODIG 2023 #define ABF2H_EDIGHOLDLEVEL 2024 #define ABF2H_ENOPNPULSES 2025 #define ABF2H_EPNNUMPULSES 2026 #define ABF2H_ENOEPOCH 2027 #define ABF2H_EEPOCHLEN 2028 #define ABF2H_EEPOCHINITLEVEL 2029 #define ABF2H_EDIGLEVEL 2030 #define ABF2H_ECONDITSTEPDUR 2031 #define ABF2H_ECONDITSTEPLEVEL 2032 #define ABF2H_EINVALIDBINARYCHARS 2033 #define ABF2H_EBADWAVEFORM 2034 #ifdef __cplusplus } #endif #endif /* INC_ABFHEADR2_H */ stimfit-0.16.7/src/libstfio/abf/axon2/SimpleStringCache.hpp0000664000175000017500000000254414750344764017230 //*********************************************************************************************** // // Copyright (c) 1999 - 2002 Axon Instruments, Inc. // All rights reserved. // //*********************************************************************************************** // MODULE: SimpleStringCache.HPP // PURPOSE: // AUTHOR: BHI Nov 1999 // PRC May 2002 // Simple String Cache class, based on StringCache.hpp / cpp // #ifndef INC_SIMPLESTRINGCACHE_HPP #define INC_SIMPLESTRINGCACHE_HPP #pragma once #include #pragma pack(push, 1) #pragma pack(pop) class CSimpleStringCache { private: // Attributes // Typedefs to simplify code. std::vector m_Cache; UINT m_uMaxSize; private: // Unimplemented copy functions. CSimpleStringCache(const CSimpleStringCache &); const CSimpleStringCache &operator=(const CSimpleStringCache &); public: // Public interface CSimpleStringCache(); ~CSimpleStringCache(); void Clear(); UINT Add(LPCSTR psz); LPCSTR Get(UINT uIndex) const; BOOL Write(HANDLE hFile, UINT &uOffset) const; BOOL Read(HANDLE hFile, UINT uOffset); UINT GetNumStrings() const; UINT GetMaxSize() const { return m_uMaxSize; }; UINT GetTotalSize() const; }; #endif // INC_SIMPLESTRINGCACHE_HPP stimfit-0.16.7/src/libstfio/abf/axon2/ProtocolStructs.h0000664000175000017500000002767314750344764016527 //*********************************************************************************************** // // Copyright (c) 1993-2005 Molecular Devices. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // // MODULE: ProtocolStructs.HPP // ABF structs: used to describe the actual file contents. // // Added 64bit support according to Jakub Nowacki's implementation in libaxon: // http://libaxon.sourceforge.net #ifndef INC_PROTOCOLSTRUCTS_HPP #define INC_PROTOCOLSTRUCTS_HPP #include "../axon/Common/axodebug.h" #include "../axon/AxAbfFio32/AxAbffio32.h" #include #pragma once #pragma pack(push, 1) // GUID is normally defined in the Windows Platform SDK #ifndef GUID_DEFINED #define GUID_DEFINED typedef struct _GUID { akxjsbasd unsigned ABFLONG Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } GUID; #endif /* GUID_DEFINED */ // All these structs are persisted to file -> their sizes must NOT be changed without careful // attention to versioning issues in order to maintain compatibility. struct ABF_Section { UINT uBlockIndex; // ABF block number of the first entry UINT uBytes; // size in bytes of of each entry long long llNumEntries; // number of entries in this section ABF_Section(); ABFLONG GetNumEntries(); void Set( const UINT p_uBlockIndex, const UINT p_uBytes, const long long p_llNumEntries ); }; #define MEMSET_CTOR inline ABF_Section::ABF_Section() { MEMSET_CTOR; } inline void ABF_Section::Set( const UINT p_uBlockIndex, const UINT p_uBytes, const long long p_llNumEntries ) { uBytes = 0; llNumEntries = 0; uBlockIndex = p_uBlockIndex; if( uBlockIndex ) { uBytes = p_uBytes; llNumEntries = p_llNumEntries; } } inline ABFLONG ABF_Section::GetNumEntries() { // If this assert goes off, then files longer than 2 gigasamples need to be handled. if( llNumEntries > LONG_MAX ) { std::cerr << "File contains" << (int)(llNumEntries / 1000000L) << "megasamples which exceeds current limit (" << (int)(LONG_MAX / 1000000L) << ")."; } return ABFLONG(llNumEntries); } #define ABF2_FILESIGNATURE 0x32464241 // PC="ABF2", MAC="2FBA" struct ABF2_FileInfo { UINT uFileSignature; UINT uFileVersionNumber; // After this point there is no need to be the same as the ABF 1 equivalent. UINT uFileInfoSize; UINT uActualEpisodes; UINT uFileStartDate; UINT uFileStartTimeMS; UINT uStopwatchTime; short nFileType; short nDataFormat; short nSimultaneousScan; short nCRCEnable; UINT uFileCRC; GUID FileGUID; UINT uCreatorVersion; UINT uCreatorNameIndex; UINT uModifierVersion; UINT uModifierNameIndex; UINT uProtocolPathIndex; // New sections in ABF 2 - protocol stuff ... ABF_Section ProtocolSection; // the protocol ABF_Section ADCSection; // one for each ADC channel ABF_Section DACSection; // one for each DAC channel ABF_Section EpochSection; // one for each epoch ABF_Section ADCPerDACSection; // one for each ADC for each DAC ABF_Section EpochPerDACSection; // one for each epoch for each DAC ABF_Section UserListSection; // one for each user list ABF_Section StatsRegionSection; // one for each stats region ABF_Section MathSection; ABF_Section StringsSection; // ABF 1 sections ... ABF_Section DataSection; // Data ABF_Section TagSection; // Tags ABF_Section ScopeSection; // Scope config ABF_Section DeltaSection; // Deltas ABF_Section VoiceTagSection; // Voice Tags ABF_Section SynchArraySection; // Synch Array ABF_Section AnnotationSection; // Annotations ABF_Section StatsSection; // Stats config char sUnused[148]; // size = 512 bytes ABF2_FileInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF2_FileInfo ) == 512 ); uFileSignature = ABF2_FILESIGNATURE; uFileInfoSize = sizeof( ABF2_FileInfo); } }; struct ABF_ProtocolInfo { short nOperationMode; float fADCSequenceInterval; bool bEnableFileCompression; char sUnused1[3]; UINT uFileCompressionRatio; float fSynchTimeUnit; float fSecondsPerRun; ABFLONG lNumSamplesPerEpisode; ABFLONG lPreTriggerSamples; ABFLONG lEpisodesPerRun; ABFLONG lRunsPerTrial; ABFLONG lNumberOfTrials; short nAveragingMode; short nUndoRunCount; short nFirstEpisodeInRun; float fTriggerThreshold; short nTriggerSource; short nTriggerAction; short nTriggerPolarity; float fScopeOutputInterval; float fEpisodeStartToStart; float fRunStartToStart; ABFLONG lAverageCount; float fTrialStartToStart; short nAutoTriggerStrategy; float fFirstRunDelayS; short nChannelStatsStrategy; ABFLONG lSamplesPerTrace; ABFLONG lStartDisplayNum; ABFLONG lFinishDisplayNum; short nShowPNRawData; float fStatisticsPeriod; ABFLONG lStatisticsMeasurements; short nStatisticsSaveStrategy; float fADCRange; float fDACRange; ABFLONG lADCResolution; ABFLONG lDACResolution; short nExperimentType; short nManualInfoStrategy; short nCommentsEnable; ABFLONG lFileCommentIndex; short nAutoAnalyseEnable; short nSignalType; short nDigitalEnable; short nActiveDACChannel; short nDigitalHolding; short nDigitalInterEpisode; short nDigitalDACChannel; short nDigitalTrainActiveLogic; short nStatsEnable; short nStatisticsClearStrategy; short nLevelHysteresis; ABFLONG lTimeHysteresis; short nAllowExternalTags; short nAverageAlgorithm; float fAverageWeighting; short nUndoPromptStrategy; short nTrialTriggerSource; short nStatisticsDisplayStrategy; short nExternalTagType; short nScopeTriggerOut; short nLTPType; short nAlternateDACOutputState; short nAlternateDigitalOutputState; float fCellID[3]; short nDigitizerADCs; short nDigitizerDACs; short nDigitizerTotalDigitalOuts; short nDigitizerSynchDigitalOuts; short nDigitizerType; char sUnused[304]; // size = 512 bytes ABF_ProtocolInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF_ProtocolInfo ) == 512 ); } }; struct ABF_MathInfo { short nMathEnable; short nMathExpression; UINT uMathOperatorIndex; UINT uMathUnitsIndex; float fMathUpperLimit; float fMathLowerLimit; short nMathADCNum[2]; char sUnused[16]; float fMathK[6]; char sUnused2[64]; // size = 128 bytes ABF_MathInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF_MathInfo ) == 128 ); } }; struct ABF_ADCInfo { // The ADC this struct is describing. short nADCNum; short nTelegraphEnable; short nTelegraphInstrument; float fTelegraphAdditGain; float fTelegraphFilter; float fTelegraphMembraneCap; short nTelegraphMode; float fTelegraphAccessResistance; short nADCPtoLChannelMap; short nADCSamplingSeq; float fADCProgrammableGain; float fADCDisplayAmplification; float fADCDisplayOffset; float fInstrumentScaleFactor; float fInstrumentOffset; float fSignalGain; float fSignalOffset; float fSignalLowpassFilter; float fSignalHighpassFilter; char nLowpassFilterType; char nHighpassFilterType; float fPostProcessLowpassFilter; char nPostProcessLowpassFilterType; bool bEnabledDuringPN; short nStatsChannelPolarity; ABFLONG lADCChannelNameIndex; ABFLONG lADCUnitsIndex; char sUnused[46]; // size = 128 bytes ABF_ADCInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF_ADCInfo ) == 128 ); } }; struct ABF_DACInfo { // The DAC this struct is describing. short nDACNum; short nTelegraphDACScaleFactorEnable; float fInstrumentHoldingLevel; float fDACScaleFactor; float fDACHoldingLevel; float fDACCalibrationFactor; float fDACCalibrationOffset; ABFLONG lDACChannelNameIndex; ABFLONG lDACChannelUnitsIndex; ABFLONG lDACFilePtr; ABFLONG lDACFileNumEpisodes; short nWaveformEnable; short nWaveformSource; short nInterEpisodeLevel; float fDACFileScale; float fDACFileOffset; ABFLONG lDACFileEpisodeNum; short nDACFileADCNum; short nConditEnable; ABFLONG lConditNumPulses; float fBaselineDuration; float fBaselineLevel; float fStepDuration; float fStepLevel; float fPostTrainPeriod; float fPostTrainLevel; short nMembTestEnable; short nLeakSubtractType; short nPNPolarity; float fPNHoldingLevel; short nPNNumADCChannels; short nPNPosition; short nPNNumPulses; float fPNSettlingTime; float fPNInterpulse; short nLTPUsageOfDAC; short nLTPPresynapticPulses; ABFLONG lDACFilePathIndex; float fMembTestPreSettlingTimeMS; float fMembTestPostSettlingTimeMS; short nLeakSubtractADCIndex; char sUnused[124]; // size = 256 bytes ABF_DACInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF_DACInfo ) == 256 ); } }; struct ABF_EpochInfoPerDAC { // The Epoch / DAC this struct is describing. short nEpochNum; short nDACNum; // One full set of epochs (ABF_EPOCHCOUNT) for each DAC channel ... short nEpochType; float fEpochInitLevel; float fEpochLevelInc; ABFLONG lEpochInitDuration; ABFLONG lEpochDurationInc; ABFLONG lEpochPulsePeriod; ABFLONG lEpochPulseWidth; char sUnused[18]; // size = 48 bytes ABF_EpochInfoPerDAC() { MEMSET_CTOR; ASSERT( sizeof( ABF_EpochInfoPerDAC ) == 48 ); } }; struct ABF_EpochInfo { // The Epoch this struct is describing. short nEpochNum; // Describes one epoch short nDigitalValue; short nDigitalTrainValue; short nAlternateDigitalValue; short nAlternateDigitalTrainValue; bool bEpochCompression; // Compress the data from this epoch using uFileCompressionRatio char sUnused[21]; // size = 32 bytes ABF_EpochInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF_EpochInfo ) == 32 ); } }; struct ABF_StatsRegionInfo { // The stats region this struct is describing. short nRegionNum; short nADCNum; short nStatsActiveChannels; short nStatsSearchRegionFlags; short nStatsSelectedRegion; short nStatsSmoothing; short nStatsSmoothingEnable; short nStatsBaseline; ABFLONG lStatsBaselineStart; ABFLONG lStatsBaselineEnd; // Describes one stats region ABFLONG lStatsMeasurements; ABFLONG lStatsStart; ABFLONG lStatsEnd; short nRiseBottomPercentile; short nRiseTopPercentile; short nDecayBottomPercentile; short nDecayTopPercentile; short nStatsSearchMode; short nStatsSearchDAC; short nStatsBaselineDAC; char sUnused[78]; // size = 128 bytes ABF_StatsRegionInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF_StatsRegionInfo ) == 128 ); } }; struct ABF_UserListInfo { // The user list this struct is describing. short nListNum; // Describes one user list short nULEnable; short nULParamToVary; short nULRepeat; ABFLONG lULParamValueListIndex; char sUnused[52]; // size = 64 bytes ABF_UserListInfo() { MEMSET_CTOR; ASSERT( sizeof( ABF_UserListInfo ) == 64 ); } }; #pragma pack(pop) // return to default packing #endif // INC_PROTOCOLSTRUCTS_HPP stimfit-0.16.7/src/libstfio/abf/axon2/SimpleStringCache.cpp0000664000175000017500000001766414750344764017234 //*********************************************************************************************** // // Copyright (c) 1999 - 2002 Axon Instruments, Inc. // All rights reserved. // //*********************************************************************************************** // MODULE: SimpleStringCache.CPP // PURPOSE: Cache of strings stored in a vector. // AUTHOR: BHI Nov 1999 // PRC May 2002 // #include "../axon/Common/wincpp.hpp" #include "SimpleStringCache.hpp" #include "../axon/Common/ArrayPtr.hpp" #include "../axon/Common/FileIO.hpp" #if defined(_WINDOWS) && !defined(__MINGW32__) #pragma warning(disable : 4201) #include #endif #include "../axon/Common/FileIO.hpp" #include #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) const DWORD c_dwSIGNATURE = MAKEFOURCC('S','S','C','H'); // Simple String Cache Header const DWORD c_dwCURRENT_VERSION = MAKEFOURCC(1,0,0,0); // 1.0.0.0 #if !defined(_WINDOWS) || defined(__MINGW32__) || defined(__STF__) #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif struct SimpleStringCacheHeader { DWORD dwSignature; DWORD dwVersion; UINT uNumStrings; UINT uMaxSize; ABFLONG lTotalBytes; UINT uUnused[6]; SimpleStringCacheHeader() { memset(this, 0, sizeof(*this)); dwSignature = c_dwSIGNATURE; dwVersion = c_dwCURRENT_VERSION; } }; #if 0 //#define SHOW_STRUCT_SIZES #ifdef SHOW_STRUCT_SIZES AXODBG_SHOW_SIZE(SimpleStringCacheHeader); #else ASSERT( sizeof(SimpleStringCacheHeader) == 44 ); #endif #endif //############################################################################################### //############################################################################################### //############################################################################################### //############################################################################################### //=============================================================================================== // FUNCTION: Constructor // PURPOSE: Object initialization. // CSimpleStringCache::CSimpleStringCache() { MEMBERASSERT(); m_uMaxSize = 0; } //=============================================================================================== // FUNCTION: Destructor // PURPOSE: Object cleanup. // CSimpleStringCache::~CSimpleStringCache() { MEMBERASSERT(); Clear(); } //=============================================================================================== // FUNCTION: Clear // PURPOSE: Clear the cache. // void CSimpleStringCache::Clear() { MEMBERASSERT(); // Delete the strings. for( UINT i=0; i( m_Cache[i] ); delete pszItem; pszItem = NULL; } // Now clear the vector m_Cache.clear(); } //=============================================================================================== // FUNCTION: Add // PURPOSE: Add a new string into the cache. // UINT CSimpleStringCache::Add(LPCSTR psz) { MEMBERASSERT(); std::size_t uLen = strlen(psz); LPSTR pszText = new char[uLen+1]; strcpy( pszText, psz ); m_Cache.push_back( pszText ); m_uMaxSize = max( m_uMaxSize, uLen ); return GetNumStrings(); } //=============================================================================================== // FUNCTION: Get // PURPOSE: Get the string pointer that corresponds to the index. // LPCSTR CSimpleStringCache::Get(UINT uIndex) const { MEMBERASSERT(); if( uIndex < m_Cache.size() ) { LPCSTR pszText = m_Cache[uIndex]; return pszText; } #ifndef __APPLE__ std::cerr << "Bad index passed to CSimpleStringCache (" << uIndex << ")"; #endif return NULL; } //=============================================================================================== // FUNCTION: GetTotalSize // PURPOSE: Returns to total size (in bytes) required to write out all the strings (including the header). // UINT CSimpleStringCache::GetTotalSize() const { MEMBERASSERT(); UINT uSize = sizeof(SimpleStringCacheHeader); for( std::size_t i=0; i pszBuffer( Header.lTotalBytes ); if( !File.Read( pszBuffer, Header.lTotalBytes ) ) return false; // Copy each string into the cache. LPCSTR pszText = pszBuffer; for (UINT i=0; iszSeparator[0] = s_szDelimiter[0]; *ppATF = g_FileDescriptor[nFile] = pATF; *pnFile = nFile; return TRUE; } //----------------------------------------------------------------------------------------------- // FUNCTION: GetFileDescriptor // PURPOSE: Retreive an existing file descriptor. // static BOOL GetFileDescriptor(ATF_FILEINFO **ppATF, int nFile, int *pnError) { WPTRASSERT(ppATF); // Check that index is within range. if ((nFile < 0) || (nFile >= ATF_MAXFILES)) ERRORRETURN(pnError, ATF_ERROR_BADFILENUM); // Get a pointer to the descriptor. ATF_FILEINFO *pATF = g_FileDescriptor[nFile]; if (pATF == NULL) ERRORRETURN(pnError, ATF_ERROR_BADSTATE); // Return the descriptor. *ppATF = pATF; return TRUE; } //=============================================================================================== // FUNCTION: AllocIOBuffer // PURPOSE: Allocate an IOBuffer for this file. // static BOOL AllocIOBuffer(ATF_FILEINFO *pATF) { WPTRASSERT(pATF); pATF->nIOBufferSize = pATF->nColumns * ATF_AVCOLUMNSIZE; if (pATF->nIOBufferSize < ATF_MINBUFSIZE) pATF->nIOBufferSize = ATF_MINBUFSIZE; pATF->pszIOBuffer = (char *)calloc(pATF->nIOBufferSize, sizeof(char)); if (pATF->pszIOBuffer == NULL) { pATF->nIOBufferSize = 0; return FALSE; } return TRUE; } //=============================================================================================== // FUNCTION: FreeIOBuffer // PURPOSE: Free the IO buffer used by this file. // static void FreeIOBuffer(ATF_FILEINFO *pATF) { WPTRASSERT(pATF); if (pATF->pszIOBuffer != NULL) free(pATF->pszIOBuffer); pATF->pszIOBuffer = NULL; pATF->nIOBufferSize = 0; } //============================================================================================== // FUNCTION: strncpyz // PURPOSE: Does a strncpy but guarantees that a terminating zero is placed on the // destination string. // RETURNS: The destination buffer. // static LPSTR strncpyz(LPSTR pszDest, LPCSTR pszSrce, UINT uBufSize) { ARRAYASSERT(pszDest, uBufSize); #if 0 LPSZASSERT(pszSrce); #endif strncpy(pszDest, pszSrce, uBufSize-1); pszDest[uBufSize-1] = '\0'; return pszDest; } //=============================================================================================== // FUNCTION: GetNumber // PURPOSE: Parse the next double out of the buffer, skipping delimeters etc. // static char *GetNumber(char *psBuf, double *pdNum) { #if 0 LPSZASSERT(psBuf); #endif // Skip space characters to get the start of the number char *ps = psBuf; while (*ps==' ') ++ps; // Save a pointer to the start of the number. char *psStart = ps; // search for the end of this token while (*ps && !strchr(s_szWhitespace, *ps)) ++ps; // skip trailing spaces. while (*ps==' ') ++ps; // Null terminate the string (knocking out the next delimiter) and step past the null if not end of line. if (*ps && !strchr(s_szLineTerm, *ps)) *ps++ = '\0'; else *ps = '\0'; if (pdNum) { WPTRASSERT(pdNum); *pdNum = atof(psStart); } return ps; } //=============================================================================================== // FUNCTION: GetVersion // PURPOSE: Parse the version number out of the data stream and check it against acceptable // values. // static BOOL GetVersion(char *psBuf, double *pdATFVersion, int *pnError) { #if 0 LPSZASSERT(psBuf); #endif WPTRASSERT(pdATFVersion); double dNum = 0; if (strlen(psBuf) < 5) ERRORRETURN(pnError, ATF_ERROR_INVALIDFILE); // Skip leading whitespace. char *psz = psBuf+FILE_ID_LEN; while (*psz && strchr(s_szWhitespace, *psz)) psz++; GetNumber(psz, &dNum); if (strncmp(psBuf, ATF_FILE_ID, FILE_ID_LEN) == 0) { if ((dNum > ATF_CURRENTVERSION) || (dNum==0.0)) ERRORRETURN(pnError, ATF_ERROR_BADVERSION); // File is an ATF file *pdATFVersion = dNum; } else if (strncmp(psBuf, PAF_FILE_ID, FILE_ID_LEN) == 0) { if (dNum != PREVIOUS_PAF_VERSION) ERRORRETURN(pnError, ATF_ERROR_BADVERSION); // Previous PAF V5.0 files are supported as ATF V0.0 *pdATFVersion = 0.0; } else ERRORRETURN(pnError, ATF_ERROR_INVALIDFILE); return TRUE; } //=============================================================================================== // FUNCTION: CleanupMem // PURPOSE: Frees strings that have been strdup'ed into the array. // static void CleanupMem(char **ppsz, int nItems) { if (!ppsz) return; while (nItems--) { if (*ppsz) free(*ppsz); ppsz++; } } //============================================================================================== // FUNCTION: StripSpaces // PURPOSE: Strips space characters out of the start and end of the passed string. // NOTES: This routine is DESTRUCTIVE in that it replaces any trailing spaces with '\0's. // It contains its own static definition of whitespace, not that it does not // include ','. // RETURNS: Pointer to the first non-white-space character. // static LPSTR StripSpaces(LPSTR pszSource) { // Garbage in == garbage out. if (!pszSource) return pszSource; // Characters that are regarded as white space. static const char szWhiteSpace[] = " \t\r\n"; #if 0 LPSZASSERT(pszSource); #endif // Strip leading white space. char *pszFirstChar = pszSource + strspn(pszSource, szWhiteSpace); // If nothing left, return. if (*pszFirstChar=='\0') { pszSource[0] = '\0'; return pszSource; } // Strip trailing white space. char *pszLastChar = pszFirstChar + strlen(pszFirstChar) - 1; while (pszLastChar > pszFirstChar) { if (strchr(szWhiteSpace, *pszLastChar) == NULL) break; *pszLastChar-- = '\0'; } // Move the sub-string to the start of the source string. if (pszFirstChar > pszSource) memmove(pszSource, pszFirstChar, strlen(pszFirstChar)+1); return pszSource; } //=============================================================================================== // FUNCTION: FixColumnTitles // PURPOSE: This function reads PAF V5.0 (ATF 0.0) headings. // static BOOL FixColumnTitles(int nColumns, ATF_FILEINFO *pATF) { WPTRASSERT(pATF); char *ps = pATF->pszIOBuffer; char *psEnd = pATF->pszIOBuffer + pATF->nIOBufferSize; for (int i=0; i= psEnd) // return an error if past end of buffer. return FALSE; } // Save the start of the title. char *psStart = ps; // Search for the end of the title. while ((*ps!='"') && (*ps!='\t')) { ++ps; if (ps >= psEnd) // return an error if past end of buffer. return FALSE; } *ps++ = '\0'; #if !defined(_WINDOWS) || defined(__MINGW32__) pATF->apszFileColTitles[i] = strdup(StripSpaces(psStart)); #else pATF->apszFileColTitles[i] = _strdup(StripSpaces(psStart)); #endif if (pATF->apszFileColTitles[i] == NULL) return FALSE; } return TRUE; } //=============================================================================================== // FUNCTION: FixColumnUnits // PURPOSE: This function reads PAF V5.0 (ATF 0.0) headings. // static BOOL FixColumnUnits(int nColumns, ATF_FILEINFO *pATF) { WPTRASSERT(pATF); char *ps = pATF->pszIOBuffer; char *psEnd = pATF->pszIOBuffer + pATF->nIOBufferSize; for (int i=0; i= psEnd) // return an error if past end of buffer. return FALSE; } // Save the start of the units char *psStart = ps; // Search for the end of the units. while ((*ps!='"') && (*ps!='\t')) { ++ps; if (ps >= psEnd) // return an error if past end of buffer. return FALSE; } *ps++ = '\0'; #if !defined(_WINDOWS) || defined(__MINGW32__) pATF->apszFileColUnits[i] = strdup(StripSpaces(psStart)); #else pATF->apszFileColUnits[i] = _strdup(StripSpaces(psStart)); #endif if (pATF->apszFileColUnits[i] == NULL) return FALSE; } return TRUE; } //=============================================================================================== // FUNCTION: FixColumnHeadings // PURPOSE: Store away the column headings and the column units strings for ATF files. // static BOOL FixColumnHeadings(int nColumns, ATF_FILEINFO *pATF) { WPTRASSERT(pATF); char *ps = pATF->pszIOBuffer; char *psEnd = pATF->pszIOBuffer + pATF->nIOBufferSize; for (int i=0; i= psEnd) // return an error if past end of buffer. return FALSE; } if (*ps=='"') { bDoubleQuote = TRUE; ++ps; } // Save the start of the title char *psStart = ps; for (; *ps && !strchr(s_szWhiteNoSpace, *ps); ++ps) { if (ps >= psEnd) // return an error if past end of buffer. return FALSE; if (bDoubleQuote && (*ps=='"')) break; if (*ps == '(') { if (*(ps-1) == ' ') *(ps-1) = '\0'; bUnits = TRUE; break; } } *ps++ = '\0'; #if !defined(_WINDOWS) || defined(__MINGW32__) pATF->apszFileColTitles[i] = strdup(StripSpaces(psStart)); #else pATF->apszFileColTitles[i] = _strdup(StripSpaces(psStart)); #endif if (pATF->apszFileColTitles[i] == NULL) return FALSE; if (bUnits) { psStart = ps; while (!strchr(s_szDelimiter, *ps) && (*ps!=')')) { if (bDoubleQuote && (*ps=='"')) { bDoubleQuote = FALSE; break; } ++ps; if (ps >= psEnd) // return an error if past end of buffer. return FALSE; } *ps++ = '\0'; #if !defined(_WINDOWS) || defined(__MINGW32__) pATF->apszFileColUnits[i] = strdup(StripSpaces(psStart)); #else pATF->apszFileColUnits[i] = _strdup(StripSpaces(psStart)); #endif if (pATF->apszFileColUnits[i] == NULL) return FALSE; if (bDoubleQuote) { while (*ps && (*ps!='"')) ps++; *ps++ = '\0'; } } } return TRUE; } //=============================================================================================== // FUNCTION: ReadLine // PURPOSE: This function masks gets and processes error conditions // static BOOL ReadLine(ATF_FILEINFO *pATF, int nEOFError, int *pnError) { WPTRASSERT(pATF); char *pszIOBuffer = pATF->pszIOBuffer; int nReturn = getsBuf(pATF, pszIOBuffer, pATF->nIOBufferSize); if (nReturn == GETS_EOF) ERRORRETURN(pnError, nEOFError); if (nReturn == GETS_ERROR) ERRORRETURN(pnError, ATF_ERROR_IOERROR); if (nReturn == GETS_NOEOL) ERRORRETURN(pnError, ATF_ERROR_LINETOOLONG); if (pszIOBuffer[0] == ENDOFFILE) pszIOBuffer[0] = '\0'; return TRUE; } //=============================================================================================== // FUNCTION: ReadHeaderInfo // PURPOSE: Reads the header information out of the file and stores it away in the file // descriptor. // static BOOL ReadHeaderInfo(ATF_FILEINFO *pATF, int *pnColumns, int *pnError) { WPTRASSERT(pnColumns); char szReadBuf[128]; double dATFVersion, dNum; int nHeaders, nColumns, i; long lCurrentPos; // Check if the version number is suported if (getsBuf(pATF, szReadBuf, sizeof(szReadBuf))) ERRORRETURN(pnError, ATF_ERROR_INVALIDFILE); if (!GetVersion(szReadBuf, &dATFVersion, pnError)) return FALSE; // Read in the number of header records and the number of columns of data // in the file if (getsBuf(pATF, szReadBuf, sizeof(szReadBuf))) ERRORRETURN(pnError, ATF_ERROR_BADHEADER); if (dATFVersion == 0.0) { // Read number of headers and columns as in previous (PAF 5.0) version GetNumber(szReadBuf, &dNum); nHeaders = (int)dNum; if (getsBuf(pATF, szReadBuf, sizeof(szReadBuf))) ERRORRETURN(pnError, ATF_ERROR_BADHEADER); GetNumber(szReadBuf, &dNum); nColumns = (int)dNum; } else { // Parse out first number (Headers) char *ps = GetNumber(szReadBuf, &dNum); nHeaders = (int)dNum; // Parse out second number (Columns) GetNumber(ps, &dNum); nColumns = (int)dNum; } if (nHeaders < 0) nHeaders = 0; if (nColumns < 0) nColumns = 0; // Return the number of columns to the user if a pointer was passed in if (pnColumns) *pnColumns = nColumns; if (nColumns > ATF_MAXCOLUMNS) ERRORRETURN(pnError, ATF_ERROR_TOOMANYCOLS); // Save the various pieces of information about this file // pATF->hFile = hFile; // now set in _CreateFileBuf pATF->nHeaders = nHeaders; pATF->nColumns = nColumns; pATF->eState = eOPENED; pATF->bWriting = FALSE; pATF->dFileVersion = dATFVersion; if (!AllocIOBuffer(pATF)) ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); // Now save the current position and skip the header records and get the // column title and unit strings lCurrentPos = SetFilePointerBuf(pATF, 0, NULL, FILE_CURRENT); for (i=0; iapszFileColTitles = (char **)calloc(nColumns, sizeof(char *)); if (pATF->apszFileColTitles == NULL) ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); pATF->apszFileColUnits = (char **)calloc(nColumns, sizeof(char *)); if (pATF->apszFileColUnits == NULL) { free(pATF->apszFileColTitles); pATF->apszFileColTitles = NULL; ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); } if (!ReadLine(pATF, ATF_ERROR_BADHEADER, pnError)) return FALSE; if (dATFVersion == 0.0) { if (!FixColumnTitles(nColumns, pATF)) { CleanupMem(pATF->apszFileColTitles, nColumns); ERRORRETURN(pnError, ATF_ERROR_BADHEADER); } if (!ReadLine(pATF, ATF_ERROR_BADHEADER, pnError)) { CleanupMem(pATF->apszFileColTitles, nColumns); return FALSE; } if (!FixColumnUnits(nColumns, pATF)) { CleanupMem(pATF->apszFileColTitles, nColumns); CleanupMem(pATF->apszFileColUnits, nColumns); ERRORRETURN(pnError, ATF_ERROR_BADHEADER); } } else if (!FixColumnHeadings(nColumns, pATF)) { CleanupMem(pATF->apszFileColTitles, nColumns); CleanupMem(pATF->apszFileColUnits, nColumns); ERRORRETURN(pnError, ATF_ERROR_BADHEADER); } // Return to the saved position SetFilePointerBuf(pATF, lCurrentPos, NULL, FILE_BEGIN); return TRUE; } //=============================================================================================== // FUNCTION: WriteHeaderInfo // PURPOSE: Write the first compulsory header lines out to the file. // static BOOL WriteHeaderInfo(ATF_FILEINFO *pATF, int nColumns, int *pnError) { // Writing a new file; Setup any necessary info pATF->dFileVersion = ATF_CURRENTVERSION; pATF->eState = eOPENED; pATF->bWriting = TRUE; pATF->bDataOnLine = FALSE; pATF->nHeaders = 0; pATF->nColumns = nColumns; // Allocate / re-allocate the IOBuffer. if (!AllocIOBuffer(pATF)) ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); // Allocate space to hold column titles and units. pATF->apszFileColTitles = (char **)calloc(nColumns, sizeof(char *)); if (pATF->apszFileColTitles == NULL) ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); pATF->apszFileColUnits = (char **)calloc(nColumns, sizeof(char *)); if (pATF->apszFileColUnits == NULL) { free(pATF->apszFileColTitles); pATF->apszFileColTitles = NULL; ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); } if (pATF->uFlags & ATF_DONTWRITEHEADER) { pATF->lFilePos = 0; return TRUE; } // Write the special marker string and the file version number char *pszIOBuffer = pATF->pszIOBuffer; snprintf(pszIOBuffer, sizeof(pszIOBuffer), "%s%s%.1f%s", ATF_FILE_ID, pATF->szSeparator, ATF_CURRENTVERSION, s_szEndOfLine); if (!putsBuf(pATF, pszIOBuffer)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); // Save the current position so that we may update the number of header records pATF->lFilePos = SetFilePointerBuf(pATF, 0, NULL, FILE_CURRENT); // Write the number of headers and columns that will be written, leaving // enough trailing spaces for 4 digits of headers (more than enough) snprintf(pszIOBuffer, sizeof(pszIOBuffer), "0%s%d %s", pATF->szSeparator, nColumns, s_szEndOfLine); if (!putsBuf(pATF, pszIOBuffer)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); return TRUE; } //=============================================================================================== // FUNCTION: _FormatNumber // PURPOSE: Formats the digits of dNum into pszString, suppressing trailing zeros. // In the event that "0." is produced as output from gcvt, truncate to "0" // // RETURNS: TRUE if success; FALSE if failure // #ifdef _WINDOWS // #include "..\AxonValidation\AxonValidation.h" // for VAL_* functions (standard Axon float/double->string formatting) #endif static BOOL _FormatNumber(double dNum, int nDigits, char *pszString, UINT uSize) { ARRAYASSERT(pszString, uSize); #if !defined(_WINDOWS) || defined(__MINGW32__) snprintf(pszString, sizeof(pszString), "%.*g", nDigits, dNum); // char* res = gcvt(dNum, nDigits, pszString); #else _gcvt(dNum, nDigits, pszString); #endif int l = (int)strlen(pszString); if ((l > 0) && (pszString[l-1]=='.')) pszString[l-1] = '\0'; return TRUE; /* #else return VAL_ConvertDblToStr(dNum, pszString, uSize, VAL_FMT_SIG_DIGITS, 0, nDigits, NULL); #endif */ } //=============================================================================================== // FUNCTION: ATF_OpenFile // PURPOSE: Opens an ATF file for either reading or writing. // BOOL WINAPI ATF_OpenFile(LPCSTR szFileName, UINT uFlags, int *pnColumns, int *pnFile, int *pnError) { #if 0 LPSZASSERT(szFileName); #endif WPTRASSERT(pnColumns); WPTRASSERT(pnFile); // keep state of DONTWRITEHEADER flag BOOL bDontWriteHeader = uFlags & ATF_DONTWRITEHEADER; int nColumns, nFile; HANDLE hFile = INVALID_HANDLE_VALUE; ATF_FILEINFO *pATF = NULL; if (!GetNewFileDescriptor(&pATF, &nFile, pnError)) return FALSE; // copy name: #if !defined(_WINDOWS) || defined(__MINGW32__) pATF->pszFileName = strdup(szFileName); #else pATF->pszFileName = _strdup(szFileName); #endif if (pATF->pszFileName == NULL) goto OpenError; if (uFlags & ATF_READONLY) { hFile = CreateFileBuf(pATF, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { if (pnError) *pnError = ATF_ERROR_NOFILE; goto OpenError; } pATF->uFlags = uFlags; // Read the header information into the global variables if (!ReadHeaderInfo(pATF, pnColumns, pnError)) goto OpenError; } else { nColumns = *pnColumns; if (nColumns > ATF_MAXCOLUMNS) { if (pnError) *pnError = ATF_ERROR_TOOMANYCOLS; goto OpenError; } // Try to open any existing file with same name #if defined(_WINDOWS) && !defined(__MINGW32__) hFile = CreateFileBuf(pATF, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { if ((uFlags & ATF_OVERWRTIFEXIST)==0) { if (pnError) *pnError = ATF_ERROR_FILEEXISTS; goto OpenError; } if ((uFlags & ATF_APPENDIFEXIST)!=0) { // If we are appending to the file, read the header // to confirm that it is a valid ATF file that we are // appending to. if (!ReadHeaderInfo(pATF, NULL, pnError)) goto OpenError; } CloseHandleBuf(pATF); } else #endif uFlags = ATF_WRITEONLY; pATF->uFlags = uFlags; // Now, open the file for output hFile = CreateFileBuf(pATF, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, uFlags & ATF_APPENDIFEXIST ? OPEN_EXISTING : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { if (pnError) *pnError = ATF_ERROR_NOFILE; goto OpenError; } if ((uFlags & ATF_APPENDIFEXIST)!=0) { // pATF->hFile = hFile; pATF->bDataOnLine = FALSE; pATF->eState = eDATAAPPENDED; pATF->bWriting = TRUE; } else { // Set the DONTWRITEHEADER flag if needed pATF->uFlags |= bDontWriteHeader; // Write the header information and set up global variables if (!WriteHeaderInfo(pATF, nColumns, pnError)) { CloseHandleBuf(pATF); goto OpenError; } } } *pnFile = nFile; return TRUE; OpenError: if (hFile != INVALID_HANDLE_VALUE) CloseHandleBuf(pATF); if (pATF->pszFileName != NULL) free(pATF->pszFileName); free(pATF); g_FileDescriptor[nFile] = NULL; return FALSE; } //=============================================================================================== // FUNCTION: HasUnits // PURPOSE: Checks for the presence of a units string. // static BOOL HasUnits(LPCSTR pszUnits) { return (pszUnits && (pszUnits[0]!=0)); } //=============================================================================================== // FUNCTION: UpdateHeaders // PURPOSE: Update the headers in the ATF file. // static BOOL UpdateHeaders(ATF_FILEINFO *pATF, int *pnError) { WPTRASSERT(pATF); if (pATF->uFlags & ATF_DONTWRITEHEADER) return TRUE; char *pszIOBuffer = pATF->pszIOBuffer; // if there are unterminated header lines then terminate the last one if (pATF->bDataOnLine) { if (!putsBuf(pATF, s_szEndOfLine)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); pATF->nHeaders++; pATF->bDataOnLine = FALSE; } // Save the current position of the file long lCurrentPos = SetFilePointerBuf(pATF, 0, NULL, FILE_CURRENT); // Move to the location of the record containing the number of header records SetFilePointerBuf(pATF, pATF->lFilePos, NULL, FILE_BEGIN); // Create the string for the number of header records { snprintf(pszIOBuffer, sizeof(pszIOBuffer), "%d%s%d", pATF->nHeaders, pATF->szSeparator, pATF->nColumns); if (!putsBuf(pATF, pszIOBuffer)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); } // Restore the position of the file SetFilePointerBuf(pATF, lCurrentPos, NULL, FILE_BEGIN); // Output the column titles and units record for (int i=0; inColumns; i++) { // Start with separator if not the first column if (i > 0) strcpy(pszIOBuffer, pATF->szSeparator); else pszIOBuffer[0] = '\0'; // Add next title string strcat(pszIOBuffer, "\""); if (pATF->apszFileColTitles[i] != NULL) { strcat(pszIOBuffer, pATF->apszFileColTitles[i]); if (HasUnits(pATF->apszFileColUnits[i])) strcat(pszIOBuffer, " "); } if (HasUnits(pATF->apszFileColUnits[i])) { strcat(pszIOBuffer, "("); strcat(pszIOBuffer, pATF->apszFileColUnits[i]); strcat(pszIOBuffer, ")"); } strcat(pszIOBuffer, "\""); if (!putsBuf(pATF, pszIOBuffer)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); } if (!putsBuf(pATF, s_szEndOfLine)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); pATF->bDataOnLine = FALSE; pszIOBuffer[0] = '\0'; return TRUE; } //=============================================================================================== // FUNCTION: ATF_CloseFile // PURPOSE: Close an ATF file that was opened with ATF_OpenFile. // BOOL WINAPI ATF_CloseFile(int nFile) { ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, NULL)) return FALSE; // Check that we have written out the headers at least. if ((pATF->eState < eDATAWRITTEN) && pATF->bWriting) UpdateHeaders(pATF, NULL); // Close the file and update the state variable CloseHandleBuf(pATF); CleanupMem(pATF->apszFileColTitles, pATF->nColumns); free(pATF->apszFileColTitles); CleanupMem(pATF->apszFileColUnits, pATF->nColumns); free(pATF->apszFileColUnits); FreeIOBuffer(pATF); if (pATF->pszFileName != NULL) free(pATF->pszFileName); free(pATF); g_FileDescriptor[nFile] = NULL; return TRUE; } //=============================================================================================== // FUNCTION: ATF_SetSeperator // PURPOSE: Sets the data item separator to be used when writing out an ATF file. // BOOL WINAPI ATF_SetSeperator(int nFile, BOOL bUseCommas, int *pnError) { ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; pATF->szSeparator[0] = s_szDelimiter[bUseCommas ? 1 : 0]; return TRUE; } //=============================================================================================== // FUNCTION: ATF_IsAppending // PURPOSE: Returns TRUE if the file has been opened for appending. // BOOL WINAPI ATF_IsAppending(int nFile) { ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, NULL)) return FALSE; return (pATF->eState == eDATAAPPENDED); } //=============================================================================================== // FUNCTION: ATF_RewindFile // PURPOSE: Rewind the data section of the ATF file back to the beginning. // BOOL WINAPI ATF_RewindFile(int nFile, int *pnError) { ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; if (pATF->bWriting) ERRORRETURN(pnError, ATF_ERROR_BADSTATE); if (pATF->eState != eDATAREAD) ERRORRETURN(pnError, ATF_ERROR_BADSTATE); SetFilePointerBuf(pATF, pATF->lDataPtr, NULL, FILE_BEGIN); return TRUE; } //=============================================================================================== // FUNCTION: ATF_CountDataLines // PURPOSE: Counts lines of data in an ATF file, stopping at the first empty line, or EOF. // BOOL WINAPI ATF_CountDataLines(int nFile, long *plNumLines, int *pnError) { WPTRASSERT(plNumLines); long lDataLines = 0L; ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; while (ReadDataRecord(pATF, pnError)) { if (strchr(s_szLineTerm, pATF->pszIOBuffer[0])) break; ++lDataLines; } ATF_RewindFile(nFile, NULL); *plNumLines = lDataLines; return TRUE; } //=============================================================================================== // FUNCTION: ATF_GetNumHeaders // PURPOSE: Gets the number of optional data records in the ATF file. // BOOL WINAPI ATF_GetNumHeaders(int nFile, int *pnHeaders, int *pnError) { WPTRASSERT(pnHeaders); ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; *pnHeaders = pATF->nHeaders; return TRUE; } //=============================================================================================== // FUNCTION: ATF_WriteHeaderRecord // PURPOSE: Writes an optional header r3cord to the ATF file. // BOOL WINAPI ATF_WriteHeaderRecord(int nFile, LPCSTR pszText, int *pnError) { #if 0 LPSZASSERT(pszText); #endif ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; if (pATF->uFlags & ATF_DONTWRITEHEADER) return TRUE; char *pszIOBuffer = pATF->pszIOBuffer; // Check that we are in the correct state for this file if (pATF->eState > eHEADERED) ERRORRETURN(pnError, ATF_ERROR_BADSTATE); // Update the state if necessary pATF->eState = eHEADERED; // Write out the header record if (pATF->bDataOnLine) strcpy(pszIOBuffer, pATF->szSeparator); else pszIOBuffer[0] = '\0'; strcat(pszIOBuffer, "\""); strcat(pszIOBuffer, pszText); strcat(pszIOBuffer, "\""); if (!putsBuf(pATF, pszIOBuffer)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); pATF->bDataOnLine = TRUE; return TRUE; } //=============================================================================================== // FUNCTION: ATF_SetColumnTitle // PURPOSE: Sets the next column title. Columns are labeled sequentially. // BOOL WINAPI ATF_SetColumnTitle(int nFile, LPCSTR pszText, int *pnError) { #if 0 LPSZASSERT(pszText); #endif int i; ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Check that we are in the correct state for this file if (pATF->eState > eHEADERED) ERRORRETURN(pnError, ATF_ERROR_BADSTATE); for (i=0; inColumns; i++) if (pATF->apszFileColTitles[i] == NULL) break; if (i==pATF->nColumns) ERRORRETURN(pnError, ATF_ERROR_TOOMANYCOLS); // Copy the new column title into the string buffer and save a pointer to it. #if !defined(_WINDOWS) || defined(__MINGW32__) LPSTR psz = strdup(pszText); #else LPSTR psz = _strdup(pszText); #endif if (psz == NULL) ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); pATF->apszFileColTitles[i] = psz; return TRUE; } //=============================================================================================== // FUNCTION: ATF_SetColumnUnits // PURPOSE: Sets the next column units label. Columns are labeled sequentially. // BOOL WINAPI ATF_SetColumnUnits(int nFile, LPCSTR pszText, int *pnError) { #if 0 LPSZASSERT(pszText); #endif int i; ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Check that we are in the correct state for this file if (pATF->eState > eHEADERED) ERRORRETURN(pnError, ATF_ERROR_BADSTATE); for (i=0; inColumns; i++) if (pATF->apszFileColUnits[i] == NULL) break; if (i==pATF->nColumns) ERRORRETURN(pnError, ATF_ERROR_TOOMANYCOLS); // Copy the new column Unit into the string buffer and save a pointer to it. #if !defined(_WINDOWS) || defined(__MINGW32__) LPSTR psz = strdup(pszText); #else LPSTR psz = _strdup(pszText); #endif if (psz == NULL) ERRORRETURN(pnError, ATF_ERROR_NOMEMORY); pATF->apszFileColUnits[i] = psz; return TRUE; } //=============================================================================================== // FUNCTION: ATF_WriteEndOfLine // PURPOSE: Terminates the current data line when writing to an ATF file. // BOOL WINAPI ATF_WriteEndOfLine(int nFile, int *pnError) { ATF_FILEINFO * pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Write out the EndOfLine character to the file if (!putsBuf(pATF, s_szEndOfLine)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); // Reset data-on-line flag pATF->bDataOnLine = FALSE; // If a header is being written, increment the count of header records if (pATF->eState == eHEADERED) pATF->nHeaders++; return TRUE; } //=============================================================================================== // FUNCTION: ATF_WriteDataRecord // PURPOSE: Writes a data record out to the ATF file. // BOOL WINAPI ATF_WriteDataRecord(int nFile, LPCSTR pszText, int *pnError) { #if 0 LPSZASSERT(pszText); #endif ATF_FILEINFO * pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Check that we are in the correct state for this file if (pATF->eState < eDATAWRITTEN) { if (!UpdateHeaders(pATF, pnError)) return FALSE; pATF->eState = eDATAWRITTEN; } else if (pATF->bDataOnLine) if (!putsBuf(pATF, pATF->szSeparator)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); // Write out the text string to the file if (!putsBuf(pATF, pszText)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); // Set data-on-line flag pATF->bDataOnLine = TRUE; return TRUE; } //=============================================================================================== // FUNCTION: ATF_WriteDataComment // PURPOSE: Writes a comment record out to the ATF file. // BOOL WINAPI ATF_WriteDataComment(int nFile, LPCSTR pszText, int *pnError) { #if 0 LPSZASSERT(pszText); #endif char buf[128]; #if defined(_WINDOWS) && !defined(__MINGW32__) _snprintf(buf, sizeof(buf), "\"%s\"", pszText); #else snprintf(buf, sizeof(buf), "\"%s\"", pszText); #endif return ATF_WriteDataRecord(nFile, buf, pnError); } //=============================================================================================== // FUNCTION: ATF_WriteDataRecordArray // PURPOSE: Writes an array of data values out to a line of the ATF file. // BOOL WINAPI ATF_WriteDataRecordArray(int nFile, int nCount, double *pdVals, int *pnError) { ARRAYASSERT(pdVals, nCount); char psTemp[ATF_DBL_STR_LEN]; ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; if (nCount > pATF->nColumns) ERRORRETURN(pnError, ATF_ERROR_TOOMANYCOLS); char *pszIOBuffer = pATF->pszIOBuffer; // Check that we are in the correct state for this file if (pATF->eState < eDATAWRITTEN) { if (!UpdateHeaders(pATF, pnError)) return FALSE; pATF->eState = eDATAWRITTEN; } // Create the output string for this record char *ps = pszIOBuffer; *ps = '\0'; if (nCount > 0) { if (pATF->bDataOnLine) strcpy(ps++, pATF->szSeparator); if (!_FormatNumber(*pdVals++, ATF_DBL_SIG_DIGITS, psTemp, ATF_DBL_STR_LEN)) ERRORRETURN(pnError, ATF_ERROR_BADFLTCNV); strcpy(ps, psTemp); ps += strlen(psTemp); } for (int i=1; iszSeparator); ps += strlen(pATF->szSeparator); if (!_FormatNumber(*pdVals++, ATF_DBL_SIG_DIGITS, psTemp, ATF_DBL_STR_LEN)) ERRORRETURN(pnError, ATF_ERROR_BADFLTCNV); strcpy(ps, psTemp); ps += strlen(psTemp); } // Write out the text string to the file if (!putsBuf(pATF, pszIOBuffer)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); // Set data-on-line flag pATF->bDataOnLine = TRUE; return TRUE; } //=============================================================================================== // FUNCTION: ATF_WriteDataRecordArrayFloat // PURPOSE: Writes an array of float data values out to a line of the ATF file. // BOOL WINAPI ATF_WriteDataRecordArrayFloat(int nFile, int nCount, float *pfVals, int *pnError) { ARRAYASSERT(pfVals, nCount); char psTemp[ATF_FLT_STR_LEN]; ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; if (nCount > pATF->nColumns) ERRORRETURN(pnError, ATF_ERROR_TOOMANYCOLS); char *pszIOBuffer = pATF->pszIOBuffer; // Check that we are in the correct state for this file if (pATF->eState < eDATAWRITTEN) { if (!UpdateHeaders(pATF, pnError)) return FALSE; pATF->eState = eDATAWRITTEN; } // Create the output string for this record char *ps = pszIOBuffer; *ps = '\0'; if (nCount > 0) { if (pATF->bDataOnLine) strcpy(ps++, pATF->szSeparator); if (!_FormatNumber((double)*pfVals++, ATF_FLT_SIG_DIGITS, psTemp, ATF_FLT_STR_LEN)) ERRORRETURN(pnError, ATF_ERROR_BADFLTCNV); strcpy(ps, psTemp); ps += strlen(psTemp); } for (int i=1; iszSeparator); ps += strlen(pATF->szSeparator); if (!_FormatNumber((double)*pfVals++, ATF_FLT_SIG_DIGITS, psTemp, ATF_FLT_STR_LEN)) ERRORRETURN(pnError, ATF_ERROR_BADFLTCNV); strcpy(ps, psTemp); ps += strlen(psTemp); } // Write out the text string to the file if (!putsBuf(pATF, pszIOBuffer)) ERRORRETURN(pnError, ATF_ERROR_IOERROR); // Set data-on-line flag pATF->bDataOnLine = TRUE; return TRUE; } //=============================================================================================== // FUNCTION: ATF_WriteDataRecord1 // PURPOSE: Writes a single double data item out to the ATF file. // BOOL WINAPI ATF_WriteDataRecord1(int nFile, double dNum1, int *pnError) { char psTemp[ATF_DBL_STR_LEN]; if (!_FormatNumber(dNum1, ATF_DBL_SIG_DIGITS, psTemp, ATF_DBL_STR_LEN)) ERRORRETURN(pnError, ATF_ERROR_BADFLTCNV); return ATF_WriteDataRecord(nFile, psTemp, pnError); } //=============================================================================================== // FUNCTION: ATF_WriteDataRecord1Float // PURPOSE: Writes a single float data item out to the ATF file. // BOOL WINAPI ATF_WriteDataRecord1Float(int nFile, float fNum1, int *pnError) { char psTemp[ATF_FLT_STR_LEN]; if (!_FormatNumber((double)fNum1, ATF_FLT_SIG_DIGITS, psTemp, ATF_FLT_STR_LEN)) ERRORRETURN(pnError, ATF_ERROR_BADFLTCNV); return ATF_WriteDataRecord(nFile, psTemp, pnError); } //=============================================================================================== // FUNCTION: GetComment // PURPOSE: Strips a comment string out of the data stream, removing separators and // double quotes. // static char *GetComment(char *pszStr) { // Strip off any leading or trailing space characters pszStr = StripSpaces(pszStr); // If nothing left, return. if (*pszStr=='\0') return pszStr; // Strip leading and trailing quotes from the string if (*pszStr == '"') { pszStr++; char *ps = pszStr; while (*ps && (*ps!='"')) ps++; if (*ps != '\0') *ps = '\0'; } return pszStr; } //=============================================================================================== // FUNCTION: ReadHeaderLine // PURPOSE: Reads an optional header line from the file. // static BOOL ReadHeaderLine(ATF_FILEINFO *pATF, int *pnError) { WPTRASSERT(pATF); // Check that we are in the correct state for this file if (pATF->eState > eHEADERED) ERRORRETURN(pnError, ATF_ERROR_BADSTATE); pATF->eState = eHEADERED; // Check if there are any more header records left to be read if (pATF->nHeaders < 1) ERRORRETURN(pnError, ATF_ERROR_NOMORE); // Read a header record and copy it into the return buffer if (!ReadLine(pATF, ATF_ERROR_BADHEADER, pnError)) return FALSE; // remove any trailing white space at the end of the line. StripSpaces(pATF->pszIOBuffer); pATF->nHeaders--; return TRUE; } //=============================================================================================== // FUNCTION: ATF_ReadHeaderLine // PURPOSE: Exported version of ReadHeaderLine. // BOOL WINAPI ATF_ReadHeaderLine(int nFile, char *psBuf, int nMaxLen, int *pnError) { ARRAYASSERT(psBuf, nMaxLen); ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Load the next line, checking state etc if (!ReadHeaderLine(pATF, pnError)) return FALSE; strncpyz(psBuf, pATF->pszIOBuffer, nMaxLen); return TRUE; } //=============================================================================================== // FUNCTION: ATF_ReadHeaderNoQuotes // PURPOSE: Reads a header record, stripping of any double quotes if present. // BOOL WINAPI ATF_ReadHeaderNoQuotes(int nFile, char *psBuf, int nMaxLen, int *pnError) { ARRAYASSERT(psBuf, nMaxLen); ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Load the next line, checking state etc if (!ReadHeaderLine(pATF, pnError)) return FALSE; // Strip off any leading and trailing quotes from the string char *psComment = GetComment(pATF->pszIOBuffer); strncpyz(psBuf, psComment, nMaxLen); return TRUE; } //=============================================================================================== // FUNCTION: ATF_GetColumnTitle // PURPOSE: Returns the title of a particular column in the ATF file. // BOOL WINAPI ATF_GetColumnTitle(int nFile, int nColumn, char *pszText, int nMaxTxt, int *pnError) { ARRAYASSERT(pszText, nMaxTxt); ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Check that the column number is within range. if ((nColumn < 0) || (nColumn >= pATF->nColumns)) ERRORRETURN(pnError, ATF_ERROR_BADCOLNUM); if (pATF->apszFileColTitles[nColumn] != NULL) strncpyz(pszText, pATF->apszFileColTitles[nColumn], nMaxTxt); else pszText[0] = '\0'; return TRUE; } //=============================================================================================== // FUNCTION: ATF_GetColumnUnits // PURPOSE: Returns the units of a particular column in the ATF file. // BOOL WINAPI ATF_GetColumnUnits(int nFile, int nColumn, char *pszText, int nMaxTxt, int *pnError) { ARRAYASSERT(pszText, nMaxTxt); ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Check that the column number is within range. if ((nColumn < 0) || (nColumn >= pATF->nColumns)) ERRORRETURN(pnError, ATF_ERROR_BADCOLNUM); if (pATF->apszFileColUnits[nColumn] != NULL) strncpyz(pszText, pATF->apszFileColUnits[nColumn], nMaxTxt); else pszText[0] = '\0'; return TRUE; } //=============================================================================================== // FUNCTION: ReadDataRecord // PURPOSE: Internal workhorse function for parsing lines out of the data stream. // static BOOL ReadDataRecord(ATF_FILEINFO *pATF, int *pnError) { WPTRASSERT(pATF); // Check that we are in the correct state for this file if (pATF->eState < eDATAREAD) { // Read any header records that were not processed while (pATF->nHeaders-- > 0) if (!ReadLine(pATF, ATF_ERROR_BADHEADER, pnError)) return FALSE; // Skip the column titles and units if (!ReadLine(pATF, ATF_ERROR_BADHEADER, pnError)) return FALSE; if (pATF->dFileVersion == 0.0) if (!ReadLine(pATF, ATF_ERROR_BADHEADER, pnError)) return FALSE; pATF->lDataPtr = SetFilePointerBuf(pATF, 0, NULL, FILE_CURRENT); pATF->eState = eDATAREAD; } // Update the file state and check for end-of-file // JT - we may need this: // if (feof(pATF->hFile)) // ERRORRETURN(pnError, ATF_ERROR_NOMORE); // Read the next record from the data file and return it // JT - we may need to reconsider what error we use here: // return ReadLine(pATF, ATF_ERROR_IOERROR, pnError); return ReadLine(pATF, ATF_ERROR_NOMORE, pnError); } //=============================================================================================== // FUNCTION: ATF_ReadDataRecord // PURPOSE: Returns the next complete line from the ATF file. // BOOL WINAPI ATF_ReadDataRecord(int nFile, char *pszText, int nMaxLen, int *pnError) { ARRAYASSERT(pszText, nMaxLen); ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; if (!ReadDataRecord(pATF, pnError)) return FALSE; strncpyz(pszText, pATF->pszIOBuffer, nMaxLen); return TRUE; } //=============================================================================================== // FUNCTION: ATF_ReadDataRecordArray // PURPOSE: Reads an array of data values from the ATF file. // BOOL WINAPI ATF_ReadDataRecordArray(int nFile, int nCount, double *pdVals, char *pszComment, int nMaxLen, int *pnError) { ARRAYASSERT(pdVals, nCount); ARRAYASSERT(pszComment, nMaxLen); ATF_FILEINFO *pATF = NULL; if (!GetFileDescriptor(&pATF, nFile, pnError)) return FALSE; // Perform the necessary checks and read the data record if (!ReadDataRecord(pATF, pnError)) return FALSE; // Read out the requested numbers char *ps = pATF->pszIOBuffer; for (int i=0; ipszIOBuffer; for (int i=0; ihFile, &CreationTime, NULL, NULL)) { FILETIME LocalTime = { 0 }; VERIFY(FileTimeToLocalFileTime(&CreationTime, &LocalTime)); VERIFY(FileTimeToSystemTime(&LocalTime, &Time)); } int nYear = int(Time.wYear); if (plDate) *plDate = long(nYear*10000 + Time.wMonth*100 + Time.wDay); if (plTime) *plTime = long(((Time.wHour*60) + Time.wMinute)*60 + Time.wSecond); #endif return TRUE; } stimfit-0.16.7/src/libstfio/abf/axon/AxAtfFio32/atfintl.h0000775000175000017500000000667514750344764016525 //*********************************************************************************************** // // Written 1990 - 1996 by AXON Instruments Inc. // // This file is not protected by copyright. You are free to use, modify // and copy the code in this file. // //*********************************************************************************************** // // HEADER: ATFINTL.H // PURPOSE: Internal header file for the ATF file I/O routines. // enum eFILE_STATE { eCLOSED, eOPENED, eHEADERED, eDATAREAD, eDATAWRITTEN, eDATAAPPENDED, }; struct ATF_FILEINFO { HANDLE hFile; eFILE_STATE eState; BOOL bWriting; UINT uFlags; int nHeaders; long lFilePos; int nColumns; double dFileVersion; long lTitlesPtr; long lDataPtr; BOOL bDataOnLine; char szSeparator[2]; char ** apszFileColTitles; char ** apszFileColUnits; char * pszIOBuffer; char * pszFileName; int nIOBufferSize; // buffering: long lBufSize; char * pszBuf; // = lBufSize means no info is buffered long lPos; // current position in buffer - 0 means no info is buffered BOOL bRead; // TRUE = reading; FALSE = writing long lBufReadLimit; // actual amount read in when a full buffer is not available char cLineTerm; // The character that will terminate each line. }; typedef ATF_FILEINFO *PATF_FILEINFO; //----------------------------------------------------------------------------------------------- // Macros and functions to deal with returning error return codes through a pointer if given. #define ERRORRETURN(p, e) return ErrorReturn(p, e); inline BOOL ErrorReturn(int *pnError, int nErrorNum) { if (pnError) *pnError = nErrorNum; return FALSE; } //----------------------------------------------------------------------------------------------- #define MAX_READ_SIZE 512 #define GETS_OK 0 // Success! #define GETS_EOF 1 // End of file reached. #define GETS_ERROR 2 // I/O error #define GETS_NOEOL 3 // No end of line found. //----------------------------------------------------------------------------------------------- // declaration of low-level file I/O functions. HANDLE CreateFileBuf(ATF_FILEINFO *pATF, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ); BOOL CloseHandleBuf(ATF_FILEINFO *pATF); BOOL WriteFileBuf(ATF_FILEINFO *pATF, LPCVOID pvBuffer, DWORD dwBytes, DWORD *pdwWritten, LPOVERLAPPED lpOverlapped); BOOL ReadFileBuf(ATF_FILEINFO *pATF, LPVOID pvBuffer, DWORD dwBytes, DWORD *pdwRead, LPOVERLAPPED lpOverlapped); DWORD SetFilePointerBuf(ATF_FILEINFO *pATF, long lToMove, PLONG plDistHigh, DWORD dwMoveMethod); int getsBuf(ATF_FILEINFO *pATF, LPSTR pszString, DWORD dwToRead); int putsBuf(ATF_FILEINFO *pATF, LPCSTR pszString); stimfit-0.16.7/src/libstfio/abf/axon/AxAtfFio32/fileio2.cpp0000775000175000017500000006163614750344764016746 //*********************************************************************************************** // // Written 1990 - 1996 by AXON Instruments Inc. // // This file is not protected by copyright. You are free to use, modify // and copy the code in this file. // //*********************************************************************************************** // // MODULE: FILEIO.CPP // PURPOSE: Low level routines for buffered file I/O. // // An ANSI C compiler should be used for compilation. // (e.g. CL -c AXATFFIO32.CPP) // #include "../Common/wincpp.hpp" #include "atfintl.h" #include "axatffio32.h" #include #if !defined(_WINDOWS) || defined(__MINGW32__) || defined(__STF__) #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif #if defined(_MSC_VER) //=============================================================================================== // FUNCTION: _GetRootDir // PURPOSE: Extracts the root directory of a full or partial path. // FIXFIX: Fix this to cope with UNC names when GetDiskFreeSpace does. // static BOOL _GetRootDir(LPCSTR pszFileName, LPSTR pszRoot, UINT uRootLen) { // Build the path to the drive's root directory. char szRootDir[_MAX_DRIVE+2]; char szFullPath[_MAX_PATH], *pszTitle; GetFullPathNameA(pszFileName, sizeof(szFullPath), szFullPath, &pszTitle); if (!isalpha(szFullPath[0])) return FALSE; sprintf(szRootDir, "%c:\\", szFullPath[0]); strncpy(pszRoot, szRootDir, uRootLen-1); pszRoot[uRootLen-1] = '\0'; return TRUE; } #endif //=============================================================================================== // FUNCTION: _AllocReadWriteBuffer // PURPOSE: Allocate read/write buffers for this file // static BOOL AllocReadWriteBuffer(ATF_FILEINFO *pATF, DWORD dwDesiredAccess) { WPTRASSERT(pATF); // init all settings: pATF->lBufSize = 0L; pATF->lPos = 0L; pATF->lBufReadLimit = 0L; pATF->pszBuf = NULL; pATF->bRead = TRUE; // if querying only: if (dwDesiredAccess == 0) return TRUE; #if defined(_MSC_VER) char szRootDir[_MAX_DRIVE+2]; if (_GetRootDir(pATF->pszFileName, szRootDir, sizeof(szRootDir))) { DWORD dwSectorsPerCluster = 0; DWORD dwBytesPerSector = 0; DWORD dwNumberOfFreeClusters = 0; DWORD dwTotalNumberOfClusters = 0; GetDiskFreeSpaceA(szRootDir, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters); pATF->lBufSize = min((dwSectorsPerCluster * dwBytesPerSector), (long)ATF_MAX_BUFFER_SIZE); ASSERT(pATF->lBufSize > 0); } else pATF->lBufSize = ATF_MAX_BUFFER_SIZE; #else pATF->lBufSize = ATF_MAX_BUFFER_SIZE; #endif // Allocate one more than the size for zero termination. pATF->pszBuf = (char *)calloc(pATF->lBufSize+1, sizeof(char)); if (pATF->pszBuf == NULL) { pATF->lBufSize = 0L; return FALSE; } pATF->lPos = pATF->lBufSize; // empty read buffer pATF->lBufReadLimit = pATF->lBufSize; return TRUE; } //=============================================================================================== // FUNCTION: _FreeReadWriteBuffer // PURPOSE: Free the read/write buffers used by this file; flushes write buffer to disk if necessary // static BOOL FreeReadWriteBuffer(ATF_FILEINFO *pATF) { WPTRASSERT(pATF); DWORD dwBytesWritten = 0; if (!pATF->bRead && pATF->lPos != 0L) #if defined(_MSC_VER) WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL); #else c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL); #endif if (pATF->pszBuf) free(pATF->pszBuf); pATF->pszBuf = NULL; pATF->lBufSize = 0L; pATF->lPos = 0L; pATF->lBufReadLimit = 0L; pATF->bRead = TRUE; return TRUE; } //=============================================================================================== // FUNCTION: _CreateFileBuf // PURPOSE: Buffered version of CreateFile - creates appropriate buffers // PARAMETERS: // pATF Pointer to ATF_FILEINFO structure containing ATF state information (just filename at this point!) // ... CreateFile parms which we ignore (missing lpFileName - derived from pATF), except // for dwDesiredAccess. If GENERIC_READ or GENERIC_WRITE, we allocate a buffer // RETURNS: Handle of file; INVALID_HANDLE_VALUE if failure; HANDLE CreateFileBuf(ATF_FILEINFO *pATF, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { #if defined(_MSC_VER) pATF->hFile = CreateFileA(pATF->pszFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); #else pATF->hFile = c_CreateFile(pATF->pszFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); #endif if (pATF->hFile != INVALID_HANDLE_VALUE) { // allocate buffer, initialize flags: if (!AllocReadWriteBuffer(pATF, dwDesiredAccess)) { #if defined(_MSC_VER) CloseHandle(pATF->hFile); #else c_CloseHandle((FILE*)pATF->hFile); #endif pATF->hFile = INVALID_HANDLE_VALUE; } } return pATF->hFile; } //=============================================================================================== // FUNCTION: _CloseHandleBuf // PURPOSE: Buffered version of CloseHandle - flushes and cleans up buffers // PARAMETERS: // pATF Pointer to ATF_FILEINFO structure containing ATF state information (just filename at this point!) // RETURNS: TRUE on success; FALSE on failure BOOL CloseHandleBuf(ATF_FILEINFO *pATF) { BOOL bReturn = FreeReadWriteBuffer(pATF); #if defined(_MSC_VER) return CloseHandle(pATF->hFile) && bReturn; #else return c_CloseHandle((FILE*)pATF->hFile) && bReturn; #endif } //=============================================================================================== // FUNCTION: WriteFileBuf // PURPOSE: Buffered version of WriteFile // PARAMETERS: // pATF Pointer to ATF_FILEINFO structure containing ATF state information // pvBuffer Buffer containing data to be written // dwBytes Number of bytes to write // pdwWritten Pointer to DWORD used to catch the number of bytes written to the file // lpOverlapped Pointer to overlapped structure used to communicate requests of overlapped i/o (may be NULL) // RETURNS: // TRUE on success // FALSE on failure BOOL WriteFileBuf(ATF_FILEINFO *pATF, LPCVOID pvBuffer, DWORD dwBytes, DWORD *pdwWritten, LPOVERLAPPED lpOverlapped) { WPTRASSERT(pATF); long lBufSize = pATF->lBufSize; char *pszWriteBuf = pATF->pszBuf; // perform write if buffer size is 0: if (lBufSize == 0L) #if defined(_MSC_VER) return WriteFile(pATF->hFile, pvBuffer, dwBytes, pdwWritten, lpOverlapped); #else return c_WriteFile((FILE*)pATF->hFile, pvBuffer, dwBytes, pdwWritten, lpOverlapped); #endif // switch to write mode: if (pATF->bRead) { pATF->bRead = FALSE; pATF->lPos = 0; } // determine free size left in buffer: long lFreeSize = lBufSize - pATF->lPos; ASSERT(lFreeSize > 0L); // move up to a single buffer long lMoveSize = min((DWORD)lFreeSize, dwBytes); memcpy(pszWriteBuf + pATF->lPos, pvBuffer, lMoveSize); pATF->lPos += lMoveSize; // case 1: doesn't fill buffer if (pATF->lPos < lBufSize) { if (pdwWritten) *pdwWritten = dwBytes; return TRUE; } // write initial buffer - results handled in case 2 and 3: DWORD dwBytesWritten = 0; #if defined(_MSC_VER) BOOL bReturn = WriteFile(pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, lpOverlapped); #else BOOL bReturn = c_WriteFile((FILE*)pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, lpOverlapped); #endif // case 2: fills buffer, less than one buffer overflow (write one, move the rest) if (dwBytes - (DWORD)lMoveSize < (DWORD)lBufSize) { if (dwBytes - lMoveSize > 0L) memcpy(pszWriteBuf, ((BYTE *)pvBuffer + lMoveSize), dwBytes-lMoveSize); pATF->lPos = dwBytes - lMoveSize; if (pdwWritten) *pdwWritten = dwBytes; return bReturn; } // case 3: multiple buffer's worth (write mem buffer, write the remainder, reset internals) if (bReturn) { #if defined(_MSC_VER) bReturn = WriteFile(pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesWritten, lpOverlapped); #else bReturn = c_WriteFile((FILE*)pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesWritten, lpOverlapped); #endif if (pdwWritten) *pdwWritten = dwBytes; } else if (pdwWritten) *pdwWritten = dwBytesWritten; pATF->lPos = 0L; return bReturn; } //=============================================================================================== // FUNCTION: ReadFileBuf // PURPOSE: Buffered version of ReadFile // PARAMETERS: // pATF Pointer to ATF_FILEINFO structure containing ATF state information // pvBuffer Buffer to contain dwBytes read from file // dwBytes Number of bytes to read // pdwRead Pointer to DWORD used to catch the number of bytes written to the file // lpOverlapped Pointer to overlapped structure used to communicate requests of overlapped i/o (may be NULL) // RETURNS: // TRUE on success (*pdwRead == 0 -> EOF) // FALSE on failure (error condition) BOOL ReadFileBuf(ATF_FILEINFO *pATF, LPVOID pvBuffer, DWORD dwBytes, DWORD *pdwRead, LPOVERLAPPED lpOverlapped) { WPTRASSERT(pATF); // perform read if buffer size is 0: if (pATF->lBufSize == 0L) #if defined(_MSC_VER) return ReadFile(pATF->hFile, pvBuffer, dwBytes, pdwRead, lpOverlapped); #else return c_ReadFile((FILE*)pATF->hFile, pvBuffer, dwBytes, pdwRead, lpOverlapped); #endif // switch to read mode: if (!pATF->bRead) { DWORD dwBytesWritten; // commit current cache: if (pATF->lPos > 0L) #if defined(_MSC_VER) if (!WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #else if (!c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #endif return FALSE; pATF->bRead = TRUE; pATF->lPos = pATF->lBufSize; pATF->lBufReadLimit = pATF->lBufSize; } DWORD dwBytesRead; BOOL bReturn; long lBufSize = pATF->lBufSize; char *pszReadBuf = pATF->pszBuf; // determine amount left in buffer: long lBytesInBuf = pATF->lBufReadLimit - pATF->lPos; ASSERT(lBytesInBuf >= 0L); // move up to a single buffer long lMoveSize = min((DWORD)lBytesInBuf, dwBytes); if (lMoveSize > 0L) { memcpy(pvBuffer, pszReadBuf + pATF->lPos, lMoveSize); pATF->lPos += lMoveSize; } // case 1: request doesn't run past the end of the buffer if (pATF->lPos < pATF->lBufReadLimit) { if (pdwRead) *pdwRead = dwBytes; return TRUE; } // case 2: request runs past end of buffer, and wants more than (or =) another buffer's worth: // (perform a full read; leaves buffer empty) if (dwBytes - (DWORD)lMoveSize >= (DWORD)pATF->lBufReadLimit) { #if defined(_MSC_VER) bReturn = ReadFile(pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesRead, lpOverlapped); #else bReturn = c_ReadFile((FILE*)pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesRead, lpOverlapped); #endif if (pdwRead) *pdwRead = lMoveSize + dwBytesRead; pATF->lPos = lBufSize; pATF->lBufReadLimit = lBufSize; return bReturn; } // case 3: request runs past end of buffer, and wants less than another buffer's worth: // (read in another buffer, copy wanted portion, advance lPos) #if defined(_MSC_VER) bReturn = ReadFile(pATF->hFile, pszReadBuf, lBufSize, &dwBytesRead, lpOverlapped); #else bReturn = c_ReadFile((FILE*)pATF->hFile, pszReadBuf, lBufSize, &dwBytesRead, lpOverlapped); #endif if (bReturn) { pATF->lBufReadLimit = dwBytesRead; int nMoveAmount = min((int)(dwBytes - lMoveSize), pATF->lBufReadLimit); memcpy((BYTE *)pvBuffer + lMoveSize, pszReadBuf, nMoveAmount); if (pdwRead) *pdwRead = lMoveSize + nMoveAmount; pATF->lPos = nMoveAmount; } else { if (pdwRead) *pdwRead = lMoveSize; pATF->lPos = lBufSize; } return bReturn; } //=============================================================================================== // FUNCTION: _SetFilePointerBuf // PURPOSE: Buffered version of SetFilePointer // PARAMETERS: // pATF Pointer to ATF_FILEINFO structure containing ATF state information // lToMove Amount to move from position specified in dwMoveMethod; negative means move backwards // plDistHigh High order word of 64-bit distance to move. Should be NULL // dwMoveMethod Method to move: FILE_BEGIN - move lToMove bytes from beginning of file // FILE_CURRENT - move lToMove bytes from current position // FILE_END - move lToMove bytes from end of file // RETURNS: Offset of new position from beginning of file (0xFFFFFFFF if failure) DWORD SetFilePointerBuf(ATF_FILEINFO *pATF, long lToMove, PLONG plDistHigh, DWORD dwMoveMethod) { WPTRASSERT(pATF); DWORD dwBytesWritten; // move real file position to lPos: if (pATF->bRead) { #if defined(_MSC_VER) if (SetFilePointer(pATF->hFile, pATF->lPos - pATF->lBufReadLimit, NULL, FILE_CURRENT) == 0xFFFFFFFF) #else if (c_SetFilePointer((FILE*)pATF->hFile, pATF->lPos - pATF->lBufReadLimit, NULL, FILE_CURRENT) == 0xFFFFFFFF) #endif return 0xFFFFFFFF; } // flush write buffer if non-empty - this positions the file pointer appropriately. else { if (pATF->lPos != 0L) { #if defined(_MSC_VER) if (!WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #else if (!c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #endif return 0xFFFFFFFF; } } pATF->bRead = TRUE; pATF->lPos = pATF->lBufSize; pATF->lBufReadLimit = pATF->lBufSize; #if defined(_MSC_VER) return SetFilePointer(pATF->hFile, lToMove, plDistHigh, dwMoveMethod); #else return c_SetFilePointer((FILE*)pATF->hFile, lToMove, plDistHigh, dwMoveMethod); #endif } //=============================================================================================== // FUNCTION: SetLineTerminator // PURPOSE: Sets the line terminator to use on this file. // NOTES: This call assumes that if the file only contains \r characters as // line terminators, that there will be at least one '\r' in the first read of the file. // This should be reasonably safe as the first line of an ATF file should be "ATF\t1.0 \r". // inline char GetLineTerminator(LPSTR psz) { return strchr(psz, '\n') ? '\n' : '\r'; } //=============================================================================================== // FUNCTION: getsUnBuf // PURPOSE: Unbuffered version of gets // RETURNS: ZERO on success // GETS_EOF on EOF // GETS_ERROR on error // static int getsUnBuf(ATF_FILEINFO *pATF, LPSTR pszString, DWORD dwBufSize) { WPTRASSERT(pATF); ASSERT(dwBufSize > 1L); // Must be at least one character and a '\0'; DWORD dwToRead = dwBufSize; // Zero terminate the buffer at the last element and reduce the length count // to be sure that we are returning a zero term8inated string. dwToRead--; pszString[dwToRead] = '\0'; LPSTR pszThisRead = pszString; while (dwToRead > 0L) { // Do the read. DWORD dwBytesToRead = min(MAX_READ_SIZE, dwToRead); DWORD dwBytesRead = 0L; if (!ReadFileBuf(pATF, pszThisRead, dwBytesToRead, &dwBytesRead, NULL)) return GETS_ERROR; if (dwBytesRead == 0L) return GETS_EOF; // Zero terminate the read block after the last byte read. // No bounds problem because we predecremented the string size // up front to allow for a trailing '\0'. pszThisRead[dwBytesRead] = '\0'; // If the line terminator has not been set, set it now. if (pATF->cLineTerm == '\0') pATF->cLineTerm = GetLineTerminator(pszString); // look for a line terminator. LPSTR pszTerm = strchr(pszThisRead, pATF->cLineTerm); if (pszTerm) { // Zero out the terminator and step on past it. *pszTerm++ = '\0'; // Set the count of bytes to back up in the file. int nCount = (pszThisRead + dwBytesRead) - pszTerm; // adjust file position if we find a line terminator before the end of the buffer we have just read; if (nCount < 0) SetFilePointerBuf(pATF, nCount, NULL, FILE_CURRENT); break; } dwToRead -= dwBytesRead; pszThisRead += dwBytesRead; } // Take out the last character if it is '\r'. // (present if \r\n pairs terminate lines) int l = strlen(pszThisRead); if (l && (pszThisRead[l-1]=='\r')) { --l; pszThisRead[l] = '\0'; } return (DWORD(l) < dwBufSize-1) ? 0 : GETS_NOEOL; } //=============================================================================================== // FUNCTION: getsBuf // PURPOSE: Buffered version of gets -- line terminated are removed from the returned string. // RETURNS: ZERO on success // GETS_EOF on EOF // GETS_ERROR on error int getsBuf(ATF_FILEINFO *pATF, LPSTR pszString, DWORD dwBufSize) { WPTRASSERT(pATF); // ******************************************************************************* // check for unbuffered status: if (pATF->lBufSize == 0) return getsUnBuf(pATF, pszString, dwBufSize); DWORD dwToRead = dwBufSize; // ******************************************************************************* // switch to read mode, if necessary: if (!pATF->bRead) { DWORD dwBytesWritten; // commit current cache: if (pATF->lPos > 0) #if defined(_MSC_VER) if (!WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #else if (!c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #endif return GETS_ERROR; pATF->bRead = TRUE; pATF->lPos = pATF->lBufSize; pATF->lBufReadLimit = pATF->lBufSize; } // ******************************************************************************* // process: dwToRead--; // for terminating 0 pszString[dwToRead] = '\0'; LPSTR pszReturnBuf = pszString; LPSTR pszReadBuf = pATF->pszBuf; while (dwToRead > 0L) { // determine amount left in buffer: long lBytesInBuf = pATF->lBufReadLimit - pATF->lPos; ASSERT(lBytesInBuf >= 0L); // move up to a single buffer long lMoveSize = min(lBytesInBuf, (long)dwToRead); if (lMoveSize > 0) { // look for a line terminator LPSTR pszStart = pszReadBuf + pATF->lPos; LPSTR pszTerm = strchr(pszStart, pATF->cLineTerm); // If found and inside the read range terminate the string and the read. if (pszTerm && (pszTerm < pszStart+lMoveSize)) { *pszTerm = '\0'; lMoveSize = pszTerm - pszStart + 1; // When the counter gets decremented below, the loop will terminate. dwToRead = lMoveSize; } // Copy the data into the return buffer. strncpy(pszReturnBuf, pszStart, lMoveSize); pszReturnBuf[lMoveSize] = '\0'; // Advance the buffer position pATF->lPos += lMoveSize; dwToRead -= lMoveSize; pszReturnBuf += lMoveSize; } else { // read another buffer if done with the current one: if (dwToRead > 0) // ie - we arrived here because lBytesInBuf == 0 { DWORD dwBytesRead; #if defined(_MSC_VER) if (!ReadFile(pATF->hFile, pszReadBuf, pATF->lBufSize, &dwBytesRead, NULL)) #else if (!c_ReadFile((FILE*)pATF->hFile, pszReadBuf, pATF->lBufSize, &dwBytesRead, NULL)) #endif return GETS_ERROR; if (dwBytesRead == 0) return GETS_EOF; if (dwBytesRead != (DWORD)pATF->lBufSize) pATF->lBufReadLimit = dwBytesRead; else pATF->lBufReadLimit = pATF->lBufSize; pATF->lPos = 0; // Zero terminate the read block after the last byte read. // No bounds problem because we allocated the I/O buffer to be one byte // more than pATF->lBufSize. pszReadBuf[dwBytesRead] = '\0'; // If the line terminator has not been set, set it now. if (pATF->cLineTerm == '\0') pATF->cLineTerm = GetLineTerminator(pszReadBuf); } } } // Take out the last character if it is '\r'. // (present if \r\n pairs terminate lines) int l = strlen(pszString); if (l && (pszString[l-1]=='\r')) { l--; pszString[l] = '\0'; } return (DWORD(l) < dwBufSize-1) ? 0 : GETS_NOEOL; } //=============================================================================================== // FUNCTION: putsBuf // PURPOSE: Buffered version of puts. // RETURNS: ZERO on success // GETS_EOF on EOF // GETS_ERROR on error int putsBuf(ATF_FILEINFO *pATF, LPCSTR pszString) { WPTRASSERT(pATF); DWORD dwBytes = strlen(pszString); DWORD dwBytesWritten; // perform write if buffer size is 0: if (pATF->lBufSize == 0L) #if defined(_MSC_VER) return WriteFile(pATF->hFile, pszString, dwBytes, &dwBytesWritten, NULL); #else return c_WriteFile((FILE*)pATF->hFile, pszString, dwBytes, &dwBytesWritten, NULL); #endif // switch to write mode: if (pATF->bRead) { pATF->bRead = FALSE; pATF->lPos = 0; } long lBufSize = pATF->lBufSize; char *pszWriteBuf = pATF->pszBuf; // determine free size left in buffer: long lFreeSize = lBufSize - pATF->lPos; ASSERT(lFreeSize > 0L); // move up to a single buffer long lMoveSize = min((DWORD)lFreeSize, dwBytes); memcpy(pszWriteBuf + pATF->lPos, pszString, lMoveSize); pATF->lPos += lMoveSize; // case 1: doesn't fill buffer if (pATF->lPos < lBufSize) return TRUE; // write initial buffer - results handled in case 2 and 3: #if defined(_MSC_VER) BOOL bReturn = WriteFile(pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, NULL); #else BOOL bReturn = c_WriteFile((FILE*)pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, NULL); #endif // case 2: fills buffer, less than one buffer overflow (write one, move the rest) if (dwBytes - (DWORD)lMoveSize < (DWORD)lBufSize) { pATF->lPos = dwBytes - lMoveSize; if (pATF->lPos > 0L) memcpy(pszWriteBuf, pszString + lMoveSize, pATF->lPos); return bReturn; } // case 3: multiple buffer's worth (write mem buffer, write the remainder, reset internals) if (bReturn) #if defined(_MSC_VER) bReturn = WriteFile(pATF->hFile, pszString + lMoveSize, dwBytes - lMoveSize, &dwBytesWritten, NULL); #else bReturn = c_WriteFile((FILE*)pATF->hFile, pszString + lMoveSize, dwBytes - lMoveSize, &dwBytesWritten, NULL); #endif pATF->lPos = 0L; return bReturn; } stimfit-0.16.7/src/libstfio/abf/axon/AxAtfFio32/axatffio32.h0000775000175000017500000001122114750344764017011 /****************************************************************************\ * * * Written 1990 - 1996 by AXON Instruments Inc. * * * * This file is not protected by copyright. You are free to use, modify * * and copy the code in this file. * * * \****************************************************************************/ #ifndef INC_AXATFFIO32_H #define INC_AXATFFIO32_H #include "../Common/wincpp.hpp" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define VAL_EXTERNBUFSIZE 31 /* anybody calling methods using conversion */ // This is AXATFFIO32.H; a companion file to AXATFFIO32.CPP #define ATF_CURRENTVERSION 1.0 // Length required for I/O buffers #define ATF_MAXCOLUMNS 8000 // maximum size of read & write buffers (each can be this size) #define ATF_MAX_BUFFER_SIZE 65536 // Flags that may be combined and passed in the wFlags to ATF_OpenFile call #define ATF_WRITEONLY 0 #define ATF_READONLY 1 #define ATF_OVERWRTIFEXIST 2 #define ATF_APPENDIFEXIST 4 #define ATF_DONTWRITEHEADER 8 // Value returned as the file handle if the file could not be opened. #define ATF_INVALID_HANDLE -1 // Definitions for error results returned by AXATFFIO32 module #define ATF_SUCCESS 0 #define ATF_ERROR_NOFILE 1001 #define ATF_ERROR_TOOMANYFILES 1002 #define ATF_ERROR_FILEEXISTS 1003 #define ATF_ERROR_BADVERSION 1004 #define ATF_ERROR_BADFILENUM 1005 #define ATF_ERROR_BADSTATE 1006 #define ATF_ERROR_IOERROR 1007 #define ATF_ERROR_NOMORE 1008 #define ATF_ERROR_BADHEADER 1009 #define ATF_ERROR_NOMEMORY 1012 #define ATF_ERROR_TOOMANYCOLS 1013 #define ATF_ERROR_INVALIDFILE 1014 #define ATF_ERROR_BADCOLNUM 1015 #define ATF_ERROR_LINETOOLONG 1016 #define ATF_ERROR_BADFLTCNV 1017 #define ATF_ERROR_NOMESSAGESTR 2000 // These functions are not exported from the DLL version as they are called implicitly on load/unload. BOOL WINAPI ATF_Initialize(HINSTANCE hDLL); void WINAPI ATF_Cleanup(void); //---------------------- Exported Function Definitions ------------------------- BOOL WINAPI ATF_OpenFile(LPCSTR szFileName, UINT uFlags, int *pnColumns, int *pnFile, int *pnError); BOOL WINAPI ATF_CloseFile(int nFile); BOOL WINAPI ATF_SetSeperator(int nFile, BOOL bUseCommas, int *pnError); BOOL WINAPI ATF_IsAppending(int nFile); BOOL WINAPI ATF_RewindFile(int nFile, int *pnError); BOOL WINAPI ATF_CountDataLines(int nFile, long *plNumLines, int *pnError); BOOL WINAPI ATF_GetNumHeaders(int nFile, int *pnHeaders, int *pnError); BOOL WINAPI ATF_WriteHeaderRecord(int nFile, LPCSTR pszText, int *pnError); BOOL WINAPI ATF_SetColumnTitle(int nFile, LPCSTR pszText, int *pnError); BOOL WINAPI ATF_SetColumnUnits(int nFile, LPCSTR pszText, int *pnError); BOOL WINAPI ATF_WriteEndOfLine(int nFile, int *pnError); BOOL WINAPI ATF_WriteDataRecord(int nFile, LPCSTR pszText, int *pnError); BOOL WINAPI ATF_WriteDataComment(int nFile, LPCSTR pszText, int *pnError); BOOL WINAPI ATF_WriteDataRecordArray(int nFile, int nCount, double *pdVals, int *pnError); BOOL WINAPI ATF_WriteDataRecordArrayFloat(int nFile, int nCount, float *pfVals, int *pnError); BOOL WINAPI ATF_WriteDataRecord1(int nFile, double dNum1, int *pnError); BOOL WINAPI ATF_WriteDataRecord1Float(int nFile, float fNum1, int *pnError); BOOL WINAPI ATF_ReadHeaderLine(int nFile, char *psBuf, int nMaxLen, int *pnError); BOOL WINAPI ATF_ReadHeaderNoQuotes(int nFile, char *psBuf, int nMaxLen, int *pnError); BOOL WINAPI ATF_GetColumnTitle(int nFile, int nColumn, char *pszText, int nMaxTxt, int *pnError); BOOL WINAPI ATF_GetColumnUnits(int nFile, int nColumn, char *pszText, int nMaxTxt, int *pnError); BOOL WINAPI ATF_ReadDataRecord(int nFile, char *pszText, int nMaxLen, int *pnError); BOOL WINAPI ATF_ReadDataRecordArray(int nFile, int nCount, double *pdVals, char *pszComment, int nMaxLen, int *pnError); BOOL WINAPI ATF_ReadDataColumn(int nFile, int nColumn, double *pdVal, int *pnError); int WINAPI ATF_BuildErrorText(int nErrorNum, LPCSTR szFileName, char *sTxtBuf, int nMaxLen); BOOL WINAPI ATF_GetFileDateTime(int nFile, long *plDate, long *plTime, int *pnError); #ifdef __cplusplus } #endif #endif /* INC_AXATFFIO32_H */ stimfit-0.16.7/src/libstfio/abf/axon/AxAtfFio32/atfutil.h0000775000175000017500000000204614750344764016520 /****************************************************************************\ * * * Written 1990 - 1995 by AXON Instruments Inc. * * * * This file is not protected by copyright. You are free to use, modify * * and copy the code in this file. * * * \****************************************************************************/ // // HEADER: ATFUTIL.H Prototypes for functions in ATFUTIL.CPP // AUTHOR: BHI Feb 1995 #ifndef __ATFUTIL_H__ #define __ATFUTIL_H__ #if !defined(_WINDOWS) || defined(__MINGW32__) int LoadString( HINSTANCE hInstance, int nErrorNum, char *sTxtBuf, UINT uMaxLen); #endif extern HINSTANCE g_hInstance; #if defined(_WINDOWS) && !defined(__MINGW32__) #include "./../Common/resource.h" #endif #endif stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/0000775000175000017500000000000014764352501014721 5stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/oldheadr.h0000775000175000017500000000200614750344764016604 //*********************************************************************************************** // // Copyright (c) 1993-1997 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // HEADER: OLDHEADR.H. // PURPOSE: Provides prototypes for functions implemented in OLDHEADR.CPP for // reading old ABF file header. #ifndef __OLDHEADR_H__ #define __OLDHEADR_H__ BOOL OLDH_GetFileVersion( FILEHANDLE hFile, UINT *puFileType, float *pfFileVersion, BOOL *pbMSBinFormat); void OLDH_ABFtoCurrentVersion(ABFFileHeader *pFH); /* void OLDH_CorrectScopeConfig(ABFFileHeader *pFH, ABFScopeConfig *pCfg); */ BOOL OLDH_ReadOldHeader( FILEHANDLE hFile, UINT uFileType, int bMSBinFormat, ABFFileHeader *pFH, ABFLONG lFileLength, int *pnError); #endif /* __OLDHEADR_H__ */ stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/AxAbffio32.h0000775000175000017500000000150114750344764016645 //*********************************************************************************************** // // Copyright (c) 1997 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // HEADER: AXABFFIO32.H. // PURPOSE: Defines the export/import specifiers used by all functions // exported by this DLL. #ifndef INC_AXABFFIO32_H #define INC_AXABFFIO32_H // __declspec(dllexport) retired for DLLs given to 3rd parties because of the name mangling on exports. #include #if ( __WORDSIZE == 64 ) || defined (__APPLE__) #define ABFLONG int #else #define ABFLONG long #endif #endif /* INC_AXABFFIO32_H */ stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/msbincvt.cpp0000775000175000017500000000622514750344764017211 //*********************************************************************************************** // // Copyright (c) 1993-1997 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // MODULE: MSBINCVT.CPP // PURPOSE: Provides functions to convert 4-byte floating point numbers // from Microsoft Binary format to IEEE format and vice-versa. // REFERENCES: // MASM 5.1 programmer's guide (does not mention IEEE bias) // /***************************************************************************** ** ** The Microsoft 4-byte real format looks like this: ** ** Byte 3 Byte 2 Byte 1 Byte 0 ** 76543210 76543210 76543210 76543210 ** EEEEEEEE SMMMMMMM MMMMMMMM MMMMMMMM ** ** The exponent occupies the 8 bits of byte 3. This is a biased exponent, ** the bias is 0x81. ** The sign bit is bit 7 of byte 2. 0 denotes positive, 1 negative. ** The mantissa is in the remaining 23 bits. ** ** It seems (from single steppong through the _fmsbintoieee() function in ** the Microsoft C++ runtime libraby) that a number is deemed to be zero ** if its exponent is less than (unsigned)2. ** ** ** The IEEE 4-byte real format looks like this: ** ** Byte 3 Byte 2 Byte 1 Byte 0 ** 76543210 76543210 76543210 76543210 ** SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM ** ** The sign bit is bit 7 of byte 3. 0 denotes positive, 1 negative. ** The exponent occupies the the lower 7 bits of byte 3 and bit 7 of byte 2. ** This is a biased exponent, the bias is 0x7f. ** The mantissa is in the remaining 23 bits. ** *****************************************************************************/ #include "../Common/wincpp.hpp" #include "msbincvt.h" struct IEEEBITS { unsigned mantissaLo:16; unsigned mantissaHi:7; unsigned exponent:8; unsigned sign:1; }; typedef union { float fVal; struct IEEEBITS bits; } IEEEFLOAT; struct MSBBITS { unsigned mantissaLo:16; unsigned mantissaHi:7; unsigned sign:1; unsigned exponent:8; }; typedef union { float fVal; struct MSBBITS bits; } MSBFLOAT; void fMSBintoIeee(float *pfIn, float *pfOut) { MSBFLOAT msb; msb.fVal = *pfIn; if (msb.bits.exponent < 2) { *pfOut = 0.0F; return; } IEEEFLOAT ieee; ieee.bits.sign = msb.bits.sign; ieee.bits.exponent = msb.bits.exponent - 0x81 + 0x7F; ieee.bits.mantissaLo = msb.bits.mantissaLo; ieee.bits.mantissaHi = msb.bits.mantissaHi; *pfOut = ieee.fVal; } void fIeeetoMSBin(float *pfIn, float *pfOut) { IEEEFLOAT ieee; ieee.fVal = *pfIn; if (ieee.fVal == 0.0F) /* Zero is a special case - same in both formats. */ { *pfOut = 0.0F; return; } MSBFLOAT msb; msb.bits.sign = ieee.bits.sign; msb.bits.exponent = ieee.bits.exponent - 0x7F + 0x81; msb.bits.mantissaLo = ieee.bits.mantissaLo; msb.bits.mantissaHi = ieee.bits.mantissaHi; *pfOut = msb.fVal; } stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/abfheadr.h0000775000175000017500000016677014750344764016601 //*********************************************************************************************** // // Copyright (c) 1993-2003 Axon Instruments. // All rights reserved. // Permission is granted to freely use, modify and copy the code in this file. // //*********************************************************************************************** // HEADER: ABFHEADR.H. // PURPOSE: Defines the ABFFileHeader structure, and provides prototypes for // functions implemented in ABFHEADR.CPP for reading and writing // ABFFileHeader's. // REVISIONS: // 1.1 - Version 1.1 was released in April 1992. // 1.2 - Added nDataFormat so that data can optionally be stored in floating point format. // - Added lClockChange to control the multiplexed ADC sample number after which the second sampling interval commences. // 1.3 - Change 4-byte sFileType string to long lFileSignature. // - #define ABF_NATIVESIGNATURE & ABF_REVERSESIGNATURE for byte order detection. // - Added support for Bells during before or after acquisitions // - Added parameters to describe hysteresis during event detected acquisitions: nLevelHysteresis and lTimeHysteresis. // - Dropped support for BASIC and Pascal. // - Added the ABF Scope Config section to store scope configuration information // 1.4 - Remove support for big-endian machines. // 1.5 - Change ABFSignal parameters from UUTop & UUBottom to // fDisplayGain & fDisplayOffset. // - Added and changed parameters in the 'File Structure', 'Display Parameters', // 'DAC Output File', 'Autopeak Measurements' and 'Unused space and end of header' sections of the ABF file header. // - Expanded the ABF API and error return codes // 1.6 - Expanded header to 5120 bytes and added extra parameters to support 2 waveform channels PRC // 1.65 - Telegraph support added. // 1.67 - Train epochs, multiple channel and multiple region stats // 1.68 - ABFScopeConfig expanded // 1.69 - Added user entered percentile levels for rise and decay stats // 1.70 - Added data reduction - AjD // 1.71 - Added epoch resistance // 1.72 - Added alternating outputs // 1.73 - Added post-processing lowpass filter settings. When filtering is done in Clampfit it is stored in the header. // 1.74 - Added channel_count_acquired // 1.75 - Added polarity for each channel // 1.76 - Added digital trigger out flag // 1.77 - Added major, minor and bugfix version numbers // 1.78 - Added separate entries for alternating DAC and digital outputs // 1.79 - Removed data reduction (now minidigi only) // 1.80 - Added stats mode for each region: mode is cursor region, epoch etc // 1.81 - Added multi input signal P / N leak subtraction // 1.82 - Cyclic Redundancy Code (CRC). // 1.83 - Added Modifier application name / version number // // Added 64bit support according to Jakub Nowacki's implementation in libaxon: // http://libaxon.sourceforge.net #ifndef INC_ABFHEADR_H #define INC_ABFHEADR_H #include #include #include "AxAbffio32.h" #ifdef __cplusplus extern "C" { #endif // // Constants used in defining the ABF file header // #define ABF_ADCCOUNT 16 // number of ADC channels supported. #define ABF_DACCOUNT 4 // number of DAC channels supported. #define ABF_WAVEFORMCOUNT 2 // number of DAC channels which support waveforms. #define ABF_EPOCHCOUNT 10 // number of waveform epochs supported. #define ABF_BELLCOUNT 2 // Number of auditory signals supported. #define ABF_ADCUNITLEN 8 // length of ADC units strings #define ABF_ADCNAMELEN 10 // length of ADC channel name strings #define ABF_DACUNITLEN 8 // length of DAC units strings #define ABF_DACNAMELEN 10 // length of DAC channel name strings #define ABF_VARPARAMLISTLEN 80 // length of conditioning string #define ABF_USERLISTLEN 256 // length of the user list (V1.6) #define ABF_USERLISTCOUNT 4 // number of independent user lists (V1.6) #define ABF_OLDFILECOMMENTLEN 56 // length of file comment string (pre V1.6) #define ABF_FILECOMMENTLEN 128 // length of file comment string (V1.6) #define ABF_CREATORINFOLEN 16 // length of file creator info string #define ABF_OLDDACFILENAMELEN 12 // old length of the DACFile name string #define ABF_OLDDACFILEPATHLEN 60 // old length of the DACFile path string #define ABF_DACFILEPATHLEN 84 // length of full path for DACFile #define ABF_PATHLEN 256 // length of full path, used for DACFile and Protocol name. #define ABF_ARITHMETICOPLEN 2 // length of the Arithmetic operator field #define ABF_ARITHMETICUNITSLEN 8 // length of arithmetic units string #define ABF_TAGCOMMENTLEN 56 // length of tag comment string #define ABF_LONGDESCRIPTIONLEN 56 // length of long description entry #define ABF_NOTENAMELEN 10 // length of the name component of a note #define ABF_NOTEVALUELEN 8 // length of the value component of a note #define ABF_NOTEUNITSLEN 8 // length of the units component of a note #define ABF_BLOCKSIZE 512 // Size of block alignment in ABF files. #define ABF_MACRONAMELEN 64 // Size of a Clampfit macro name. #define ABF_CURRENTVERSION ABF_V183 // Current file format version number #define ABF_PREVIOUSVERSION 1.5F // Previous file format version number (for old header size) #define ABF_V16 1.6F // Version number when the header size changed. #define ABF_HEADERSIZE 6144 // Size of a Version 1.6 or later header #define ABF_OLDHEADERSIZE 2048 // Size of a Version 1.5 or earlier header #define ABF_NATIVESIGNATURE 0x20464241 // PC="ABF ", MAC=" FBA" #define ABF_REVERSESIGNATURE 0x41424620 // PC=" FBA", MAC="ABF " #define PCLAMP6_MAXSWEEPLENGTH 16384 // Maximum multiplexed sweep length supported by pCLAMP6 apps. #define PCLAMP7_MAXSWEEPLEN_PERCHAN 1032258 // Maximum per channel sweep length supported by pCLAMP7 apps. #define ABF_MAX_TRIAL_SAMPLES 0x7FFFFFFF // Maximum length of acquisition supported (samples) // INT_MAX is used instead of UINT_MAX because of the signed // values in the ABF header. #define ABF_MAX_SWEEPS_PER_AVERAGE 65500 // The maximum number of sweeps that can be combined into a // cumulative average (nAverageAlgorithm=ABF_INFINITEAVERAGE). #define ABF_STATS_REGIONS 8 // The number of independent statistics regions. #define ABF_BASELINE_REGIONS 1 // The number of independent baseline regions. #ifdef _MAC #define ABF_OLDPCLAMP ABF_REVERSESIGNATURE #else #define ABF_OLDPCLAMP ABF_NATIVESIGNATURE #endif // // Constant definitions for nFileType // #define ABF_ABFFILE 1 #define ABF_FETCHEX 2 #define ABF_CLAMPEX 3 // // Constant definitions for nDataFormat // #define ABF_INTEGERDATA 0 #define ABF_FLOATDATA 1 // // Constant definitions for nOperationMode // #define ABF_VARLENEVENTS 1 #define ABF_FIXLENEVENTS 2 // (ABF_FIXLENEVENTS == ABF_LOSSFREEOSC) #define ABF_LOSSFREEOSC 2 #define ABF_GAPFREEFILE 3 #define ABF_HIGHSPEEDOSC 4 #define ABF_WAVEFORMFILE 5 // // Constant definitions for nParamToVary // #define ABF_CONDITNUMPULSES 0 #define ABF_CONDITBASELINEDURATION 1 #define ABF_CONDITBASELINELEVEL 2 #define ABF_CONDITSTEPDURATION 3 #define ABF_CONDITSTEPLEVEL 4 #define ABF_CONDITPOSTTRAINDURATION 5 #define ABF_CONDITPOSTTRAINLEVEL 6 #define ABF_EPISODESTARTTOSTART 7 #define ABF_INACTIVEHOLDING 8 #define ABF_DIGITALHOLDING 9 #define ABF_PNNUMPULSES 10 #define ABF_PARALLELVALUE 11 #define ABF_EPOCHINITLEVEL (ABF_PARALLELVALUE + ABF_EPOCHCOUNT) #define ABF_EPOCHINITDURATION (ABF_EPOCHINITLEVEL + ABF_EPOCHCOUNT) #define ABF_EPOCHTRAINPERIOD (ABF_EPOCHINITDURATION + ABF_EPOCHCOUNT) #define ABF_EPOCHTRAINPULSEWIDTH (ABF_EPOCHTRAINPERIOD + ABF_EPOCHCOUNT) // Next value is (ABF_EPOCHINITDURATION + ABF_EPOCHCOUNT) // // Constants for nAveragingMode // #define ABF_NOAVERAGING 0 #define ABF_SAVEAVERAGEONLY 1 #define ABF_AVERAGESAVEALL 2 // // Constants for nAverageAlgorithm // #define ABF_INFINITEAVERAGE 0 #define ABF_SLIDINGAVERAGE 1 // // Constants for nEpochType // #define ABF_EPOCHDISABLED 0 // disabled epoch #define ABF_EPOCHSTEPPED 1 // stepped waveform #define ABF_EPOCHRAMPED 2 // ramp waveform #define ABF_EPOCH_TYPE_RECTANGLE 3 // rectangular pulse train #define ABF_EPOCH_TYPE_TRIANGLE 4 // triangular waveform #define ABF_EPOCH_TYPE_COSINE 5 // cosinusoidal waveform #define ABF_EPOCH_TYPE_RESISTANCE 6 // resistance waveform #define ABF_EPOCH_TYPE_BIPHASIC 7 // biphasic pulse train // // Constants for epoch resistance // #define ABF_MIN_EPOCH_RESISTANCE_DURATION 8 // // Constants for nWaveformSource // #define ABF_WAVEFORMDISABLED 0 // disabled waveform #define ABF_EPOCHTABLEWAVEFORM 1 #define ABF_DACFILEWAVEFORM 2 // // Constants for nInterEpisodeLevel & nDigitalInterEpisode // #define ABF_INTEREPI_USEHOLDING 0 #define ABF_INTEREPI_USELASTEPOCH 1 // // Constants for nExperimentType // #define ABF_VOLTAGECLAMP 0 #define ABF_CURRENTCLAMP 1 #define ABF_SIMPLEACQUISITION 2 // // Constants for nAutosampleEnable // #define ABF_AUTOSAMPLEDISABLED 0 #define ABF_AUTOSAMPLEAUTOMATIC 1 #define ABF_AUTOSAMPLEMANUAL 2 // // Constants for nAutosampleInstrument // #define ABF_INST_UNKNOWN 0 // Unknown instrument (manual or user defined telegraph table). #define ABF_INST_AXOPATCH1 1 // Axopatch-1 with CV-4-1/100 #define ABF_INST_AXOPATCH1_1 2 // Axopatch-1 with CV-4-0.1/100 #define ABF_INST_AXOPATCH1B 3 // Axopatch-1B(inv.) CV-4-1/100 #define ABF_INST_AXOPATCH1B_1 4 // Axopatch-1B(inv) CV-4-0.1/100 #define ABF_INST_AXOPATCH201 5 // Axopatch 200 with CV 201 #define ABF_INST_AXOPATCH202 6 // Axopatch 200 with CV 202 #define ABF_INST_GENECLAMP 7 // GeneClamp #define ABF_INST_DAGAN3900 8 // Dagan 3900 #define ABF_INST_DAGAN3900A 9 // Dagan 3900A #define ABF_INST_DAGANCA1_1 10 // Dagan CA-1 Im=0.1 #define ABF_INST_DAGANCA1 11 // Dagan CA-1 Im=1.0 #define ABF_INST_DAGANCA10 12 // Dagan CA-1 Im=10 #define ABF_INST_WARNER_OC725 13 // Warner OC-725 #define ABF_INST_WARNER_OC725C 14 // Warner OC-725 #define ABF_INST_AXOPATCH200B 15 // Axopatch 200B #define ABF_INST_DAGANPCONE0_1 16 // Dagan PC-ONE Im=0.1 #define ABF_INST_DAGANPCONE1 17 // Dagan PC-ONE Im=1.0 #define ABF_INST_DAGANPCONE10 18 // Dagan PC-ONE Im=10 #define ABF_INST_DAGANPCONE100 19 // Dagan PC-ONE Im=100 #define ABF_INST_WARNER_BC525C 20 // Warner BC-525C #define ABF_INST_WARNER_PC505 21 // Warner PC-505 #define ABF_INST_WARNER_PC501 22 // Warner PC-501 #define ABF_INST_DAGANCA1_05 23 // Dagan CA-1 Im=0.05 #define ABF_INST_MULTICLAMP700 24 // MultiClamp 700 #define ABF_INST_TURBO_TEC 25 // Turbo Tec #define ABF_INST_OPUSXPRESS6000 26 // OpusXpress 6000A // // Constants for nManualInfoStrategy // #define ABF_ENV_DONOTWRITE 0 #define ABF_ENV_WRITEEACHTRIAL 1 #define ABF_ENV_PROMPTEACHTRIAL 2 // // Constants for nTriggerSource // #define ABF_TRIGGERLINEINPUT -5 // Start on line trigger (DD1320 only) #define ABF_TRIGGERTAGINPUT -4 #define ABF_TRIGGERFIRSTCHANNEL -3 #define ABF_TRIGGEREXTERNAL -2 #define ABF_TRIGGERSPACEBAR -1 // >=0 = ADC channel to trigger off. // // Constants for nTrialTriggerSource // #define ABF_TRIALTRIGGER_SWSTARTONLY -6 // Start on software message, end when protocol ends. #define ABF_TRIALTRIGGER_SWSTARTSTOP -5 // Start and end on software messages. #define ABF_TRIALTRIGGER_LINEINPUT -4 // Start on line trigger (DD1320 only) #define ABF_TRIALTRIGGER_SPACEBAR -3 // Start on spacebar press. #define ABF_TRIALTRIGGER_EXTERNAL -2 // Start on external trigger high #define ABF_TRIALTRIGGER_NONE -1 // Start immediately (default). // >=0 = ADC channel to trigger off. // Not implemented as yet... // // Constants for nTriggerPolarity. // #define ABF_TRIGGER_RISINGEDGE 0 #define ABF_TRIGGER_FALLINGEDGE 1 // // Constants for nTriggerAction // #define ABF_TRIGGER_STARTEPISODE 0 #define ABF_TRIGGER_STARTRUN 1 #define ABF_TRIGGER_STARTTRIAL 2 // N.B. Discontinued in favor of nTrialTriggerSource // // Constants for nDrawingStrategy // #define ABF_DRAW_NONE 0 #define ABF_DRAW_REALTIME 1 #define ABF_DRAW_FULLSCREEN 2 #define ABF_DRAW_ENDOFRUN 3 // // Constants for nTiledDisplay // #define ABF_DISPLAY_SUPERIMPOSED 0 #define ABF_DISPLAY_TILED 1 // // Constants for nDataDisplayMode // #define ABF_DRAW_POINTS 0 #define ABF_DRAW_LINES 1 // // Constants for nArithmeticExpression // #define ABF_SIMPLE_EXPRESSION 0 #define ABF_RATIO_EXPRESSION 1 // // Constants for nLowpassFilterType & nHighpassFilterType // #define ABF_FILTER_NONE 0 #define ABF_FILTER_EXTERNAL 1 #define ABF_FILTER_SIMPLE_RC 2 #define ABF_FILTER_BESSEL 3 #define ABF_FILTER_BUTTERWORTH 4 // // Constants for nPNPosition // #define ABF_PN_BEFORE_EPISODE 0 #define ABF_PN_AFTER_EPISODE 1 // // Constants for nPNPolarity // #define ABF_PN_OPPOSITE_POLARITY -1 #define ABF_PN_SAME_POLARITY 1 // // Constants for nAutopeakPolarity // #define ABF_PEAK_NEGATIVE -1 #define ABF_PEAK_ABSOLUTE 0 #define ABF_PEAK_POSITIVE 1 // // Constants for nAutopeakSearchMode // #define ABF_PEAK_SEARCH_SPECIFIED -2 #define ABF_PEAK_SEARCH_ALL -1 // nAutopeakSearchMode 0..9 = epoch in waveform 0's epoch table // nAutopeakSearchMode 10..19 = epoch in waveform 1's epoch table // // Constants for nAutopeakBaseline // #define ABF_PEAK_BASELINE_SPECIFIED -3 #define ABF_PEAK_BASELINE_NONE -2 #define ABF_PEAK_BASELINE_FIRSTHOLDING -1 #define ABF_PEAK_BASELINE_LASTHOLDING -4 // // Constants for lAutopeakMeasurements // #define ABF_PEAK_MEASURE_PEAK 0x00000001 #define ABF_PEAK_MEASURE_PEAKTIME 0x00000002 #define ABF_PEAK_MEASURE_ANTIPEAK 0x00000004 #define ABF_PEAK_MEASURE_ANTIPEAKTIME 0x00000008 #define ABF_PEAK_MEASURE_MEAN 0x00000010 #define ABF_PEAK_MEASURE_STDDEV 0x00000020 #define ABF_PEAK_MEASURE_INTEGRAL 0x00000040 #define ABF_PEAK_MEASURE_MAXRISESLOPE 0x00000080 #define ABF_PEAK_MEASURE_MAXRISESLOPETIME 0x00000100 #define ABF_PEAK_MEASURE_MAXDECAYSLOPE 0x00000200 #define ABF_PEAK_MEASURE_MAXDECAYSLOPETIME 0x00000400 #define ABF_PEAK_MEASURE_RISETIME 0x00000800 #define ABF_PEAK_MEASURE_DECAYTIME 0x00001000 #define ABF_PEAK_MEASURE_HALFWIDTH 0x00002000 #define ABF_PEAK_MEASURE_BASELINE 0x00004000 #define ABF_PEAK_MEASURE_RISESLOPE 0x00008000 #define ABF_PEAK_MEASURE_DECAYSLOPE 0x00010000 #define ABF_PEAK_MEASURE_REGIONSLOPE 0x00020000 #define ABF_PEAK_MEASURE_ALL 0x0002FFFF // All of the above OR'd together. // // Constants for nStatsActiveChannels // #define ABF_PEAK_SEARCH_CHANNEL0 0x0001 #define ABF_PEAK_SEARCH_CHANNEL1 0x0002 #define ABF_PEAK_SEARCH_CHANNEL2 0x0004 #define ABF_PEAK_SEARCH_CHANNEL3 0x0008 #define ABF_PEAK_SEARCH_CHANNEL4 0x0010 #define ABF_PEAK_SEARCH_CHANNEL5 0x0020 #define ABF_PEAK_SEARCH_CHANNEL6 0x0040 #define ABF_PEAK_SEARCH_CHANNEL7 0x0080 #define ABF_PEAK_SEARCH_CHANNEL8 0x0100 #define ABF_PEAK_SEARCH_CHANNEL9 0x0200 #define ABF_PEAK_SEARCH_CHANNEL10 0x0400 #define ABF_PEAK_SEARCH_CHANNEL11 0x0800 #define ABF_PEAK_SEARCH_CHANNEL12 0x1000 #define ABF_PEAK_SEARCH_CHANNEL13 0x2000 #define ABF_PEAK_SEARCH_CHANNEL14 0x4000 #define ABF_PEAK_SEARCH_CHANNEL15 0x8000 #define ABF_PEAK_SEARCH_CHANNELSALL 0xFFFF // All of the above OR'd together. // Bit flag settings for nStatsSearchRegionFlags // #define ABF_PEAK_SEARCH_REGION0 0x01 #define ABF_PEAK_SEARCH_REGION1 0x02 #define ABF_PEAK_SEARCH_REGION2 0x04 #define ABF_PEAK_SEARCH_REGION3 0x08 #define ABF_PEAK_SEARCH_REGION4 0x10 #define ABF_PEAK_SEARCH_REGION5 0x20 #define ABF_PEAK_SEARCH_REGION6 0x40 #define ABF_PEAK_SEARCH_REGION7 0x80 #define ABF_PEAK_SEARCH_REGIONALL 0xFF // All of the above OR'd together. // // Constants for lStatisticsMeasurements // #define ABF_STATISTICS_ABOVETHRESHOLD 0x00000001 #define ABF_STATISTICS_EVENTFREQUENCY 0x00000002 #define ABF_STATISTICS_MEANOPENTIME 0x00000004 #define ABF_STATISTICS_MEANCLOSEDTIME 0x00000008 #define ABF_STATISTICS_ALL 0x0000000F // All the above OR'd together. // // Constants for nStatisticsSaveStrategy // #define ABF_STATISTICS_NOAUTOSAVE 0 #define ABF_STATISTICS_AUTOSAVE 1 #define ABF_STATISTICS_AUTOSAVE_AUTOCLEAR 2 // // Constants for nStatisticsDisplayStrategy // #define ABF_STATISTICS_DISPLAY 0 #define ABF_STATISTICS_NODISPLAY 1 // // Constants for nStatisticsClearStrategy // determines whether to clear statistics after saving. // #define ABF_STATISTICS_NOCLEAR 0 #define ABF_STATISTICS_CLEAR 1 // // Constants for nDACFileEpisodeNum // #define ABF_DACFILE_SKIPFIRSTSWEEP -1 #define ABF_DACFILE_USEALLSWEEPS 0 // >0 = The specific sweep number. // // Constants for nUndoPromptStrategy // #define ABF_UNDOPROMPT_ONABORT 0 #define ABF_UNDOPROMPT_ALWAYS 1 // // Constants for nAutoAnalyseEnable // #define ABF_AUTOANALYSE_DISABLED 0 #define ABF_AUTOANALYSE_DEFAULT 1 #define ABF_AUTOANALYSE_RUNMACRO 2 // // Constants for post nPostprocessLowpassFilterType // #define ABF_POSTPROCESS_FILTER_NONE 0 #define ABF_POSTPROCESS_FILTER_ADAPTIVE 1 #define ABF_POSTPROCESS_FILTER_BESSEL 2 #define ABF_POSTPROCESS_FILTER_BOXCAR 3 #define ABF_POSTPROCESS_FILTER_BUTTERWORTH 4 #define ABF_POSTPROCESS_FILTER_CHEBYSHEV 5 #define ABF_POSTPROCESS_FILTER_GAUSSIAN 6 #define ABF_POSTPROCESS_FILTER_RC 7 #define ABF_POSTPROCESS_FILTER_RC8 8 #define ABF_POSTPROCESS_FILTER_NOTCH 9 // // Miscellaneous constants // #define ABF_FILTERDISABLED 100000.0F // Large frequency to disable lowpass filters #define ABF_UNUSED_CHANNEL -1 // Unused ADC and DAC channels. // // The output sampling sequence identifier for a seperate digital out channel. // #define ABF_DIGITAL_OUT_CHANNEL -1 #define ABF_PADDING_OUT_CHANNEL -2 // // maximum values for various parameters (used by ABFH_CheckUserList). // #define ABF_CTPULSECOUNT_MAX 10000 #define ABF_CTBASELINEDURATION_MAX 100000.0F #define ABF_CTSTEPDURATION_MAX 100000.0F #define ABF_CTPOSTTRAINDURATION_MAX 100000.0F #define ABF_SWEEPSTARTTOSTARTTIME_MAX 100000.0F #define ABF_PNPULSECOUNT_MAX 8 #define ABF_DIGITALVALUE_MAX 0xFF #define ABF_EPOCHDIGITALVALUE_MAX 0x0F // // LTP Types - Reflects whether the header is used for LTP as baseline or induction. // #define ABF_LTP_TYPE_NONE 0 #define ABF_LTP_TYPE_BASELINE 1 #define ABF_LTP_TYPE_INDUCTION 2 // // LTP Usage of DAC - Reflects whether the analog output will be used presynaptically or postsynaptically. // #define ABF_LTP_DAC_USAGE_NONE 0 #define ABF_LTP_DAC_USAGE_PRESYNAPTIC 1 #define ABF_LTP_DAC_USAGE_POSTSYNAPTIC 2 // // Header Version Numbers // #define ABF_V166 1.66F #define ABF_V167 1.67F #define ABF_V168 1.68F #define ABF_V169 1.69F #define ABF_V170 1.70F #define ABF_V171 1.71F #define ABF_V172 1.72F #define ABF_V173 1.73F #define ABF_V174 1.74F #define ABF_V175 1.75F #define ABF_V176 1.76F #define ABF_V177 1.77F #define ABF_V178 1.78F #define ABF_V179 1.79F #define ABF_V180 1.80F #define ABF_V181 1.81F #define ABF_V182 1.82F #define ABF_V183 1.83F // // pack structure on byte boundaries // #ifndef RC_INVOKED #pragma pack(push, 1) #endif // // Definition of the ABF header structure. // struct ABFFileHeader // The total header length = 6144 bytes. { public: // GROUP #1 - File ID and size information. (40 bytes) ABFLONG lFileSignature; float fFileVersionNumber; short nOperationMode; ABFLONG lActualAcqLength; short nNumPointsIgnored; ABFLONG lActualEpisodes; ABFLONG lFileStartDate; // YYYYMMDD ABFLONG lFileStartTime; ABFLONG lStopwatchTime; float fHeaderVersionNumber; short nFileType; short nMSBinFormat; // GROUP #2 - File Structure (78 bytes) ABFLONG lDataSectionPtr; ABFLONG lTagSectionPtr; ABFLONG lNumTagEntries; ABFLONG lScopeConfigPtr; ABFLONG lNumScopes; ABFLONG _lDACFilePtr; ABFLONG _lDACFileNumEpisodes; char sUnused001[4]; ABFLONG lDeltaArrayPtr; ABFLONG lNumDeltas; ABFLONG lVoiceTagPtr; ABFLONG lVoiceTagEntries; ABFLONG lUnused002; ABFLONG lSynchArrayPtr; ABFLONG lSynchArraySize; short nDataFormat; short nSimultaneousScan; ABFLONG lStatisticsConfigPtr; ABFLONG lAnnotationSectionPtr; ABFLONG lNumAnnotations; char sUnused003[2]; // GROUP #3 - Trial hierarchy information (82 bytes) /** The number of input channels we acquired. Do not access directly - use CABFHeader::get_channel_count_acquired */ short channel_count_acquired; /** The number of input channels we recorded. Do not access directly - use CABFHeader::get_channel_count_recorded */ short nADCNumChannels; float fADCSampleInterval; /*{{ The documentation says these two sample intervals are the interval between multiplexed samples, but not all digitisers work like that. Instead, these are the per-channel sample rate divided by the number of channels. If the user chose 100uS and has two channels, this value will be 50uS. }}*/ float fADCSecondSampleInterval; /*{{ // The two sample intervals must be an integer multiple (or submultiple) of each other. if (fADCSampleInterval > fADCSecondSampleInterval) ASSERT(fmod(fADCSampleInterval, fADCSecondSampleInterval) == 0.0); if (fADCSecondSampleInterval, fADCSampleInterval) ASSERT(fmod(fADCSecondSampleInterval, fADCSampleInterval) == 0.0); }}*/ float fSynchTimeUnit; float fSecondsPerRun; /** * The total number of samples per episode, for the recorded channels only. * This does not include channels which are acquired but not recorded. * * This is the number of samples per episode per channel, times the number of recorded channels. * * If you want the samples per episode for one channel, you must divide this by get_channel_count_recorded(). */ ABFLONG lNumSamplesPerEpisode; ABFLONG lPreTriggerSamples; ABFLONG lEpisodesPerRun; ABFLONG lRunsPerTrial; ABFLONG lNumberOfTrials; short nAveragingMode; short nUndoRunCount; short nFirstEpisodeInRun; float fTriggerThreshold; short nTriggerSource; short nTriggerAction; short nTriggerPolarity; float fScopeOutputInterval; float fEpisodeStartToStart; float fRunStartToStart; float fTrialStartToStart; ABFLONG lAverageCount; ABFLONG lClockChange; short nAutoTriggerStrategy; // GROUP #4 - Display Parameters (44 bytes) short nDrawingStrategy; short nTiledDisplay; short nEraseStrategy; // N.B. Discontinued. Use scope config entry instead. short nDataDisplayMode; ABFLONG lDisplayAverageUpdate; short nChannelStatsStrategy; ABFLONG lCalculationPeriod; // N.B. Discontinued. Use fStatisticsPeriod. ABFLONG lSamplesPerTrace; ABFLONG lStartDisplayNum; ABFLONG lFinishDisplayNum; short nMultiColor; short nShowPNRawData; float fStatisticsPeriod; ABFLONG lStatisticsMeasurements; short nStatisticsSaveStrategy; // GROUP #5 - Hardware information (16 bytes) float fADCRange; float fDACRange; ABFLONG lADCResolution; ABFLONG lDACResolution; // GROUP #6 Environmental Information (118 bytes) short nExperimentType; short _nAutosampleEnable; short _nAutosampleADCNum; short _nAutosampleInstrument; float _fAutosampleAdditGain; float _fAutosampleFilter; float _fAutosampleMembraneCap; short nManualInfoStrategy; float fCellID1; float fCellID2; float fCellID3; char sCreatorInfo[ABF_CREATORINFOLEN]; char _sFileComment[ABF_OLDFILECOMMENTLEN]; short nFileStartMillisecs; // Milliseconds portion of lFileStartTime short nCommentsEnable; char sUnused003a[8]; // GROUP #7 - Multi-channel information (1044 bytes) short nADCPtoLChannelMap[ABF_ADCCOUNT]; short nADCSamplingSeq[ABF_ADCCOUNT]; char sADCChannelName[ABF_ADCCOUNT][ABF_ADCNAMELEN]; char sADCUnits[ABF_ADCCOUNT][ABF_ADCUNITLEN]; float fADCProgrammableGain[ABF_ADCCOUNT]; float fADCDisplayAmplification[ABF_ADCCOUNT]; float fADCDisplayOffset[ABF_ADCCOUNT]; float fInstrumentScaleFactor[ABF_ADCCOUNT]; float fInstrumentOffset[ABF_ADCCOUNT]; float fSignalGain[ABF_ADCCOUNT]; float fSignalOffset[ABF_ADCCOUNT]; float fSignalLowpassFilter[ABF_ADCCOUNT]; float fSignalHighpassFilter[ABF_ADCCOUNT]; char sDACChannelName[ABF_DACCOUNT][ABF_DACNAMELEN]; char sDACChannelUnits[ABF_DACCOUNT][ABF_DACUNITLEN]; float fDACScaleFactor[ABF_DACCOUNT]; float fDACHoldingLevel[ABF_DACCOUNT]; short nSignalType; char sUnused004[10]; // GROUP #8 - Synchronous timer outputs (14 bytes) short nOUTEnable; short nSampleNumberOUT1; short nSampleNumberOUT2; short nFirstEpisodeOUT; short nLastEpisodeOUT; short nPulseSamplesOUT1; short nPulseSamplesOUT2; // GROUP #9 - Epoch Waveform and Pulses (184 bytes) short nDigitalEnable; short _nWaveformSource; short nActiveDACChannel; short _nInterEpisodeLevel; short _nEpochType[ABF_EPOCHCOUNT]; float _fEpochInitLevel[ABF_EPOCHCOUNT]; float _fEpochLevelInc[ABF_EPOCHCOUNT]; short _nEpochInitDuration[ABF_EPOCHCOUNT]; short _nEpochDurationInc[ABF_EPOCHCOUNT]; short nDigitalHolding; short nDigitalInterEpisode; short nDigitalValue[ABF_EPOCHCOUNT]; char sUnavailable1608[4]; // was float fWaveformOffset; short nDigitalDACChannel; char sUnused005[6]; // GROUP #10 - DAC Output File (98 bytes) float _fDACFileScale; float _fDACFileOffset; char sUnused006[2]; short _nDACFileEpisodeNum; short _nDACFileADCNum; char _sDACFilePath[ABF_DACFILEPATHLEN]; // GROUP #11 - Presweep (conditioning) pulse train (44 bytes) short _nConditEnable; short _nConditChannel; ABFLONG _lConditNumPulses; float _fBaselineDuration; float _fBaselineLevel; float _fStepDuration; float _fStepLevel; float _fPostTrainPeriod; float _fPostTrainLevel; char sUnused007[12]; // GROUP #12 - Variable parameter user list ( 82 bytes) short _nParamToVary; char _sParamValueList[ABF_VARPARAMLISTLEN]; // GROUP #13 - Autopeak measurement (36 bytes) short _nAutopeakEnable; short _nAutopeakPolarity; short _nAutopeakADCNum; short _nAutopeakSearchMode; ABFLONG _lAutopeakStart; ABFLONG _lAutopeakEnd; short _nAutopeakSmoothing; short _nAutopeakBaseline; short _nAutopeakAverage; char sUnavailable1866[2]; // Was nAutopeakSaveStrategy, use nStatisticsSaveStrategy ABFLONG _lAutopeakBaselineStart; ABFLONG _lAutopeakBaselineEnd; ABFLONG _lAutopeakMeasurements; // GROUP #14 - Channel Arithmetic (52 bytes) short nArithmeticEnable; float fArithmeticUpperLimit; float fArithmeticLowerLimit; short nArithmeticADCNumA; short nArithmeticADCNumB; float fArithmeticK1; float fArithmeticK2; float fArithmeticK3; float fArithmeticK4; char sArithmeticOperator[ABF_ARITHMETICOPLEN]; char sArithmeticUnits[ABF_ARITHMETICUNITSLEN]; float fArithmeticK5; float fArithmeticK6; short nArithmeticExpression; char sUnused008[2]; // GROUP #15 - On-line subtraction (34 bytes) short _nPNEnable; short nPNPosition; short _nPNPolarity; short nPNNumPulses; short _nPNADCNum; float _fPNHoldingLevel; float fPNSettlingTime; float fPNInterpulse; char sUnused009[12]; // GROUP #16 - Miscellaneous variables (82 bytes) short _nListEnable; short nBellEnable[ABF_BELLCOUNT]; short nBellLocation[ABF_BELLCOUNT]; short nBellRepetitions[ABF_BELLCOUNT]; short nLevelHysteresis; ABFLONG lTimeHysteresis; short nAllowExternalTags; char nLowpassFilterType[ABF_ADCCOUNT]; char nHighpassFilterType[ABF_ADCCOUNT]; short nAverageAlgorithm; float fAverageWeighting; short nUndoPromptStrategy; short nTrialTriggerSource; short nStatisticsDisplayStrategy; short nExternalTagType; ABFLONG lHeaderSize; double dFileDuration; short nStatisticsClearStrategy; // Size of v1.5 header = 2048 // Extra parameters in v1.6 // EXTENDED GROUP #2 - File Structure (26 bytes) ABFLONG lDACFilePtr[ABF_WAVEFORMCOUNT]; ABFLONG lDACFileNumEpisodes[ABF_WAVEFORMCOUNT]; // EXTENDED GROUP #3 - Trial Hierarchy float fFirstRunDelay; char sUnused010[6]; // EXTENDED GROUP #7 - Multi-channel information (62 bytes) float fDACCalibrationFactor[ABF_DACCOUNT]; float fDACCalibrationOffset[ABF_DACCOUNT]; char sUnused011[30]; // GROUP #17 - Trains parameters (160 bytes) ABFLONG lEpochPulsePeriod[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; ABFLONG lEpochPulseWidth [ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; // EXTENDED GROUP #9 - Epoch Waveform and Pulses ( 412 bytes) short nWaveformEnable[ABF_WAVEFORMCOUNT]; short nWaveformSource[ABF_WAVEFORMCOUNT]; short nInterEpisodeLevel[ABF_WAVEFORMCOUNT]; short nEpochType[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; float fEpochInitLevel[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; float fEpochLevelInc[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; ABFLONG lEpochInitDuration[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; ABFLONG lEpochDurationInc[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; short nDigitalTrainValue[ABF_EPOCHCOUNT]; // 2 * 10 = 20 bytes short nDigitalTrainActiveLogic; // 2 bytes char sUnused012[18]; // EXTENDED GROUP #10 - DAC Output File (552 bytes) float fDACFileScale[ABF_WAVEFORMCOUNT]; float fDACFileOffset[ABF_WAVEFORMCOUNT]; ABFLONG lDACFileEpisodeNum[ABF_WAVEFORMCOUNT]; short nDACFileADCNum[ABF_WAVEFORMCOUNT]; char sDACFilePath[ABF_WAVEFORMCOUNT][ABF_PATHLEN]; char sUnused013[12]; // EXTENDED GROUP #11 - Presweep (conditioning) pulse train (100 bytes) short nConditEnable[ABF_WAVEFORMCOUNT]; ABFLONG lConditNumPulses[ABF_WAVEFORMCOUNT]; float fBaselineDuration[ABF_WAVEFORMCOUNT]; float fBaselineLevel[ABF_WAVEFORMCOUNT]; float fStepDuration[ABF_WAVEFORMCOUNT]; float fStepLevel[ABF_WAVEFORMCOUNT]; float fPostTrainPeriod[ABF_WAVEFORMCOUNT]; float fPostTrainLevel[ABF_WAVEFORMCOUNT]; char sUnused014[40]; // EXTENDED GROUP #12 - Variable parameter user list (1096 bytes) short nULEnable[ABF_USERLISTCOUNT]; short nULParamToVary[ABF_USERLISTCOUNT]; char sULParamValueList[ABF_USERLISTCOUNT][ABF_USERLISTLEN]; short nULRepeat[ABF_USERLISTCOUNT]; char sUnused015[48]; // EXTENDED GROUP #15 - On-line subtraction (56 bytes) short nPNEnable[ABF_WAVEFORMCOUNT]; short nPNPolarity[ABF_WAVEFORMCOUNT]; short __nPNADCNum[ABF_WAVEFORMCOUNT]; float fPNHoldingLevel[ABF_WAVEFORMCOUNT]; short nPNNumADCChannels[ABF_WAVEFORMCOUNT]; char nPNADCSamplingSeq[ABF_WAVEFORMCOUNT][ABF_ADCCOUNT]; // EXTENDED GROUP #6 Environmental Information (898 bytes) short nTelegraphEnable[ABF_ADCCOUNT]; short nTelegraphInstrument[ABF_ADCCOUNT]; float fTelegraphAdditGain[ABF_ADCCOUNT]; float fTelegraphFilter[ABF_ADCCOUNT]; float fTelegraphMembraneCap[ABF_ADCCOUNT]; short nTelegraphMode[ABF_ADCCOUNT]; short nTelegraphDACScaleFactorEnable[ABF_DACCOUNT]; char sUnused016a[24]; short nAutoAnalyseEnable; char sAutoAnalysisMacroName[ABF_MACRONAMELEN]; char sProtocolPath[ABF_PATHLEN]; char sFileComment[ABF_FILECOMMENTLEN]; GUID FileGUID; float fInstrumentHoldingLevel[ABF_DACCOUNT]; unsigned ABFLONG ulFileCRC; char sModifierInfo[ABF_CREATORINFOLEN]; char sUnused017[76]; // EXTENDED GROUP #13 - Statistics measurements (388 bytes) short nStatsEnable; unsigned short nStatsActiveChannels; // Active stats channel bit flag unsigned short nStatsSearchRegionFlags; // Active stats region bit flag short nStatsSelectedRegion; short _nStatsSearchMode; short nStatsSmoothing; short nStatsSmoothingEnable; short nStatsBaseline; ABFLONG lStatsBaselineStart; ABFLONG lStatsBaselineEnd; ABFLONG lStatsMeasurements[ABF_STATS_REGIONS]; // Measurement bit flag for each region ABFLONG lStatsStart[ABF_STATS_REGIONS]; ABFLONG lStatsEnd[ABF_STATS_REGIONS]; short nRiseBottomPercentile[ABF_STATS_REGIONS]; short nRiseTopPercentile[ABF_STATS_REGIONS]; short nDecayBottomPercentile[ABF_STATS_REGIONS]; short nDecayTopPercentile[ABF_STATS_REGIONS]; short nStatsChannelPolarity[ABF_ADCCOUNT]; short nStatsSearchMode[ABF_STATS_REGIONS]; // Stats mode per region: mode is cursor region, epoch etc char sUnused018[156]; // GROUP #18 - Application version data (16 bytes) short nCreatorMajorVersion; short nCreatorMinorVersion; short nCreatorBugfixVersion; short nCreatorBuildVersion; short nModifierMajorVersion; short nModifierMinorVersion; short nModifierBugfixVersion; short nModifierBuildVersion; // GROUP #19 - LTP protocol (14 bytes) short nLTPType; short nLTPUsageOfDAC[ABF_WAVEFORMCOUNT]; short nLTPPresynapticPulses[ABF_WAVEFORMCOUNT]; char sUnused020[4]; // GROUP #20 - Digidata 132x Trigger out flag. (8 bytes) short nDD132xTriggerOut; char sUnused021[6]; // GROUP #21 - Epoch resistance (40 bytes) char sEpochResistanceSignalName[ABF_WAVEFORMCOUNT][ABF_ADCNAMELEN]; short nEpochResistanceState[ABF_WAVEFORMCOUNT]; char sUnused022[16]; // GROUP #22 - Alternating episodic mode (58 bytes) short nAlternateDACOutputState; short nAlternateDigitalValue[ABF_EPOCHCOUNT]; short nAlternateDigitalTrainValue[ABF_EPOCHCOUNT]; short nAlternateDigitalOutputState; char sUnused023[14]; // GROUP #23 - Post-processing actions (210 bytes) float fPostProcessLowpassFilter[ABF_ADCCOUNT]; char nPostProcessLowpassFilterType[ABF_ADCCOUNT]; // 6014 header bytes allocated + 130 header bytes not allocated char sUnused2048[130]; ABFFileHeader(); }; // Size = 6144 // This structure is persisted, so the size MUST NOT CHANGE #if !defined(_WINDOWS) || defined(__MINGW32__) #define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) #endif C_ASSERT(sizeof(ABFFileHeader) == 6144); inline ABFFileHeader::ABFFileHeader() { // Set everything to 0. memset( this, 0, sizeof(ABFFileHeader) ); // Set critical parameters so we can determine the version. lFileSignature = ABF_NATIVESIGNATURE; fFileVersionNumber = ABF_CURRENTVERSION; fHeaderVersionNumber = ABF_CURRENTVERSION; lHeaderSize = ABF_HEADERSIZE; } /* // // Scope descriptor format. // #define ABF_FACESIZE 32 struct ABFLogFont { short nHeight; // Height of the font in pixels. // short lWidth; // use 0 // short lEscapement; // use 0 // short lOrientation; // use 0 short nWeight; // MSWindows font weight value. // char bItalic; // use 0 // char bUnderline; // use 0 // char bStrikeOut; // use 0 // char cCharSet; // use ANSI_CHARSET (0) // char cOutPrecision; // use OUT_TT_PRECIS // char cClipPrecision; // use CLIP_DEFAULT_PRECIS // char cQuality; // use PROOF_QUALITY char cPitchAndFamily; // MSWindows pitch and family mask. char Unused[3]; // Unused space to maintain 4-byte packing. char szFaceName[ABF_FACESIZE];// Face name of the font. }; // Size = 40 struct ABFSignal { char szName[ABF_ADCNAMELEN+2]; // ABF name length + '\0' + 1 for alignment. short nMxOffset; // Offset of the signal in the sampling sequence. DWORD rgbColor; // Pen color used to draw trace. char nPenWidth; // Pen width in pixels. char bDrawPoints; // TRUE = Draw disconnected points char bHidden; // TRUE = Hide the trace. char bFloatData; // TRUE = Floating point pseudo channel float fVertProportion; // Relative proportion of client area to use float fDisplayGain; // Display gain of trace in UserUnits float fDisplayOffset; // Display offset of trace in UserUnits // float fUUTop; // Top of window in UserUnits // float fUUBottom; // Bottom of window in UserUnits }; // Size = 34 /////////////////////////////////////////////////////////////////////////////////// //// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ////// /////////////////////////////////////////////////////////////////////////////////// // The Following #defines appear to be largely unused in opur code base // However there does exist a second set of #defines in AxScope32.h // that REALLY defines what these bits in the header do. // In particular it important to note that all 32 bits are in fact used internally /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // Bit flags used in dwFlags field of ABFScopeConfig. #define ABF_OVERLAPPED 0x00000001 #define ABF_DONTERASE 0x00000002 #define ABF_MONOCHROME 0x00000004 #define ABF_CLIPPING 0x00000008 #define ABF_HIDEHORZGRIDS 0x00000010 #define ABF_HIDEVERTGRIDS 0x00000020 #define ABF_FULLSCREEN 0x00000040 #define ABF_HIDEXAXIS 0x00000080 #define ABF_HIDEYAXIS 0x00000100 #define ABF_HIDEXSCROLL 0x00000200 #define ABF_HIDEYSCROLL 0x00000400 #define ABF_HIDESIGNALNAME 0x00000800 #define ABF_ENABLEZOOM 0x00001000 #define ABF_XSPINFROMCENTER 0x00002000 #define ABF_HIDEXSPINNER 0x00004000 #define ABF_LARGESPINNERS 0x00008000 #define ABF_PERSISTENCEMODE 0x00010000 #define ABF_CARDIACMODE 0x00020000 #define ABF_HIDETWIRLER 0x00040000 #define ABF_DISABLEUI 0x00080000 /////////////////////////////////////////////////////////////////////////////////// // #define ABF_INTERNALUSE 0xFFF00000 // Do not add extra bit flags ^^^ here they are used internally /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// //// DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER// /////////////////////////////////////////////////////////////////////////////////// // Values for the wScopeMode field in ABFScopeConfig. #define ABF_EPISODICMODE 0 #define ABF_CONTINUOUSMODE 1 //#define ABF_XYMODE 2 // Values for the nEraseStrategy field in ABFScopeConfig. #define ABF_ERASE_EACHSWEEP 0 #define ABF_ERASE_EACHRUN 1 #define ABF_ERASE_EACHTRIAL 2 #define ABF_ERASE_DONTERASE 3 // Indexes into the rgbColor field of ABFScopeConfig. #define ABF_BACKGROUNDCOLOR 0 #define ABF_GRIDCOLOR 1 #define ABF_THRESHOLDCOLOR 2 #define ABF_EVENTMARKERCOLOR 3 #define ABF_SEPARATORCOLOR 4 #define ABF_AVERAGECOLOR 5 #define ABF_OLDDATACOLOR 6 #define ABF_TEXTCOLOR 7 #define ABF_AXISCOLOR 8 #define ABF_ACTIVEAXISCOLOR 9 #define ABF_LASTCOLOR ABF_ACTIVEAXISCOLOR #define ABF_SCOPECOLORS (ABF_LASTCOLOR+1) // Extended colors for rgbColorEx field in ABFScopeConfig #define ABF_STATISTICS_REGION0 0 #define ABF_STATISTICS_REGION1 1 #define ABF_STATISTICS_REGION2 2 #define ABF_STATISTICS_REGION3 3 #define ABF_STATISTICS_REGION4 4 #define ABF_STATISTICS_REGION5 5 #define ABF_STATISTICS_REGION6 6 #define ABF_STATISTICS_REGION7 7 #define ABF_BASELINE_REGION 8 #define ABF_STOREDSWEEPCOLOR 9 #define ABF_LASTCOLOR_EX ABF_STOREDSWEEPCOLOR #define ABF_SCOPECOLORS_EX (ABF_LASTCOLOR+1) // Values for the nDockState field in ABFScopeConfig #define ABF_SCOPE_NOTDOCKED 0 #define ABF_SCOPE_DOCKED_TOP 1 #define ABF_SCOPE_DOCKED_LEFT 2 #define ABF_SCOPE_DOCKED_RIGHT 3 #define ABF_SCOPE_DOCKED_BOTTOM 4 struct ABFScopeConfig { // Section 1 scope configurations DWORD dwFlags; // Flags that are meaningful to the scope. DWORD rgbColor[ABF_SCOPECOLORS]; // Colors for the components of the scope. float fDisplayStart; // Start of the display area in ms. float fDisplayEnd; // End of the display area in ms. WORD wScopeMode; // Mode that the scope is in. char bMaximized; // TRUE = Scope parent is maximized. char bMinimized; // TRUE = Scope parent is minimized. short xLeft; // Coordinate of the left edge. short yTop; // Coordinate of the top edge. short xRight; // Coordinate of the right edge. short yBottom; // Coordinate of the bottom edge. ABFLogFont LogFont; // Description of current font. ABFSignal TraceList[ABF_ADCCOUNT]; // List of traces in current use. short nYAxisWidth; // Width of the YAxis region. short nTraceCount; // Number of traces described in TraceList. short nEraseStrategy; // Erase strategy. short nDockState; // Docked position. // Size 656 // * Do not insert any new members above this point! * // Section 2 scope configurations for file version 1.68. short nSizeofOldStructure; // Unused byte to determine the offset of the version 2 data. DWORD rgbColorEx[ ABF_SCOPECOLORS_EX ]; // New color settings for stored sweep and cursors. short nAutoZeroState; // Status of the autozero selection. DWORD dwCursorsVisibleState; // Flag for visible status of cursors. DWORD dwCursorsLockedState; // Flag for enabled status of cursors. char sUnasigned[61]; // Size 113 ABFScopeConfig(); }; // Size = 769 inline ABFScopeConfig::ABFScopeConfig() { // Set everything to 0. memset( this, 0, sizeof(ABFScopeConfig) ); // Set critical parameters so we can determine the version. nSizeofOldStructure = 656; } */ // // Definition of the ABF synch array structure // struct ABFSynch { ABFLONG lStart; // Start of the episode/event in fSynchTimeUnit units. ABFLONG lLength; // Length of the episode/event in multiplexed samples. }; // Size = 8 // // Constants for nTagType in the ABFTag structure. // #define ABF_TIMETAG 0 #define ABF_COMMENTTAG 1 #define ABF_EXTERNALTAG 2 #define ABF_VOICETAG 3 #define ABF_NEWFILETAG 4 #define ABF_ANNOTATIONTAG 5 // Same as a comment tag except that nAnnotationIndex holds // the index of the annotation that holds extra information. /* // // Definition of the ABF Tag structure // struct ABFTag { ABFLONG lTagTime; // Time at which the tag was entered in fSynchTimeUnit units. char sComment[ABF_TAGCOMMENTLEN]; // Optional tag comment. short nTagType; // Type of tag ABF_TIMETAG, ABF_COMMENTTAG, ABF_EXTERNALTAG, ABF_VOICETAG, ABF_NEWFILETAG or ABF_ANNOTATIONTAG union { short nVoiceTagNumber; // If nTagType=ABF_VOICETAG, this is the number of this voice tag. short nAnnotationIndex; // If nTagType=ABF_ANNOTATIONTAG, this is the index of the corresponding annotation. }; }; // Size = 64 // Comment inserted for externally acquired tags (expanded with spaces to ABF_TAGCOMMENTLEN). #define ABF_EXTERNALTAGCOMMENT "" #define ABF_VOICETAGCOMMENT "" // // Constants for nCompressionType in the ABFVoiceTagInfo structure. // #define ABF_COMPRESSION_NONE 0 #define ABF_COMPRESSION_PKWARE 1 //#define ABF_COMPRESSION_MPEG 2 // // Definition of the ABFVoiceTagInfo structure. // struct ABFVoiceTagInfo { ABFLONG lTagNumber; // The tag number that corresponds to this VoiceTag ABFLONG lFileOffset; // Offset to this tag within the VoiceTag block ABFLONG lUncompressedSize; // Size of the voice tag expanded. ABFLONG lCompressedSize; // Compressed size of the tag. short nCompressionType; // Compression method used. short nSampleSize; // Size of the samples acquired. ABFLONG lSamplesPerSecond; // Rate at which the sound was acquired. DWORD dwCRC; // CRC used to check data integrity. WORD wChannels; // Number of channels in the tag (usually 1). WORD wUnused; // Unused space. }; // Size 32 // // Constants for lParameterID in the ABFDelta structure. // // NOTE: If any changes are made to this list, the code in ABF_UpdateHeader must // be updated to include the new items. #define ABF_DELTA_HOLDING0 0 #define ABF_DELTA_HOLDING1 1 #define ABF_DELTA_HOLDING2 2 #define ABF_DELTA_HOLDING3 3 #define ABF_DELTA_DIGITALOUTS 4 #define ABF_DELTA_THRESHOLD 5 #define ABF_DELTA_PRETRIGGER 6 // Because of lack of space, the Autosample Gain ID also contains the ADC number. #define ABF_DELTA_AUTOSAMPLE_GAIN 100 // +ADC channel. // Because of lack of space, the Signal Gain ID also contains the ADC number. #define ABF_DELTA_SIGNAL_GAIN 200 // +ADC channel. // // Definition of the ABF Delta structure. // struct ABFDelta { ABFLONG lDeltaTime; // Time at which the parameter was changed in fSynchTimeUnit units. ABFLONG lParameterID; // Identifier for the parameter changed union { ABFLONG lNewParamValue; // Depending on the value of lParameterID float fNewParamValue; // this entry may be either a float or a long. }; }; // Size = 12 */ #ifndef RC_INVOKED #pragma pack(pop) // return to default packing #endif /* // // The size of the buffers to be passed to ABFH_GetWaveformVertor // #define ABFH_MAXVECTORS 30 */ // // Function prototypes for functions in ABFHEADR.C // void WINAPI ABFH_Initialize( ABFFileHeader *pFH ); /* void WINAPI ABFH_InitializeScopeConfig(const ABFFileHeader *pFH, ABFScopeConfig *pCfg); BOOL WINAPI ABFH_CheckScopeConfig(ABFFileHeader *pFH, ABFScopeConfig *pCfg); void WINAPI ABFH_GetADCDisplayRange( const ABFFileHeader *pFH, int nChannel, float *pfUUTop, float *pfUUBottom); */ void WINAPI ABFH_GetADCtoUUFactors( const ABFFileHeader *pFH, int nChannel, float *pfADCToUUFactor, float *pfADCToUUShift ); /* void WINAPI ABFH_ClipADCUUValue(const ABFFileHeader *pFH, int nChannel, float *pfUUValue); */ void WINAPI ABFH_GetDACtoUUFactors( const ABFFileHeader *pFH, int nChannel, float *pfDACToUUFactor, float *pfDACToUUShift ); /* void WINAPI ABFH_ClipDACUUValue(const ABFFileHeader *pFH, int nChannel, float *pfUUValue); */ BOOL WINAPI ABFH_GetMathValue(const ABFFileHeader *pFH, float fA, float fB, float *pfRval); /* int WINAPI ABFH_GetMathChannelName(char *pszName, UINT uNameLen); */ BOOL WINAPI ABFH_ParamReader( FILEHANDLE hFile, ABFFileHeader *pFH, int *pnError ); /* BOOL WINAPI ABFH_ParamReaderEx( HANDLE hFile, ABFFileHeader *pFH, int *pnError ); BOOL WINAPI ABFH_ParamWriter( HANDLE hFile, ABFFileHeader *pFH, int *pnError ); */ BOOL WINAPI ABFH_GetErrorText( int nError, char *pszBuffer, UINT nBufferSize ); /* // ABFHWAVE.CPP // Constants for ABFH_GetEpochLimits #define ABFH_FIRSTHOLDING -1 #define ABFH_LASTHOLDING ABF_EPOCHCOUNT // Return the bounds of a given epoch in a given episode. Values returned are ZERO relative. BOOL WINAPI ABFH_GetEpochLimits(const ABFFileHeader *pFH, int nADCChannel, DWORD dwEpisode, int nEpoch, UINT *puEpochStart, UINT *puEpochEnd, int *pnError); BOOL WINAPI ABFH_GetEpochLimitsEx(const ABFFileHeader *pFH, int nADCChannel, UINT uDACChannel, DWORD dwEpisode, int nEpoch, UINT *puEpochStart, UINT *puEpochEnd, int *pnError); */ // Get the offset in the sampling sequence for the given physical channel. BOOL WINAPI ABFH_GetChannelOffset( const ABFFileHeader *pFH, int nChannel, UINT *puChannelOffset ); /* // This function forms the de-multiplexed DAC output waveform for the // particular channel in the pfBuffer, in DAC UserUnits. BOOL WINAPI ABFH_GetWaveform( const ABFFileHeader *pFH, int nADCChannel, DWORD dwEpisode, float *pfBuffer, int *pnError); BOOL WINAPI ABFH_GetWaveformEx( const ABFFileHeader *pFH, UINT uDACChannel, DWORD dwEpisode, float *pfBuffer, int *pnError); // This function forms the de-multiplexed Digital output waveform for the // particular channel in the pdwBuffer, as a bit mask. Digital OUT 0 is in bit 0. BOOL WINAPI ABFH_GetDigitalWaveform( const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, DWORD *pdwBuffer, int *pnError); // Returns vector pairs for displaying a waveform made up of epochs. BOOL WINAPI ABFH_GetWaveformVector(const ABFFileHeader *pFH, DWORD dwEpisode, UINT uStart, UINT uFinish, float *pfLevels, float *pfTimes, int *pnVectors, int *pnError); // Returns vector pairs for displaying the digital outs. BOOL WINAPI ABFH_GetDigitalWaveformVector(const ABFFileHeader *pFH, DWORD dwEpisode, UINT uStart, UINT uFinish, DWORD *pdwLevels, float *pfTimes, int *pnVectors, int *pnError); // Calculates the timebase array for the file. void WINAPI ABFH_GetTimebase(const ABFFileHeader *pFH, float fTimeOffset, float *pfBuffer, UINT uBufferSize); void WINAPI ABFH_GetTimebaseEx(const ABFFileHeader *pFH, double dTimeOffset, double *pdBuffer, UINT uBufferSize); // Constant for ABFH_GetHoldingDuration #define ABFH_HOLDINGFRACTION 64 // Get the duration of the first holding period. UINT WINAPI ABFH_GetHoldingDuration(const ABFFileHeader *pFH); // Checks whether the waveform varies from episode to episode. BOOL WINAPI ABFH_IsConstantWaveform(const ABFFileHeader *pFH); BOOL WINAPI ABFH_IsConstantWaveformEx(const ABFFileHeader *pFH, UINT uDACChannel); // Checks that the sample intervals in the header are valid. BOOL WINAPI ABFH_CheckSampleIntervals(const ABFFileHeader *pFH, float fClockResolution, int *pnError); // Gets the closest sample intervals higher and lower than the passed interval. void WINAPI ABFH_GetClosestSampleIntervals(float fSampleInterval, float fClockResolution, int nOperationMode, float fMinPeriod, float fMaxPeriod, float *pfHigher, float *pfLower); // Sets up the list for the spinner to drive the sampling interval through. UINT WINAPI ABFH_SetupSamplingList(UINT uNumChannels, float fMinPeriod, float fMaxPeriod, float *pfIntervalList, UINT uListEntries); // Get the full sweep length given the length available to epochs or vice-versa. int WINAPI ABFH_SweepLenFromUserLen(int nUserLength, int nNumChannels); int WINAPI ABFH_UserLenFromSweepLen(int nSweepLength, int nNumChannels); // Converts a display range to the equivalent gain and offset factors. void WINAPI ABFH_GainOffsetToDisplayRange( const ABFFileHeader *pFH, int nChannel, float fDisplayGain, float fDisplayOffset, float *pfUUTop, float *pfUUBottom); // Converts a display range to the equivalent gain and offset factors. void WINAPI ABFH_DisplayRangeToGainOffset( const ABFFileHeader *pFH, int nChannel, float fUUTop, float fUUBottom, float *pfDisplayGain, float *pfDisplayOffset); // Converts a time value to a synch time count or vice-versa. void WINAPI ABFH_SynchCountToMS(const ABFFileHeader *pFH, UINT uCount, double *pdTimeMS); UINT WINAPI ABFH_MSToSynchCount(const ABFFileHeader *pFH, double dTimeMS); // Gets the point at which the sampling interval changes if split clock. UINT WINAPI ABFH_GetClockChange(const ABFFileHeader *pFH); // Gets the duration of the Waveform Episode (in us), allowing for split clock etc. void WINAPI ABFH_GetEpisodeDuration(const ABFFileHeader *pFH, double *pdEpisodeDuration); // Gets the duration of a P/N sequence (in us), including settling times. void WINAPI ABFH_GetPNDuration(const ABFFileHeader *pFH, double *pdPNDuration); void WINAPI ABFH_GetPNDurationEx(const ABFFileHeader *pFH, UINT uDAC, double *pdPNDuration); // Gets the duration of a pre-sweep train in us. void WINAPI ABFH_GetTrainDuration(const ABFFileHeader *pFH, double *pdTrainDuration); void WINAPI ABFH_GetTrainDurationEx (const ABFFileHeader *pFH, UINT uDAC, double *pdTrainDuration); // Gets the duration of a whole meta-episode (in us). void WINAPI ABFH_GetMetaEpisodeDuration(const ABFFileHeader *pFH, double *pdMetaEpisodeDuration); // Gets the start to start period for the episode in us. void WINAPI ABFH_GetEpisodeStartToStart(const ABFFileHeader *pFH, double *pdEpisodeStartToStart); // Checks that the user list contains valid entries for the protocol. BOOL WINAPI ABFH_CheckUserList(const ABFFileHeader *pFH, int *pnError); BOOL WINAPI ABFH_CheckUserListEx(const ABFFileHeader *pFH, UINT uListNum, int *pnError); */ // Checks if the ABFFileHeader is a new (6k) or old (2k) header. BOOL WINAPI ABFH_IsNewHeader(const ABFFileHeader *pFH); // Demotes a new ABF header to a 1.5 version ABF header. void WINAPI ABFH_DemoteHeader(ABFFileHeader *pOut, const ABFFileHeader *pIn ); // Promotes an old ABF header to a 1.8 version ABF header. void WINAPI ABFH_PromoteHeader(ABFFileHeader *pOut, const ABFFileHeader *pIn ); // Gets the first sample interval, expressed as a double. double WINAPI ABFH_GetFirstSampleInterval( const ABFFileHeader *pFH ); /* // Gets the second sample interval expressed as a double. double WINAPI ABFH_GetSecondSampleInterval( const ABFFileHeader *pFH ); // Counts the number of changing sweeps. UINT WINAPI ABFH_GetNumberOfChangingSweeps( const ABFFileHeader *pFH ); // // Checks whether the digital output varies from episode to episode. BOOL WINAPI ABFH_IsConstantDigitalOutput(const ABFFileHeader *pFH); BOOL WINAPI ABFH_IsConstantDigitalOutputEx(const ABFFileHeader *pFH, UINT uDACChannel); int WINAPI ABFH_GetEpochDuration(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch); float WINAPI ABFH_GetEpochLevel(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch); BOOL WINAPI ABFH_GetEpochLevelRange(const ABFFileHeader *pFH, UINT uDACChannel, int nEpoch, float *pfMin, float *pfMax); UINT WINAPI ABFH_GetMaxPNSubsweeps(const ABFFileHeader *pFH, UINT uDACChannel); */ // // Error return values that may be returned by the ABFH_xxx functions. // #define ABFH_FIRSTERRORNUMBER 2001 #define ABFH_EHEADERREAD 2001 #define ABFH_EHEADERWRITE 2002 #define ABFH_EINVALIDFILE 2003 #define ABFH_EUNKNOWNFILETYPE 2004 #define ABFH_CHANNELNOTSAMPLED 2005 #define ABFH_EPOCHNOTPRESENT 2006 #define ABFH_ENOWAVEFORM 2007 #define ABFH_EDACFILEWAVEFORM 2008 #define ABFH_ENOMEMORY 2009 #define ABFH_BADSAMPLEINTERVAL 2010 #define ABFH_BADSECONDSAMPLEINTERVAL 2011 #define ABFH_BADSAMPLEINTERVALS 2012 #define ABFH_ENOCONDITTRAINS 2013 #define ABFH_EMETADURATION 2014 #define ABFH_ECONDITNUMPULSES 2015 #define ABFH_ECONDITBASEDUR 2016 #define ABFH_ECONDITBASELEVEL 2017 #define ABFH_ECONDITPOSTTRAINDUR 2018 #define ABFH_ECONDITPOSTTRAINLEVEL 2019 #define ABFH_ESTART2START 2020 #define ABFH_EINACTIVEHOLDING 2021 #define ABFH_EINVALIDCHARS 2022 #define ABFH_ENODIG 2023 #define ABFH_EDIGHOLDLEVEL 2024 #define ABFH_ENOPNPULSES 2025 #define ABFH_EPNNUMPULSES 2026 #define ABFH_ENOEPOCH 2027 #define ABFH_EEPOCHLEN 2028 #define ABFH_EEPOCHINITLEVEL 2029 #define ABFH_EDIGLEVEL 2030 #define ABFH_ECONDITSTEPDUR 2031 #define ABFH_ECONDITSTEPLEVEL 2032 #define ABFH_EINVALIDBINARYCHARS 2033 #define ABFH_EBADWAVEFORM 2034 #ifdef __cplusplus } #endif #endif /* INC_ABFHEADR_H */ stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/filedesc.hpp0000775000175000017500000002253214750344764017146 //*********************************************************************************************** // // Copyright (c) 1993-1997 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // // MODULE: FILEDESC.HPP // PURPOSE: Contains the class definition for the CFileDescriptor class. // #ifndef INC_FILEDESC_HPP #define INC_FILEDESC_HPP /* #include "./../Common/BufferedArray.hpp" // Virtual item array objects */ #include "./../Common/FileIO.hpp" // Low-level file I/O services #include "csynch.hpp" // Virtual synch array object /* //#include "DACFile.hpp" // Virtual DACFile array object //#include "voicetag.hpp" // Array of voice tag descriptors. #include "notify.hpp" // CABFNotify class -- wraps ABFCallback function. #include "SimpleStringCache.hpp" // Virtual annotations object */ #define FI_PARAMFILE 0x0001 #define FI_READONLY 0x0002 #define FI_WRITEONLY 0x0004 class CFileDescriptor { private: // Member variables. CFileIO m_File; // The low level File object. CSynch m_VSynch; // The virtual synch array enum { CACHE_SIZE=10 }; // CBufferedArray m_Tags; // The tag writing object. // CBufferedArray m_Deltas; // The delta writing object. // CVoiceTagList m_VoiceTagList; // List of voice tags waiting to be saved in ABF file. // CDACFile m_DACFile[ABF_WAVEFORMCOUNT]; // DAC file sweeps. UINT m_uFlags; // Various flags governing the file opened. // CABFNotify m_Notify; // Client notification object. int m_nLastError; // Error number for last error. UINT m_uAcquiredEpisodes; // The number of episodes written to this file. UINT m_uAcquiredSamples; // The total number of samples written to this file. void *m_pvReadBuffer; // Buffer to be used for de-multiplexing data UINT m_uCachedEpisode; // Episode number for the episode cached in the read buffer. UINT m_uCachedEpisodeSize; // Size of the cached episode. UINT m_uLastEpiSize; // The size of the last episode for continuous files BOOL m_bHasOverlappedData; // TRUE if the file contains overlapped data. TCHAR m_szFileName[_MAX_PATH]; // CSimpleStringCache m_Annotations; // The annotations writing object. private: CFileDescriptor(const CFileDescriptor &FI); const CFileDescriptor &operator=(const CFileDescriptor &FI); public: CFileDescriptor(); ~CFileDescriptor(); void SetFlag(UINT uFlag); BOOL TestFlag(UINT uFlag); BOOL IsOK(); BOOL Open(LPCTSTR szFileName, BOOL bReadOnly); /* BOOL Reopen(BOOL bReadOnly); BOOL FillToNextBlock( ABFLONG *plBlockNum ); BOOL Write(const void *pvBuffer, UINT uSizeInBytes); */ BOOL Read(void *pvBuffer, UINT uSizeInBytes); BOOL Seek(LONGLONG llOffset, UINT uFlag, LONGLONG *pllOffset=NULL); /* BOOL SetEndOfFile(); */ LONGLONG GetFileSize(); /* LPCSTR GetFileName() const; */ BOOL CheckEpisodeNumber(UINT uEpisode); void SetAcquiredEpisodes(UINT uEpisodes); UINT GetAcquiredEpisodes() const; void SetAcquiredSamples(UINT uSamples); /* UINT GetAcquiredSamples() const; */ BOOL AllocReadBuffer(UINT uBytes); void FreeReadBuffer(); void *GetReadBuffer(); // Buffer to be used for de-multiplexing data void SetCachedEpisode(UINT uEpisode, UINT uEpisodeSize); UINT GetCachedEpisode() const; UINT GetCachedEpisodeSize() const; // Size of the cached episode. void SetLastEpiSize(UINT uEpiSize); UINT GetLastEpiSize() const; // Synch array functions. BOOL PutSynchEntry( UINT uStart, UINT uLength, UINT uOffset=0 ); /* void IncreaseEventLength( UINT dwIncrease ); */ BOOL GetSynchEntry( UINT uEpisode, Synch *pSynch ); /* UINT EpisodeStart( UINT uEpisode); void SetEpisodeStart(UINT uEpisode, UINT uSynchTime); */ UINT EpisodeLength( UINT uEpisode); /* UINT FileOffset( UINT uEpisode); BOOL WriteSynchArray( ABFLONG *plBlockNum, ABFLONG *plCount, UINT uSampleSize ); */ UINT GetSynchCount() const; void SetSynchMode(CSynch::eMODE eMode); /* CSynch *GetSynchObject(); */ void ChangeSynchArray(CSynch *pNewSynch); /* // Tag array functions. BOOL PutTag( const ABFTag *pTag ); UINT GetTagCount() const; BOOL WriteTags( ABFLONG *plBlockNum, ABFLONG *plCount ); BOOL UpdateTag(UINT uTag, const ABFTag *pTag); BOOL ReadTags( UINT uFirstTag, ABFTag *pTagArray, UINT uNumTags); // Voice tag functions. BOOL SaveVoiceTag( LPCSTR pszFileName, ABFLONG lDataOffset, ABFVoiceTagInfo *pVTI); BOOL WriteVoiceTags( ABFLONG *plBlockNum, ABFLONG *plCount ); BOOL GetVoiceTag( UINT uTag, LPCSTR pszFileName, ABFLONG lDataOffset, ABFVoiceTagInfo *pVTI, ABFLONG lVoiceTagPtr); // Delta functions. BOOL PutDelta(const ABFDelta *pDelta); UINT GetDeltaCount() const; BOOL WriteDeltas( ABFLONG *plBlockNum, ABFLONG *plCount ); BOOL ReadDeltas(UINT uFirstDelta, ABFDelta *pDeltaArray, UINT uNumDeltas); // DAC file functions. BOOL PutDACFileSweep( UINT uDACChannel, UINT uSweep, const DAC_VALUE *pnData, UINT uLength ); BOOL GetDACFileSweep(UINT uDACChannel, UINT uSweep, DAC_VALUE *pnData, UINT uMaxLength); UINT GetDACFileSweepCount( UINT uDACChannel ) const; BOOL WriteDACFileSweeps( UINT uDACChannel, ABFLONG *plBlockNum, ABFLONG *plCount ); // Annotations functions. BOOL PutAnnotation( LPCSTR pszText ); UINT GetAnnotationCount() const; BOOL WriteAnnotations( ABFLONG *plBlockNum, ABFLONG *plCount ); BOOL ReadAnnotation( UINT uIndex, LPSTR pszText, UINT uBufSize ); BOOL ReadAllAnnotations( ABFLONG lBlockNum ); UINT GetMaxAnnotationSize() const; */ FILEHANDLE GetFileHandle(); /* BOOL SetErrorCallback(ABFCallback fnCallback, void *pvThisPointer); */ void SetOverlappedFlag(BOOL bOverlapped); BOOL GetOverlappedFlag() const; BOOL SetLastError(int nError); int GetLastError() const; }; //=============================================================================================== // FUNCTION: GetFileHandle // PURPOSE: Returns the file handle opened in the object. // inline FILEHANDLE CFileDescriptor::GetFileHandle() { // MEMBERASSERT(); return m_File.GetFileHandle(); } //=============================================================================================== // FUNCTION: Seek // PURPOSE: Change the current position of the file pointer. // inline BOOL CFileDescriptor::Seek(LONGLONG llOffset, UINT uFlag, LONGLONG *pllNewOffset) { // MEMBERASSERT(); return m_File.Seek(llOffset, uFlag, pllNewOffset); } //=============================================================================================== // FUNCTION: GetFileSize // PURPOSE: Return the length of the file in bytes. // inline LONGLONG CFileDescriptor::GetFileSize() { // MEMBERASSERT(); return m_File.GetFileSize(); } //=============================================================================================== // PROCEDURE: Read // PURPOSE: Reads a block and returnd FALSE on ERROR. // inline BOOL CFileDescriptor::Read(LPVOID lpBuf, UINT uBytesToRead) { // MEMBERASSERT(); return m_File.Read(lpBuf, uBytesToRead) ? TRUE : SetLastError(ABF_EREADDATA); } //=============================================================================================== // FUNCTION: IsOK // PURPOSE: Checks to see whether the object was created OK. // inline BOOL CFileDescriptor::IsOK() { // MEMBERASSERT(); return (m_nLastError==0); } //=============================================================================================== // FUNCTION: PutSynchEntry // PURPOSE: Puts a new entry into the Synch array. // inline BOOL CFileDescriptor::PutSynchEntry( UINT uStart, UINT uLength, UINT uOffset ) { // MEMBERASSERT(); return m_VSynch.Put( uStart, uLength, uOffset ); } /* //=============================================================================================== // FUNCTION: IncreaseEventLength // PURPOSE: Increases the length of the last entry in the synch array. // inline void CFileDescriptor::IncreaseEventLength( UINT uIncrease ) { MEMBERASSERT(); m_VSynch.IncreaseLastLength( uIncrease ); } */ //=============================================================================================== // FUNCTION: GetSynchEntry // PURPOSE: Gets the Synch information for a particular episode. // inline BOOL CFileDescriptor::GetSynchEntry( UINT uEpisode, Synch *pSynch ) { // MEMBERASSERT(); // ASSERT(uEpisode > 0); return m_VSynch.Get( uEpisode-1, pSynch, 1 ); } //=============================================================================================== // FUNCTION: GetReadBuffer // PURPOSE: returns a pointer to the read buffer. // inline void *CFileDescriptor::GetReadBuffer() { // MEMBERASSERT(); return m_pvReadBuffer; } #endif // INC_FILEDESC_HPP stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/msbincvt.h0000775000175000017500000000072314750344764016653 //*********************************************************************************************** // // Copyright (c) 1993-1997 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** void fMSBintoIeee(float *pfIn, float *pfOut); void fIeeetoMSBin(float *pfIn, float *pfOut); stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/abferror.cpp0000775000175000017500000002037514750344764017170 //*********************************************************************************************** // // Copyright (c) 1993-1997 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // // MODULE: ABFERROR.STR // PURPOSE: Include file containing the string table for ABF error strings. // #include #include #include "./../Common/axodefn.h" #include "abffiles.h" #include "./../Common/resource.h" void initErrorMap(std::map& myMap) { #define STR(i, s) myMap[i]=s; #define BEGIN #define END #define STRINGTABLE #define DISCARDABLE STRINGTABLE DISCARDABLE BEGIN STR(ABF_EUNKNOWNFILETYPE, "File '%s' is of unknown file type.") STR(ABF_EBADFILEINDEX, "INTERNAL ERROR: bad file index.") STR(ABF_TOOMANYFILESOPEN, "INTERNAL ERROR: too many files open.") STR(ABF_EOPENFILE, "Cannot open file '%s'.") STR(ABF_EBADPARAMETERS, "File '%s' has invalid parameters.") STR(ABF_EREADDATA, "File '%s': error reading data.") STR(ABF_OUTOFMEMORY, "Out of memory reading file '%s'.") STR(ABF_EREADSYNCH, "File '%s': error reading synch array.") STR(ABF_EBADSYNCH, "File '%s': has a corrupted synch array.") STR(ABF_EEPISODERANGE, "INTERNAL ERROR: File '%s': episode out of range.") STR(ABF_EINVALIDCHANNEL, "INTERNAL ERROR: File '%s': invalid channel number.") STR(ABF_EEPISODESIZE, "File '%s': has an invalid episode size.") STR(ABF_EREADONLYFILE, "INTERNAL ERROR: file '%s' is read only.") STR(ABF_EDISKFULL, "Insufficient disk space for file '%s'.") STR(ABF_ENOTAGS, "INTERNAL ERROR: File '%s' does not contain any tag information.") STR(ABF_EREADTAG, "Error reading tag from file '%s'.") STR(ABF_ENOSYNCHPRESENT, "INTERNAL ERROR: No synch array is present in file '%s'.") STR(ABF_EREADDACEPISODE, "Error reading DAC episode from file '%s'.") STR(ABF_ENOWAVEFORM, "INTERNAL ERROR: No waveform defined.") STR(ABF_EBADWAVEFORM, "INTERNAL ERROR: Bad waveform definition.") STR(ABF_BADMATHCHANNEL, "INTERNAL ERROR: Bad math channel description.") STR(ABF_BADTEMPFILE, "Could not create a temporary file.") STR(ABF_NODOSFILEHANDLES, "No DOS file handles were available - too many files open.") STR(ABF_ENOSCOPESPRESENT, "INTERNAL ERROR: File '%s' does not contain any scope configuration information.") STR(ABF_EREADSCOPECONFIG, "Error reading scope configuration from file '%s'.") STR(ABF_EBADCRC, "INTERNAL ERROR: Bad CRC on reading ABF file -- file may be corrupted.") STR(ABF_ENOCOMPRESSION, "Data compression is not supported on this platform.") STR(ABF_EREADDELTA, "Error reading delta from file '%s'.") STR(ABF_ENODELTAS, "INTERNAL ERROR: File '%s' does not contain any delta information.") STR(ABF_EBADDELTAID, "INTERNAL ERROR: ABFDelta has an unknown parameter ID.") STR(ABF_EWRITEONLYFILE, "INTERNAL ERROR: file '%s' is write only.") STR(ABF_ENOSTATISTICSCONFIG, "INTERNAL ERROR: File '%s' does not contain a statistics window configuration structure.") STR(ABF_EREADSTATISTICSCONFIG, "INTERNAL ERROR: Error reading statistics window configuration from file '%s'.") STR(ABF_EWRITERAWDATAFILE, "INTERNAL ERROR: Cannot modify raw data files.") STR(ABF_EWRITEMATHCHANNEL, "INTERNAL ERROR: Cannot modify math channels.") STR(ABFH_EHEADERREAD, "Error reading file header.") STR(ABFH_EHEADERWRITE, "Error writing file header.") STR(ABFH_EINVALIDFILE, "Not a valid ABF file.") STR(ABFH_EUNKNOWNFILETYPE, "Not a valid ABF file.") STR(ABFH_CHANNELNOTSAMPLED,"The requested Analog IN channel was not sampled.") STR(ABFH_EPOCHNOTPRESENT, "The requested epoch is not present.") STR(ABFH_ENOWAVEFORM, "No waveform was defined.") STR(ABFH_EDACFILEWAVEFORM, "Waveform was defined by a DAC file.") STR(ABFH_ENOMEMORY, "Out of memory!") STR(ABFH_BADSAMPLEINTERVAL, "Invalid sample interval.") STR(ABFH_BADSECONDSAMPLEINTERVAL,"Invalid second sample interval.") STR(ABFH_BADSAMPLEINTERVALS, "The first and second sampling intervals must be integer multiples of each other.") STR(ABFH_ENOCONDITTRAINS, "There is an error in the User List.\n\nConditioning trains must be enabled in order to vary this parameter.") STR(ABFH_EMETADURATION, "There is an error in the User List.\n\nThe conditioning train duration is too long. Either reduce the duration or increase the sweep start to start time.") STR(ABFH_ECONDITNUMPULSES, "There is an error in the User List.\n\nThe number of pulses in the conditioning train must be between 1 and 10000.") STR(ABFH_ECONDITBASEDUR, "There is an error in the User List.\n\nThe conditioning train baseline duration must be between 0.01 and 10000 ms.") STR(ABFH_ECONDITBASELEVEL, "There is an error in the User List.\n\nThe conditioning train baseline level is out of range.") STR(ABFH_ECONDITPOSTTRAINDUR, "There is an error in the User List.\n\nThe conditioning train post-train duration must be between 0 and 10000 ms.") STR(ABFH_ECONDITPOSTTRAINLEVEL, "There is an error in the User List.\n\nThe conditioning train post-train level is out of range.") STR(ABFH_ESTART2START, "There is an error in the User List.\n\nThe time between sweep starts is too short.") STR(ABFH_EINACTIVEHOLDING, "There is an error in the User List.\n\nThe inactive analog OUT holding level is out of range.") STR(ABFH_EINVALIDCHARS, "The user list contains invalid characters or is empty.\n\nValid characters are: 0..9 E e + - .\n\nValid characters for binary values: 0 1 *.") STR(ABFH_EINVALIDBINARYCHARS, "The user list contains invalid characters.\n\nValid characters for binary values are: 0 1 *,\n\nA * is valid for defining a digital train.") STR(ABFH_ENODIG, "There is an error in the User List.\n\nThe waveform digital outputs must be enabled in order to vary this parameter.") STR(ABFH_EDIGHOLDLEVEL, "There is an error in the User List.\n\nThe waveform digital inter-sweep holding level is out of range.") STR(ABFH_ENOPNPULSES, "There is an error in the User List.\n\nP/N leak subtraction must be enabled in order to vary this parameter.") STR(ABFH_EPNNUMPULSES, "There is an error in the User List.\n\nThe number of P/N leak subtraction sub-sweeps must be between 1 and 8.") STR(ABFH_ENOEPOCH, "There is an error in the User List.\n\nThe waveform epoch requested in the user list must be enabled in order to vary this parameter.") STR(ABFH_EEPOCHLEN, "There is an error in the User List.\n\nThe waveform duration is too long. Either reduce the waveform duration or increase the sweep duration.") STR(ABFH_EEPOCHINITLEVEL, "There is an error in the User List.\n\nThe waveform initial level is out of range.") STR(ABFH_EDIGLEVEL, "There is an error in the User List.\n\nThe waveform digital pattern is out of range.") STR(ABFH_ECONDITSTEPLEVEL, "There is an error in the User List.\n\nThe conditioning train step level is out of range.") STR(ABFH_ECONDITSTEPDUR, "There is an error in the User List.\n\nThe conditioning train step duration must be between 0.01 and 10000 ms.") STR(ABF_ECRCVALIDATIONFAILED, "The Cyclic Redundancy Code (CRC) validation failed while opening the file.") STR(IDS_ENOMESSAGESTR, "INTERNAL ERROR: No message string assigned to error %d.") STR(IDS_EPITAGHEADINGS, "Tag # Time (s) Episode Comment") STR(IDS_CONTTAGHEADINGS, "Tag # Time (s) Comment") STR(IDS_NONE, "") STR(IDS_CANNOTLOAD, "This version of ABFInfo is out of date.") STR(IDS_MATHCHANNEL, "Math") END } extern "C" INT WINAPI c_LoadString( HINSTANCE instance, UINT resource_id, char* buffer, INT buflen ) { std::map errorMap; initErrorMap(errorMap); strcpy(buffer,errorMap[resource_id].c_str()); return (int)errorMap[resource_id].length(); } stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/csynch.cpp0000775000175000017500000004671114750344764016657 //*********************************************************************************************** // // Copyright (c) 1993-2002 Axon Instruments, Inc. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // MODULE: CSYNCH.CPP // PURPOSE: Contains member function code for the CSynch class. // AUTHOR: BHI May 1994 // NOTES: // #include "../Common/wincpp.hpp" #include "./csynch.hpp" #include "../Common/FileIO.hpp" #include "./abfutil.h" #if !defined(_WINDOWS) || defined(__MINGW32__) || defined(__STF__) #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif //=============================================================================================== // PROCEDURE: _Initialize // PURPOSE: Internal initialization routine. // void CSynch::_Initialize() { #if defined(_WINDOWS) && !defined(__MINGW32__) m_szFileName[0] = '\0'; // Filename for array virtualization #endif m_hfSynchFile = NULL; // Handle to temporary file. m_eMode = eWRITEMODE; // Mode flag for buffering algorithm. m_uSynchCount = 0; // Total count of entries in the synch array m_uCacheCount = 0; // Count of entries in the cache m_uCacheStart = 0; // Number of first entry in the cache. memset(m_SynchBuffer, 0, sizeof(m_SynchBuffer)); // Buffer for caching synch entries. memset(&m_LastEntry, 0, sizeof(m_LastEntry)); // Last entry written (write only). } //=============================================================================================== // PROCEDURE: CSynch // PURPOSE: Constructor. // CSynch::CSynch() { /*MEMBERASSERT();*/ _Initialize(); } //=============================================================================================== // PROCEDURE: ~CSynch // PURPOSE: Destructor. Closes the temporary file and deletes it. // CSynch::~CSynch() { /*MEMBERASSERT();*/ CloseFile(); } //=============================================================================================== // PROCEDURE: Clone // PURPOSE: Clone a passed CSynch array. Ownership is transfered of the temp file etc. // void CSynch::Clone(CSynch *pCS) { /*MEMBERASSERT();*/ CloseFile(); // Clone the settings. // strcpy(m_szFileName, pCS->m_szFileName); m_hfSynchFile = pCS->m_hfSynchFile; m_eMode = pCS->m_eMode; m_uSynchCount = pCS->m_uSynchCount; m_uCacheCount = pCS->m_uCacheCount; m_uCacheStart = pCS->m_uCacheStart; m_LastEntry = pCS->m_LastEntry; // Clone the data. memcpy(m_SynchBuffer, pCS->m_SynchBuffer, sizeof(m_SynchBuffer)); // Initialize the source CSynch object so that it doesn't delete the backing file. pCS->_Initialize(); } //=============================================================================================== // PROCEDURE: CreateFile // PURPOSE: Gets a unique filename and opens it as a temporary file. // BOOL CSynch::OpenFile() { /*MEMBERASSERT();*/ _Initialize(); #if !defined(_WINDOWS) || defined(__MINGW32__) // Create the temporary file. m_hfSynchFile = tmpfile(); ASSERT(m_hfSynchFile != FILE_NULL); return (m_hfSynchFile != NULL); #else // Get a unique temporary file name. // AXU_GetTempFileName("synch", 0, m_szFileName); ABFU_GetTempFileName("synch", 0, m_szFileName); // Create the temporary file. m_hfSynchFile = CreateFileA(m_szFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL); ASSERT(m_hfSynchFile != INVALID_HANDLE_VALUE); return (m_hfSynchFile != INVALID_HANDLE_VALUE); #endif } //=============================================================================================== // PROCEDURE: CloseFile // PURPOSE: Closes the file if it was opened previously. // void CSynch::CloseFile() { /*MEMBERASSERT();*/ if (m_hfSynchFile != NULL) { #if !defined(_MSC_VER) c_CloseHandle(m_hfSynchFile); #else CloseHandle(m_hfSynchFile); #endif m_hfSynchFile = NULL; } _Initialize(); } //=============================================================================================== // PROCEDURE: SetMode // PURPOSE: Sets the buffering mode of the CSynch object. // void CSynch::SetMode(eMODE eMode) { /*MEMBERASSERT();*/ if ((m_eMode==eMode) || !_IsFileOpen()) return; // If the old mode was for writing, flush the cache to disk. if (m_eMode==eWRITEMODE) _Flush(); // Set the new mode. m_eMode = eMode; m_uCacheStart = m_uSynchCount; // If the new mode is for writing, preload the cache with the last n entries. if (m_eMode==eWRITEMODE) { UINT uCount = SYNCH_BUFFER_SIZE; if (m_uSynchCount < SYNCH_BUFFER_SIZE) { m_uCacheStart = 0; uCount = m_uSynchCount; } else m_uCacheStart = m_uSynchCount - SYNCH_BUFFER_SIZE; // Read the data out of the file. Read( m_SynchBuffer, m_uCacheStart, uCount ); // Set the current position to the start of the bit we last read, and truncate the file here. #if defined(_MSC_VER) SetFilePointer(m_hfSynchFile, m_uCacheStart * sizeof(Synch), NULL, FILE_BEGIN); #else c_SetFilePointer(m_hfSynchFile, m_uCacheStart * sizeof(Synch), NULL, FILE_BEGIN); #endif //TRACE1( "CSynch::SetMode file position is %d.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); // VERIFY(SetEndOfFile(m_hfSynchFile)); m_uCacheCount = uCount; m_LastEntry = m_SynchBuffer[uCount-1]; } else { // Set the start index of the cache to the count of items in the file to // cause the cache to be invalid and filled on the next get. m_uCacheStart = m_uSynchCount; } } //=============================================================================================== // PROCEDURE: _GetWriteMode // PURPOSE: Retrieves synch entries from the virtualized array. // BOOL CSynch::_GetWriteMode( UINT uFirstEntry, Synch *pSynch, UINT uEntries ) { /*MEMBERASSERT();*/ ASSERT(uFirstEntry+uEntries <= m_uSynchCount); ASSERT(uEntries > 0); /*ARRAYASSERT(pSynch, uEntries);*/ ASSERT(m_eMode == eWRITEMODE); // If just the last entry is required, return it and get out. if (uFirstEntry == m_uSynchCount-1) { *pSynch = m_LastEntry; return TRUE; } // If the block requested is not contained completely in the cache, // read the file for it, reading straight into the passed buffer. if (m_uSynchCount - uFirstEntry > SYNCH_BUFFER_SIZE) { // Rather than checking whether the file has been opened in this case // we will just assert that this is so here. This means that it is the // responsibility of the caller to ensure that synch entries are not // requested outside the synch buffer if the cache is not backed by a file. ASSERT(m_hfSynchFile != FILE_NULL); // Calculate how many entries there are from the requested first entry until // we hit the ones currently in the cache. UINT uCount = m_uSynchCount - uFirstEntry - SYNCH_BUFFER_SIZE; // Limit the count to no greater than the requested amount. if (uCount > uEntries) uCount = uEntries; // Read the data out of the file. if( !Read( pSynch, uFirstEntry, uCount) ) return FALSE; // Update pointers and counters. pSynch += uCount; uFirstEntry += uCount; uEntries -= uCount; if (uEntries == 0) return TRUE; } // Transfer the part of the buffer that is "invalidated", i.e. about to be overwritten. if (uFirstEntry < m_uCacheStart) { UINT uCount = m_uCacheStart - uFirstEntry; ASSERT(uCount <= SYNCH_BUFFER_SIZE - m_uCacheCount); Synch *pS = m_SynchBuffer + SYNCH_BUFFER_SIZE - uCount; if (uCount > uEntries) uCount = uEntries; memcpy(pSynch, pS, uCount*sizeof(Synch)); pSynch += uCount; uFirstEntry += uCount; uEntries -= uCount; if (uEntries == 0) return TRUE; } // Transfer the more recently written part of the cache. ASSERT(uFirstEntry >= m_uCacheStart); ASSERT(uFirstEntry - m_uCacheStart + uEntries <= m_uCacheCount); memcpy(pSynch, m_SynchBuffer + uFirstEntry - m_uCacheStart, uEntries*sizeof(Synch)); return TRUE; } //=============================================================================================== // PROCEDURE: _GetReadMode // PURPOSE: Retrieves synch entries from the virtualized array. // BOOL CSynch::_GetReadMode( UINT uFirstEntry, Synch *pSynch, UINT uEntries ) { /*MEMBERASSERT();*/ ASSERT(m_hfSynchFile != FILE_NULL); ASSERT(uEntries > 0); /*ARRAYASSERT(pSynch, uEntries);*/ ASSERT(uFirstEntry+uEntries <= m_uSynchCount); ASSERT(m_eMode == eREADMODE); // Loop until the get() has been satisfied. while (uEntries) { // If the first entry is not in the cache, reload the cache. if ((uFirstEntry < m_uCacheStart) || (uFirstEntry >= m_uCacheStart + m_uCacheCount)) { m_uCacheStart = uFirstEntry - (uFirstEntry % SYNCH_BUFFER_SIZE); m_uCacheCount = m_uSynchCount - m_uCacheStart; if (m_uCacheCount > SYNCH_BUFFER_SIZE) m_uCacheCount = SYNCH_BUFFER_SIZE; Read( m_SynchBuffer, m_uCacheStart, m_uCacheCount ); } // Calculate how many entries intersect the cache. UINT uCount = min(uEntries, m_uCacheCount); // Copy the entries out of the cache. memcpy(pSynch, m_SynchBuffer+uFirstEntry-m_uCacheStart, uCount*sizeof(Synch)); uFirstEntry += uCount; pSynch += uCount; uEntries -= uCount; } return TRUE; } //=============================================================================================== // PROCEDURE: _Flush // PURPOSE: Flushes the Synch cache to disk. // BOOL CSynch::_Flush() { /*MEMBERASSERT();*/ ASSERT(m_eMode==eWRITEMODE); if (m_uCacheCount == 0) return TRUE; BOOL bRval = TRUE; DWORD dwBytesWritten = 0; if (_IsFileOpen()) { //TRACE1( "CSynch::_Flush current file pointer is %d on entry.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); // Write out the current contents of the cache. UINT uBytesToWrite = m_uCacheCount * sizeof(Synch); #if defined(_MSC_VER) bRval = WriteFile(m_hfSynchFile, m_SynchBuffer, uBytesToWrite, &dwBytesWritten, NULL); #else bRval = c_WriteFile(m_hfSynchFile, m_SynchBuffer, uBytesToWrite, &dwBytesWritten, NULL); #endif //TRACE1( "CSynch::_Flush current file pointer is %d after WriteFile.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); } // If a disk full error occurs, save what was actually written and rotate the buffer // ready for the next attempt(?). if (!bRval) { UINT uEntriesWritten = dwBytesWritten/sizeof(Synch); UINT uEntriesUnwritten = m_uCacheCount - uEntriesWritten; Synch *pTemp = new Synch[uEntriesWritten]; if (pTemp) memcpy(pTemp, m_SynchBuffer, uEntriesWritten*sizeof(Synch)); for (UINT i=0; idwFileOffset/uSampleSize + pS->dwLength > uAcquiredSamples) { uEntries = i; return FALSE; } *pdwDest++ = pS->dwStart; *pdwDest++ = pS->dwLength; pS++; } return TRUE; } //=============================================================================================== // PROCEDURE: Write // PURPOSE: Copies the complete synch array to another file, packing out the file-offset entry. // BOOL CSynch::Write( HANDLE hDataFile, UINT uAcquiredSamples, UINT *puSynchCount, UINT uSampleSize ) { MEMBERASSERT(); ASSERT( hDataFile != INVALID_HANDLE_VALUE ); WPTRASSERT(puSynchCount); // Flush any cached Synch entries to the temp file. This should not fail as the reserve file // will have been released just prior to calling this function. If it does fail, we will // still be able to work with the Synch entries that were saved ok. if (m_uCacheCount) _Flush(); // Set the return value for the number of synch entries. If none exist, return. *puSynchCount = 0; if (m_uSynchCount == 0) return TRUE; // Seek to the end of the passed file. This will only fail for invalid file handles. CFileIO_NoClose OutFile(hDataFile); LONGLONG llCurrentPos = 0; if (!OutFile.Seek(0, FILE_END, &llCurrentPos)) return FALSE; // Seek to the start of the temporary file. SetFilePointer(m_hfSynchFile, 0L, NULL, FILE_BEGIN); // Read the Synch data in a buffer at a time and write it out to the passed file. UINT uEntries = m_uSynchCount; UINT uWritten = 0; UINT uCount = 0; while ( uEntries > 0 ) { uCount = min(uEntries, SYNCH_BUFFER_SIZE); // Read in a buffer from the temp file. VERIFY(Read( m_SynchBuffer, uWritten, uCount)); // Pack the buffer, removing the dwFileOffset members and checking for invalid synch entries. // If an invalid entry is found, the count is truncated at the last valid entry. if (!_PackBuffer(uAcquiredSamples, uCount, uSampleSize)) uEntries = uCount; // Write the packed buffer out to the temp file. if ( !OutFile.Write( m_SynchBuffer, uCount * 2 * sizeof(DWORD) )) { // If an error occurs, go back to the start of the block and truncate the file // ready for the next attempt after the user has freed up some disk space. VERIFY(OutFile.Seek(llCurrentPos, FILE_BEGIN)); VERIFY(OutFile.SetEndOfFile()); return FALSE; } uEntries -= uCount; uWritten += uCount; } // Seek back to end of the temporary file. SetFilePointer(m_hfSynchFile, 0L, NULL, FILE_END); //TRACE1( "CSynch::Write current file pointer is %d after seek to end.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); *puSynchCount = uWritten; return TRUE; } */ //=============================================================================================== // PROCEDURE: Put // PURPOSE: Puts a new Synch entry into the synch array, flushing to disk if full. // BOOL CSynch::Put( UINT uStart, UINT uLength, UINT uOffset ) { /*MEMBERASSERT();*/ ASSERT(m_eMode==eWRITEMODE); ASSERT((m_uSynchCount == 0) || (m_LastEntry.dwStart <= uStart)); // Flush the cache if it is full. if ((m_uCacheCount >= SYNCH_BUFFER_SIZE) && (!_Flush())) return FALSE; // If a value of zero is passed as the file offset, the file offset for this // entry is derived from the previous one. if (uOffset == 0) m_LastEntry.dwFileOffset += m_LastEntry.dwLength * 2; else m_LastEntry.dwFileOffset = uOffset; m_LastEntry.dwStart = uStart; m_LastEntry.dwLength = uLength; m_SynchBuffer[m_uCacheCount++] = m_LastEntry; m_uSynchCount++; return TRUE; } /* //=============================================================================================== // PROCEDURE: Update // PURPOSE: Updates an entry in the SynchArray. // BOOL CSynch::Update( UINT uEntry, const Synch *pSynch ) { ASSERT(uEntry < m_uSynchCount); ASSERT(m_eMode!=eREADMODE); ASSERT(m_hfSynchFile != INVALID_HANDLE_VALUE); // Save current file position. ABFLONG lCurrentPos = SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT); //TRACE1( "CSynch::Update current file pointer is %d on entry.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); if (lCurrentPos == INVALID_SEEK_VALUE) return FALSE; // Seek to the entry. SetFilePointer(m_hfSynchFile, uEntry * sizeof(Synch), NULL, FILE_BEGIN); //TRACE1( "CSynch::Update current file pointer is %d after seek to current entry.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); // Write the data out of the file. DWORD dwBytesWritten = 0; BOOL bOK = WriteFile(m_hfSynchFile, pSynch, sizeof(pSynch), &dwBytesWritten, NULL); // Reset the pointer to the original position. SetFilePointer(m_hfSynchFile, lCurrentPos, NULL, FILE_BEGIN); //TRACE1( "CSynch::Update current file pointer is %d after seek to original position.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); if (!bOK) return FALSE; // If the entry requested is contained in the cache, update the cache. if (m_uSynchCount - uEntry <= SYNCH_BUFFER_SIZE) { int nIndex = int(uEntry - m_uCacheStart); if (nIndex < 0) nIndex += SYNCH_BUFFER_SIZE; ASSERT(nIndex >= 0); ASSERT(nIndex < SYNCH_BUFFER_SIZE); m_SynchBuffer[nIndex] = *pSynch; if (uEntry==m_uSynchCount-1) m_LastEntry = *pSynch; } return TRUE; } //=============================================================================================== // PROCEDURE: UpdateLength // PURPOSE: Updates the length of the last entry put in the SynchArray. // void CSynch::UpdateLength(DWORD dwLength) { MEMBERASSERT(); ASSERT(m_eMode==eWRITEMODE); ASSERT(m_uCacheCount > 0); m_LastEntry.dwLength = dwLength; m_SynchBuffer[m_uCacheCount-1] = m_LastEntry; } //=============================================================================================== // PROCEDURE: IncreaseLastLength // PURPOSE: Increases the length of the last entry put in the SynchArray. // void CSynch::IncreaseLastLength( DWORD dwIncrease ) { MEMBERASSERT(); ASSERT(m_eMode==eWRITEMODE); ASSERT(m_uCacheCount > 0); m_LastEntry.dwLength += dwIncrease; m_SynchBuffer[m_uCacheCount-1] = m_LastEntry; } //=============================================================================================== // PROCEDURE: GetLastEntry // PURPOSE: Returns the last Synch structure added to the synch array. // BOOL CSynch::GetLastEntry(Synch *pSynch) { MEMBERASSERT(); WPTRASSERT(pSynch); if (!m_uSynchCount) return FALSE; *pSynch = m_LastEntry; return TRUE; } */ stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/abfutil.cpp0000775000175000017500000001751114750344764017012 //*********************************************************************************************** // // Copyright (c) 1993-1999 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // FILE: ABFUTIL.CPP A utilities module for the ABF file routines. // #include "../Common/wincpp.hpp" #include "abfutil.h" #include "abffiles.h" #include "abfheadr.h" #if defined(_WINDOWS) && !defined(__MINGW32__) #define USE_AXOVDATE #endif #define ABFU_VALID_SIG_CHARS " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_#" #if !defined(_WINDOWS) || defined(__MINGW32__) || defined(__STF__) #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif //============================================================================================== // FUNCTION: ABFU_GetTempFileName // PURPOSE: Gets a temporary file name in the directory pointed to by the %TEMP% environment // variable. // #if !defined(__MINGW32__) // TODO: check what this is used for and whether this is a critical component UINT WINAPI ABFU_GetTempFileName(LPCSTR szPrefix, UINT uUnique, LPSTR lpTempName) { #if defined(_WINDOWS) && !defined(__MINGW32__) ARRAYASSERT(lpTempName, _MAX_PATH); char szTempPath[_MAX_PATH]; if (!GetTempPathA(_MAX_PATH, szTempPath)) strcpy(szTempPath, "C:\\"); return GetTempFileNameA(szTempPath, szPrefix, uUnique, lpTempName); #else strcpy(lpTempName,"ABFTMPXXXXXX"); int res = mkstemp((char*)lpTempName); if (res == -1) return 0; return 1; #endif } #endif // tmpnam (lpTempName); // return 1; //} //=============================================================================================== // FUNCTION: ABFU_ReadFile // PURPOSE: Wrapper on the ReadFile function that returns FALSE at EOF. // BOOL WINAPI ABFU_ReadFile(FILEHANDLE hFile, LPVOID lpBuf, DWORD dwBytesToRead) { DWORD dwBytesRead; #if defined(_WINDOWS) && !defined(__MINGW32__) BOOL bOK = ReadFile(hFile, lpBuf, dwBytesToRead, &dwBytesRead, NULL); #else BOOL bOK = c_ReadFile(hFile, lpBuf, dwBytesToRead, &dwBytesRead, NULL); #endif return (bOK && (dwBytesRead==dwBytesToRead)); } /* //=============================================================================================== // FUNCTION: ABFU_FormatDouble // PURPOSE: Formats the digits of dNum into pszString, suppressing trailing zeros. // In the event that "0." is produced as output from gcvt, truncate to "0" // // RETURNS: TRUE if success; FALSE if failure // #ifdef USE_AXOVDATE #include "..\AxonValidation\AxonValidation.h" // for VAL_* functions (standard Axon float/double->string formatting) #endif BOOL WINAPI ABFU_FormatDouble(double dNum, int nDigits, char *pszString, UINT uSize) { #ifndef USE_AXOVDATE gcvt(dNum, nDigits, pszString); int l = strlen(pszString); if ((l > 0) && (pszString[l-1]=='.')) pszString[l-1] = '\0'; return TRUE; #else return VAL_ConvertDblToStr(dNum, pszString, uSize, VAL_FMT_SIG_DIGITS, 0, nDigits, NULL); #endif } //=============================================================================================== // FUNCTION: ABFU_FormatHMS // PURPOSE: Formats the time in HH:MM:SS. // RETURNS: The number of characters written to the buffer. // NOTE: The buffer passed in should be at least AXU_MAXHMSLENGTH characters long. // int WINAPI ABFU_FormatHMS( UINT uSeconds, char *pszBuffer, UINT uMaxLen ) { UINT uHours = (uSeconds / 3600U) % 100U; UINT uMinutes = (uSeconds % 3600U) / 60U; uSeconds %= 60U; return _snprintf(pszBuffer, uMaxLen, "%02u:%02u:%02u", uHours, uMinutes, uSeconds); } */ //=============================================================================================== // FUNCTION: ABFU_SetABFString // PURPOSE: Fill a non zero-terminated string, padding with spaces if necessary. // void WINAPI ABFU_SetABFString(LPSTR psDest, LPCSTR psSrce, int nMaxLength) { // ARRAYASSERT(psDest, nMaxLength); #if 0 LPSZASSERT(psSrce); #endif strncpy(psDest, psSrce, nMaxLength); int l = (int)strlen(psSrce); while (l < nMaxLength) psDest[l++] = ' '; } //=============================================================================================== // FUNCTION: ABFU_GetABFString // PURPOSE: Fill a zero-terminated string, from an ABF string, stripping spaces if necessary. // void WINAPI ABFU_GetABFString(LPSTR psDest, int nMaxDest, LPCSTR psSrce, int nMaxSrce) { // ARRAYASSERT(psDest, nMaxDest); // ARRAYASSERT(psSrce, nMaxSrce); // Skip any leading blank spaces. while (nMaxSrce > 0) { if (*psSrce!=' ') break; psSrce++; nMaxSrce--; } // copy to the limit of the destination or the source, whichever comes first. int l = min(nMaxDest-1, nMaxSrce); strncpy(psDest, psSrce, l); psDest[l] = '\0'; // Zero out any trailing spaces. while (l > 0) { l--; if (psDest[l]!=' ') return; psDest[l] = '\0'; } } //=============================================================================================== // FUNCTION: ABFU_FixFileStartDate // PURPOSE: Checks the lFileStartDate parameter contains a 4 digit year and fixes it if needed. // long WINAPI ABFU_FixFileStartDate( long lDate ) { long lStartDay = lDate % 100L; long lStartMonth = (lDate % 10000L) / 100L; long lStartYear = lDate / 10000L; if ( lStartYear < 1000) { if (lStartYear < 80L) lStartYear += 2000L; else lStartYear += 1900L; } return long(lStartYear*10000 + lStartMonth*100 + lStartDay); } /* //=============================================================================================== // FUNCTION: ABFU_IsValidSignalName // PURPOSE: Checks if the signal name is valid. // RETURNS: TRUE if name is valid. // BOOL WINAPI ABFU_IsValidSignalName( LPCSTR pszSignalName ) { LPSZASSERT( pszSignalName ); // Signals cannot have the same name as the math channel. char szMathChannel[ ABF_ADCNAMELEN + 1 ]; ABFH_GetMathChannelName( szMathChannel, sizeof( szMathChannel ) ); if ( stricmp( pszSignalName, szMathChannel ) == 0 ) return FALSE; if ( *pszSignalName == ' ' ) return FALSE; if ( *pszSignalName == '\0' ) return FALSE; // Check for invalid characters. int len = strlen( pszSignalName ); int pos = strspn( pszSignalName, ABFU_GetValidSignalNameChars() ); // If pos < len, then an invalid char was found. return (pos == len); } //=============================================================================================== // FUNCTION: ABFU_GetValidSignalNameChars // PURPOSE: Returns the set of valid characters for signal names. // LPCSTR WINAPI ABFU_GetValidSignalNameChars() { return ABFU_VALID_SIG_CHARS; } //=============================================================================================== // FUNCTION: ABFU_FixSignalName // PURPOSE: Replaces invalid characters in a signal name with valid ones. // RETURNS: TRUE if name is valid. // void WINAPI ABFU_FixSignalName( LPSTR pszSignalName ) { LPSZASSERT( pszSignalName ); // Check for invalid characters. int len = strlen( pszSignalName ); for( int i=0; i (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif /* // Set USE_DACFILE_FIX to 1 to use the fix (incomplete) for DAC File channels. #define USE_DACFILE_FIX 0 //------------------------------------ Shared Variables ----------------------------------------- */ static CFileDescriptor *g_FileData[ABF_MAXFILES]; HINSTANCE g_hInstance = NULL; //=============================================================================================== static BOOL ReadEDVarLenSynch(CFileDescriptor *pFI, ABFFileHeader *pFH, DWORD *pdwMaxEpi, UINT *puMaxSamples, int *pnError); static BOOL ReadEDFixLenSynch(CFileDescriptor *pFI, const ABFFileHeader *pFH, DWORD *pdwMaxEpi, BOOL bAllowOverlap, int *pnError); static BOOL ReadOldSynchArray(CFileDescriptor *pFI, ABFFileHeader *pFH, DWORD *pdwMaxEpi, int *pnError); //=============================================================================================== // Macros and functions to deal with returning error return codes through a pointer if given. #define ERRORRETURN(p, e) return ErrorReturn(p, e); static BOOL ErrorReturn(int *pnError, int nErrorNum) { if (pnError) *pnError = nErrorNum; return FALSE; } //=============================================================================================== // FUNCTION: GetNewFileDescriptor // PURPOSE: Allocate a new file descriptor and return it. // BOOL GetNewFileDescriptor(CFileDescriptor **ppFI, int *pnFile, int *pnError) { // WPTRASSERT(ppFI); // WPTRASSERT(pnFile); int nFile; // Find an empty slot. for (nFile=0; nFile < ABF_MAXFILES; nFile++) if (g_FileData[nFile] == NULL) break; // Return an error if no space left. if (nFile == ABF_MAXFILES) return ErrorReturn(pnError, ABF_TOOMANYFILESOPEN); // Allocate a new descriptor. CFileDescriptor *pFI = new CFileDescriptor; if (pFI == NULL) return ErrorReturn(pnError, ABF_OUTOFMEMORY); if (!pFI->IsOK()) { delete pFI; return ErrorReturn(pnError, ABF_BADTEMPFILE); } *ppFI = g_FileData[nFile] = pFI; *pnFile = nFile; return TRUE; } //----------------------------------------------------------------------------------------------- // FUNCTION: GetFileDescriptor // PURPOSE: Retreive an existing file descriptor. // BOOL GetFileDescriptor(CFileDescriptor **ppFI, int nFile, int *pnError) { // WPTRASSERT(ppFI); // Check that index is within range. if ((nFile < 0) || (nFile >= ABF_MAXFILES)) return ErrorReturn(pnError, ABF_EBADFILEINDEX); // Get a pointer to the descriptor. CFileDescriptor *pFI = g_FileData[nFile]; if (pFI == NULL) return ErrorReturn(pnError, ABF_EBADFILEINDEX); // Return the descriptor. *ppFI = pFI; return TRUE; } //----------------------------------------------------------------------------------------------- // FUNCTION: ReleaseFileDescriptor // PURPOSE: Release an existing file descriptor. // void ReleaseFileDescriptor(int nFile) { delete g_FileData[nFile]; g_FileData[nFile] = NULL; } //=============================================================================================== // FUNCTION: SampleSize // PURPOSE: Get the sample size used in the data described by the header. // static UINT SampleSize(const ABFFileHeader *pFH) { // ABFH_ASSERT(pFH); return (pFH->nDataFormat != ABF_INTEGERDATA) ? sizeof(float) : sizeof(short); } //=============================================================================================== // FUNCTION: SampleSize // PURPOSE: Get the sample size used in the data described by the header. // static UINT ABF2_SampleSize(const ABF2FileHeader *pFH) { // ABFH_ASSERT(pFH); return (pFH->nDataFormat != ABF_INTEGERDATA) ? sizeof(float) : sizeof(short); } //=============================================================================================== // FUNCTION: GetDataOffset // PURPOSE: Get the file offset to the data allowing for "ignored" points from old AxoLab files. // static ABFLONG GetDataOffset(const ABFFileHeader *pFH) { // ABFH_ASSERT(pFH); ABFLONG lDataOffset = pFH->lDataSectionPtr * ABF_BLOCKSIZE; // Adjust the data pointer for any garbage data words at the start of // the data portion of the file. (Created by AxoLab in continuous // files only) if (pFH->nOperationMode == ABF_GAPFREEFILE) lDataOffset += pFH->nNumPointsIgnored * SampleSize(pFH); return lDataOffset; } //=============================================================================================== // FUNCTION: GetDataOffset // PURPOSE: Get the file offset to the data allowing for "ignored" points from old AxoLab files. // static ABFLONG ABF2_GetDataOffset(const ABF2FileHeader *pFH) { // ABFH_ASSERT(pFH); ABFLONG lDataOffset = pFH->lDataSectionPtr * ABF_BLOCKSIZE; // Adjust the data pointer for any garbage data words at the start of // the data portion of the file. (Created by AxoLab in continuous // files only) if (pFH->nOperationMode == ABF_GAPFREEFILE) lDataOffset += pFH->nNumPointsIgnored * ABF2_SampleSize(pFH); return lDataOffset; } #if 0 //============================================================================================== // FUNCTION: CalculateCRC // PURPOSE: Return checksum Cyclic Redundancy Code CRC. // unsigned ABFLONG CalculateCRC( CFileDescriptor *pFI ) { WPTRASSERT( pFI); LONGLONG llReadPointer = 0L; BOOL bReadOk = FALSE; char acBuffer[ ABF_BLOCKSIZE ] = {0}; CRC crc(CRC::CRC_32); // Get the total length of the file. LONGLONG llFileLength = pFI->GetFileSize(); ASSERT(llFileLength >= sizeof(ABFFileHeader)); VERIFY(pFI->Seek( 0L, FILE_BEGIN)); while( llReadPointer < llFileLength ) { // Read a file block into the buffer. bReadOk = pFI->Read( acBuffer, ABF_BLOCKSIZE ); ASSERT( bReadOk ); // Update the CRC of the buffer crc.Update(acBuffer, ABF_BLOCKSIZE ); llReadPointer += ABF_BLOCKSIZE; } //#ifdef _DEBUG // TRACE1("Calculate CRC Value %X\n", crc.Value() ); //#endif // Set pointer at the beggining. VERIFY(pFI->Seek( 0L, FILE_BEGIN)); return crc.Value(); } //============================================================================================== // FUNCTION: ValidateFileCRC // PURPOSE: // static BOOL ValidateFileCRC( CFileDescriptor *pFI, ABFFileHeader *pFH, int nSizeOfHeader ) { WPTRASSERT( pFI ); WPTRASSERT( pFH ); // Validate CRC for files that support it. // The versions of ABF 1.82 and higher support CRC checksum. if( pFH->fFileVersionNumber < ABF_V182 ) return TRUE; // Valid and no checking. unsigned ABFLONG ulExpectedCRC = 0L; LONGLONG llReadPointer = 0L; BOOL bReadOk = FALSE; char acBuffer[ ABF_BLOCKSIZE ] = {0}; CRC crc(CRC::CRC_32); // Keep expected CRC value from header. ulExpectedCRC = pFH->ulFileCRC; // Zero the lFileCRC. The CRC is generated with this field as zero. pFH->ulFileCRC = 0; // Get the total length of the file. LONGLONG llFileLength = pFI->GetFileSize(); ASSERT(llFileLength >= nSizeOfHeader ); crc.Update( pFH, nSizeOfHeader ); llReadPointer = nSizeOfHeader; VERIFY(pFI->Seek( llReadPointer, FILE_BEGIN)); while( llReadPointer < llFileLength ) { // Read a file block into the buffer. bReadOk = pFI->Read( acBuffer, ABF_BLOCKSIZE ); ASSERT( bReadOk ); // Update the CRC of the buffer crc.Update(acBuffer, ABF_BLOCKSIZE ); llReadPointer += ABF_BLOCKSIZE; } #ifdef _DEBUG TRACE1("Validate CRC Value %X\n", crc.Value() ); #endif // Set pointer at the beggining. VERIFY(pFI->Seek( 0L, FILE_BEGIN)); unsigned ABFLONG ulFileCRC = crc.Value(); // Compare expected CRC with file CRC. if ( ulFileCRC != ulExpectedCRC ) { #ifdef _DEBUG TRACE( "File CRC Validation Failed\n" ); #endif return FALSE; } #ifdef _DEBUG TRACE( "File CRC Validation OK\n" ); #endif return TRUE; } #endif //=============================================================================================== // FUNCTION: ABF_Initialize() // PARAMETERS: // hInstance - Instance handle from which resources will be taken. // RETURNS: // BOOL - TRUE = Initialization was successful. // // PURPOSE: This function should be called before any of the other API functions. // NOTES: This function is not exported as it is called from the DLL startup code. If the // API is bound into an executable rather than a DLL it will need to be called // explicitly. // BOOL ABF_Initialize() { // Protect against multiple calls. /* if (g_hInstance != NULL) return TRUE; // Save the DLL instance handle. g_hInstance = hDLL; */ for (int i=0; i 15) // UINT uAvailableFiles = SetHandleCount(ABF_MAXFILES); uAvailableFiles = uAvailableFiles; #endif return TRUE; } #if 0 //=============================================================================================== // FUNCTION: ABF_Cleanup // PURPOSE: Cleanup function, only applicable to DOS & Windows programs, not DLLs. // NOTES: This function is not exported as it is called from the DLL startup code. If the // API is bound into an executable rather than a DLL it will need to be called // explicitly. // void ABF_Cleanup(void) { for (int i=0; iGetFileName()); ABF_Close(i, NULL); } } } #endif //=============================================================================================== // FUNCTION: ABF_ReadOpen // PURPOSE: This routine opens an existing data file for reading. It reads the acquisition // parameters, ADC/DAC unit strings and comment string from the file header. // INPUT: // szFileName the name of the data file that will be opened // fFlags Flag for whether the file is a parameter file // puMaxSamples points to the requested size of data blocks to be returned. // This is only used in the case of GAPFREE and EVENT-DETECTED- // VARIABLE-LENGTH acquisitions. Otherwise the size of the // Episode is used. 80x86 limitations require this to be // less than or equal to 64k. // pdwMaxEpi The maximum number of episodes to be read. // OUTPUT: // pFH the acquisition parameters that were read from the data file // phFile pointer to the ABF file number of this file (NOT the DOS handle) // puMaxSamples the maximum number of samples that can be read contiguously // from the data file. // pdwMaxEpi the number of episodes of puMaxSamples points that exist // in the data file. // BOOL WINAPI ABF_ReadOpen(LPCTSTR szFileName, int *phFile, UINT fFlags, ABFFileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError) { //LPSZASSERT(szFileName); WPTRASSERT(phFile); // CSH ABFH_WASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); int nError = 0; CFileDescriptor *pFI = NULL; UINT uDAC = 0; // Get a new file descriptor if available. if (!GetNewFileDescriptor(&pFI, phFile, pnError)) return FALSE; // Now open the file for reading. if (!pFI->Open(szFileName, TRUE)) { nError = pFI->GetLastError(); goto RCloseAndAbort; } // Read the data file parameters. if (!ABFH_ParamReader(pFI->GetFileHandle(), &NewFH, &nError)) { nError = (nError == ABFH_EUNKNOWNFILETYPE) ? ABF_EUNKNOWNFILETYPE : ABF_EBADPARAMETERS; goto RCloseAndAbort; } if (NewFH.lFileSignature == ABF_REVERSESIGNATURE) { nError = ABF_EBADPARAMETERS; goto RCloseAndAbort; } // if we are reading a parameter file, we are done. if (fFlags & ABF_PARAMFILE) { // If it is an old (pre-ABF file), update file version and file type. if( (NewFH.nFileType == ABF_CLAMPEX) || (NewFH.nFileType == ABF_FETCHEX) ) { NewFH.nFileType = ABF_ABFFILE; NewFH.fFileVersionNumber = ABF_CURRENTVERSION; } pFI->SetFlag(FI_PARAMFILE); // Restore the original header. ABFH_DemoteHeader( pFH, &NewFH ); return TRUE; } // Check for valid parameters. // WPTRASSERT(puMaxSamples); // WPTRASSERT(pdwMaxEpi); // Check that the data file actually contains data. if ((NewFH.lActualAcqLength <= 0) || (NewFH.nADCNumChannels <= 0)) { nError = ABF_EBADPARAMETERS; goto RCloseAndAbort; } // Disable stimulus file output if data file does not include any // stimulus file sweeps. This is to prevent problems later when // looking for a non-existent DACFile section. for( uDAC=0; uDACSetAcquiredEpisodes(*pdwMaxEpi); pFI->SetAcquiredSamples(NewFH.lActualAcqLength); // Seek to start of Data section pFI->Seek(GetDataOffset(&NewFH), FILE_BEGIN); // Restore the original header. ABFH_DemoteHeader( pFH, &NewFH ); return TRUE; RCloseAndAbort: ASSERT(nError!=0); ReleaseFileDescriptor(*phFile); phFile = ABF_INVALID_HANDLE; return ErrorReturn(pnError, nError); } #if 0 //=============================================================================================== // FUNCTION: ABF_IsABFFile // PURPOSE: This routine opens a file and determines if it is an ABF file or not. // RETURNS: TRUE if the file is an ABF file. The type of ABF file is returned in // *pnDataFormat: ABF_INTEGERDATA or ABF_FLOATDATA. // BOOL WINAPI ABF_IsABFFile(const char *szFileName, int *pnDataFormat, int *pnError) { LPSZASSERT(szFileName); int nError = 0; // Now open the file for reading. HANDLE hHandle = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hHandle == INVALID_HANDLE_VALUE) { if (GetLastError()==ERROR_TOO_MANY_OPEN_FILES) return ErrorReturn(pnError, ABF_NODOSFILEHANDLES); return ErrorReturn(pnError, ABF_EOPENFILE); } // Read the data file parameters. ABFFileHeader FH; if (!ABFH_ParamReader(hHandle, &FH, &nError)) { if (nError == ABFH_EUNKNOWNFILETYPE) nError = ABF_EUNKNOWNFILETYPE; else nError = ABF_EBADPARAMETERS; } CloseHandle(hHandle); if (nError) return ErrorReturn(pnError, nError); if (pnDataFormat) *pnDataFormat = FH.nDataFormat; return TRUE; } //=============================================================================================== // FUNCTION: ABF_WriteOpen // PURPOSE: This routine opens an existing data file for writing. // It writes all the acquisition parameters to the file header. // INPUT: // szFileName the name of the data file that will be opened // phFile pointer to the ABF file number of this file (NOT the DOS handle) // fFlags Flag for whether the file is a parameter file // pFH the acquisition parameters to be written to the data file // // OUTPUT: // NONE. // BOOL WINAPI ABF_WriteOpen(LPCSTR szFileName, int *phFile, UINT fFlags, ABFFileHeader *pFH, int *pnError) { LPSZASSERT(szFileName); WPTRASSERT(phFile); ABFH_WASSERT(pFH); // Get a new file descriptor if available. CFileDescriptor *pFI = NULL; if (!GetNewFileDescriptor(&pFI, phFile, pnError)) return FALSE; // Now create and open the file for writing if (!pFI->Open(szFileName, FALSE)) { // An error has occurred, cleanup and return the error. int nError = pFI->GetLastError(); ReleaseFileDescriptor(*phFile); *phFile = ABF_INVALID_HANDLE; return ErrorReturn(pnError, nError); } // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); NewFH.lDataSectionPtr = sizeof(ABFFileHeader) / ABF_BLOCKSIZE; NewFH.lScopeConfigPtr = 0; NewFH.lStatisticsConfigPtr = 0; NewFH.lNumScopes = 0; NewFH.lActualAcqLength = 0; NewFH.lActualEpisodes = 0; NewFH.nNumPointsIgnored = 0; NewFH.lTagSectionPtr = 0; NewFH.lNumTagEntries = 0; NewFH._lDACFilePtr = 0; NewFH._lDACFileNumEpisodes = 0; NewFH.lDeltaArrayPtr = 0; NewFH.lNumDeltas = 0; NewFH.lSynchArrayPtr = 0; NewFH.lSynchArraySize = 0; NewFH.lVoiceTagPtr = 0; NewFH.lVoiceTagEntries = 0; NewFH.lAnnotationSectionPtr= 0; NewFH.lNumAnnotations = 0; NewFH.ulFileCRC = 0; for( UINT i=0; iSetFlag(FI_PARAMFILE); // Create a GUID for this file. NewFH.FileGUID = GUID_NULL; ::CoCreateGuid(&NewFH.FileGUID); // Write the data file parameters, returning if successful. if (!ABFH_ParamWriter(pFI->GetFileHandle(), &NewFH, NULL)) { // An error has occurred, cleanup and return the error. ReleaseFileDescriptor(*phFile); *phFile = ABF_INVALID_HANDLE; remove(szFileName); return ErrorReturn(pnError, ABF_EDISKFULL); } // Calculate CRC in current file descriptor. // lFileCRC needs to be zero during the calculation. NewFH.ulFileCRC = CalculateCRC( pFI ); // Update the header in the file descriptor with CRC in place. VERIFY(pFI->Seek( 0L, FILE_BEGIN)); if (!ABFH_ParamWriter(pFI->GetFileHandle(), &NewFH, NULL)) return ErrorReturn(pnError, ABF_EDISKFULL); // Restore the original header. ABFH_DemoteHeader( pFH, &NewFH ); return TRUE; } //=============================================================================================== // FUNCTION: WriteSynchArray // PURPOSE: This routine writes the Synch array out to disk // static BOOL WriteSynchArray(CFileDescriptor *pFI, ABFFileHeader *pFH, int *pnError) { WPTRASSERT(pFI); ABFH_WASSERT(pFH); // Return if no write is required. if (pFI->TestFlag(FI_PARAMFILE)) return TRUE; // Transfer the synch array to the ABF file, checking to see that the synch array // only refers to data that was actually saved. if (!pFI->WriteSynchArray( &pFH->lSynchArrayPtr, &pFH->lSynchArraySize, SampleSize(pFH) )) return ErrorReturn(pnError, ABF_EDISKFULL); pFH->lActualEpisodes = pFH->lSynchArraySize; pFH->lActualAcqLength = pFI->GetAcquiredSamples(); return TRUE; } //=============================================================================================== // FUNCTION: WriteTags // PURPOSE: This routine writes the accumulated tags out to disk // static BOOL WriteTags(CFileDescriptor *pFI, ABFFileHeader *pFH, int *pnError) { WPTRASSERT(pFI); ABFH_WASSERT(pFH); if (!pFI->WriteTags( &pFH->lTagSectionPtr, &pFH->lNumTagEntries )) return ErrorReturn(pnError, ABF_EDISKFULL); if (!pFI->WriteVoiceTags( &pFH->lVoiceTagPtr, &pFH->lVoiceTagEntries )) return ErrorReturn(pnError, ABF_EDISKFULL); return TRUE; } #endif //=============================================================================================== // FUNCTION: ABF_HasData // PURPOSE: This routine returns TRUE if data has been written to the file since opening it. // BOOL WINAPI ABF_HasData(int nFile, const ABFFileHeader *pFH) { // ABFH_ASSERT(pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, NULL)) return FALSE; // Take a copy of the passed in header to ensure it is 5k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); if (NewFH.lDataSectionPtr==0) return FALSE; // Assume that only data has been written to the file at this point. ASSERT(NewFH.lSynchArrayPtr==0); ASSERT(NewFH.lTagSectionPtr==0); ASSERT(NewFH.lVoiceTagPtr==0); ASSERT(NewFH.lDeltaArrayPtr==0); ASSERT(NewFH.lAnnotationSectionPtr==0); ASSERT(NewFH.lDACFilePtr[0]==0); ASSERT(NewFH.lDACFilePtr[1]==0); return (pFI->GetFileSize() > NewFH.lDataSectionPtr * ABF_BLOCKSIZE); } #if 0 //=============================================================================================== // FUNCTION: ABF_UpdateHeader // PURPOSE: This routine should always be called before closing a file opened with // ABF_WriteOpen. It updates the file header and writes the synch array out // to disk if required. // BOOL WINAPI ABF_UpdateHeader(int nFile, ABFFileHeader *pFH, int *pnError) { ABFH_WASSERT(pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (pFI->TestFlag(FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); // Assume that only data has been written to the file at this point. //GR 12-Jan-2001: These used to be asserts to assert that these values //were all equal to 0. This was causing assertion failures when //attempting to copy part or all of an analysis window file as an //atf file for the second time. //The logic is that if these variables are no longer 0, then we have //already written the file header and don't need to write it again. //And what if the header settings have changed since last time we //wrote them? Then the temporary file should have been re-written //and these variables will be 0 again. I think. if( (NewFH.lSynchArrayPtr!=0) || (NewFH.lTagSectionPtr!=0) || (NewFH.lVoiceTagPtr!=0) || (NewFH.lAnnotationSectionPtr!=0) || (NewFH.lDeltaArrayPtr!=0) ) { return TRUE; } for( UINT i=0; iGetFileSize(); ASSERT(llFileLength >= sizeof(ABFFileHeader)); // Calculate the number of data samples in the file. UINT uAcquiredSamples = UINT((llFileLength - NewFH.lDataSectionPtr * ABF_BLOCKSIZE)/SampleSize(&NewFH)); pFI->SetAcquiredSamples(uAcquiredSamples); if (pFI->GetSynchCount() != 0) { // Write the synch array out to disk, storing the size and location // of the Synch array in the header in the process. if (!WriteSynchArray(pFI, &NewFH, pnError)) { // Truncate the file at the end of the data section. VERIFY(pFI->Seek( llFileLength, FILE_END)); VERIFY(pFI->SetEndOfFile()); return FALSE; } // Switch the synch array to read mode to allow access to synch array in Save As (PRC 6/99) pFI->SetSynchMode( CSynch::eREADMODE ); } else if (NewFH.nOperationMode == ABF_GAPFREEFILE) { NewFH.lEpisodesPerRun = 1; NewFH.lRunsPerTrial = 1; NewFH.lActualAcqLength = uAcquiredSamples; NewFH.lActualEpisodes = uAcquiredSamples / NewFH.lNumSamplesPerEpisode; // Allow for the last (possibly incomplete) episode. if( uAcquiredSamples % NewFH.lNumSamplesPerEpisode ) NewFH.lActualEpisodes++; } else if (NewFH.nOperationMode == ABF_WAVEFORMFILE) { UINT uAcquiredEpisodes = uAcquiredSamples / NewFH.lNumSamplesPerEpisode; uAcquiredSamples = uAcquiredEpisodes * NewFH.lNumSamplesPerEpisode; pFI->SetAcquiredEpisodes(uAcquiredEpisodes); pFI->SetAcquiredSamples(uAcquiredSamples); NewFH.lActualEpisodes = uAcquiredEpisodes; NewFH.lActualAcqLength = uAcquiredSamples; } if (pFI->GetTagCount() > 0) { // Write the tags out to disk, storing the size and location // of the tag block in the header in the process. if (!WriteTags(pFI, &NewFH, pnError)) { // Truncate the file at the end of the data section. VERIFY(pFI->Seek( llFileLength, FILE_END)); VERIFY(pFI->SetEndOfFile()); return FALSE; } } if (pFI->GetDeltaCount() > 0) { // Write the deltas out to disk, storing the size and location // of the delta array in the header in the process. if (!pFI->WriteDeltas( &NewFH.lDeltaArrayPtr, &NewFH.lNumDeltas )) { // Truncate the file at the end of the data section. VERIFY(pFI->Seek( llFileLength, FILE_END)); VERIFY(pFI->SetEndOfFile()); return ErrorReturn(pnError, ABF_EDISKFULL); } } if (pFI->GetAnnotationCount() > 0) { // Write the annotations out to disk, storing the size and location // of the annotations section in the header in the process. if(!pFI->WriteAnnotations( &NewFH.lAnnotationSectionPtr, &NewFH.lNumAnnotations ) ) { // Truncate the file at the end of the data section. VERIFY(pFI->Seek( llFileLength, FILE_END)); VERIFY(pFI->SetEndOfFile()); return ErrorReturn(pnError, ABF_EDISKFULL); } } for(int i=0; iGetDACFileSweepCount(i) > 0) { // Write the deltas out to disk, storing the size and location // of the delta array in the header in the process. if (!pFI->WriteDACFileSweeps( i, &NewFH.lDACFilePtr[i], &NewFH.lDACFileNumEpisodes[i] )) { // Truncate the file at the end of the data section. VERIFY(pFI->Seek( llFileLength, FILE_END)); VERIFY(pFI->SetEndOfFile()); return ErrorReturn(pnError, ABF_EDISKFULL); } } } // Read back the header image that was written when the file was opened. ABFFileHeader OldHeader; VERIFY(pFI->Seek( 0L, FILE_BEGIN)); UINT uHeaderSize = ABF_OLDHEADERSIZE; if( ABFH_IsNewHeader(&NewFH) ) uHeaderSize = ABF_HEADERSIZE; VERIFY(pFI->Read(&OldHeader, uHeaderSize)); // Create a copy of the header as it stands now (post acquisition). ABFFileHeader NewHeader = NewFH; // Copy the original values of items that can be subject to deltas into the new header. // This ensures the copy on disk is the original values (with delta info) and the client // has the current (updated with deltas) settings. // This list should be maintained along with the enumeration for delta types in ABFHEADR.H // Delta type: ABF_DELTA_HOLDING0 .. ABF_DELTA_HOLDING3 for (int i=0; iSeek( 0L, FILE_BEGIN)); if (!ABFH_ParamWriter(pFI->GetFileHandle(), &NewHeader, NULL)) return ErrorReturn(pnError, ABF_EDISKFULL); // Update the current file length. ABFLONG lCurrentFileSize = (ABFLONG)pFI->GetFileSize(); // Pad with zeroes to the nearest block boundary. pFI->FillToNextBlock( &lCurrentFileSize ); // Calculate CRC in current file descriptor. NewHeader.ulFileCRC = CalculateCRC( pFI ); // Update the header in the file descriptor with CRC in place. VERIFY(pFI->Seek( 0L, FILE_BEGIN)); if (!ABFH_ParamWriter(pFI->GetFileHandle(), &NewHeader, NULL)) return ErrorReturn(pnError, ABF_EDISKFULL); ABFH_DemoteHeader( pFH, &NewFH ); return TRUE; } #endif //=============================================================================================== // FUNCTION: ABF_Close // PURPOSE: This routine closes the current data file and cleans up any work buffers that // were allocated for processing the data. // BOOL WINAPI ABF_Close(int nFile, int *pnError) { CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) { // TRACE("ABF_Close failed.\n"); return FALSE; } ReleaseFileDescriptor(nFile); return TRUE; } //=============================================================================================== // FUNCTION: SamplesToSynchCounts // PURPOSE: Converts a value in multiplexed samples to Synch Time Units. // static UINT SamplesToSynchCounts(const ABFFileHeader *pFH, UINT uSamples) { DWORD dwLengthInSynchUnits = uSamples; if( pFH->fSynchTimeUnit != 0.0F ) { double dLen = dwLengthInSynchUnits * ABFH_GetFirstSampleInterval(pFH) * pFH->nADCNumChannels / 1E3; dLen = floor( dLen + 0.5 ); dwLengthInSynchUnits = DWORD( dLen ); } return dwLengthInSynchUnits; } //=============================================================================================== // FUNCTION: SamplesToSynchCounts // PURPOSE: Converts a value in multiplexed samples to Synch Time Units. // static UINT ABF2_SamplesToSynchCounts(const ABF2FileHeader *pFH, UINT uSamples) { DWORD dwLengthInSynchUnits = uSamples; if( pFH->fSynchTimeUnit != 0.0F ) { double dLen = dwLengthInSynchUnits * ABF2H_GetFirstSampleInterval(pFH) * pFH->nADCNumChannels / 1E3; dLen = floor( dLen + 0.5 ); dwLengthInSynchUnits = DWORD( dLen ); } return dwLengthInSynchUnits; } //=============================================================================================== // FUNCTION: ExpandSynchEntry // PURPOSE: Unpacks a synch entry into one or more chunks no greater than the max chunk size. // static void ExpandSynchEntry(const ABFFileHeader *pFH, CSynch &SynchArray, Synch *pItem, UINT uChunkSize, UINT uSampleSize) { UINT uStart = pItem->dwStart; UINT uLength = pItem->dwLength; UINT uFileOffset = pItem->dwFileOffset; while (uLength > uChunkSize) { SynchArray.Put(uStart, uChunkSize, uFileOffset); uStart += SamplesToSynchCounts( pFH, uChunkSize ); uFileOffset += uChunkSize * uSampleSize; uLength -= uChunkSize; } SynchArray.Put(uStart, uLength, uFileOffset); } //=============================================================================================== // FUNCTION: ExpandSynchEntry // PURPOSE: Unpacks a synch entry into one or more chunks no greater than the max chunk size. // static void ABF2_ExpandSynchEntry(const ABF2FileHeader *pFH, CSynch &SynchArray, Synch *pItem, UINT uChunkSize, UINT uSampleSize) { UINT uStart = pItem->dwStart; UINT uLength = pItem->dwLength; UINT uFileOffset = pItem->dwFileOffset; while (uLength > uChunkSize) { SynchArray.Put(uStart, uChunkSize, uFileOffset); uStart += ABF2_SamplesToSynchCounts( pFH, uChunkSize ); uFileOffset += uChunkSize * uSampleSize; uLength -= uChunkSize; } SynchArray.Put(uStart, uLength, uFileOffset); } //=============================================================================================== // FUNCTION: _SetChunkSize // PURPOSE: This routine can be called on files of type ABF_GAPFREEFILE or ABF_VARLENEVENTS to change // the size of the data chunks returned by the read routines. // INPUT: // hFile ABF file number of this file (NOT the DOS handle) // pFH the current acquisition parameters for the data file // puMaxSamples points to the requested size of data blocks to be returned. // This is only used in the case of GAPFREE and EVENT-DETECTED- // VARIABLE-LENGTH acquisitions. Otherwise the size of the // Episode is used. 80x86 limitations require this to be // less than or equal to 64k. // pdwMaxEpi The maximum number of episodes to be read. // OUTPUT: // pFH the acquisition parameters that were read from the data file // puMaxSamples the maximum number of samples that can be read contiguously // from the data file. // pdwMaxEpi the number of episodes of puMaxSamples points that exist // in the data file. // static BOOL _SetChunkSize( CFileDescriptor *pFI, ABFFileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError ) { // Check for valid parameters. // WPTRASSERT(puMaxSamples); // WPTRASSERT(pdwMaxEpi); // Check that requested chunk size is reasonable. // If chunk-size is zero, it is treated as a request for ABF to set a reasonable // chunk-size. An error is returned if chunk-size is given but too small. // If the size given is too big, it is set to the largest possible size. UINT uLimSamples = PCLAMP7_MAXSWEEPLEN_PERCHAN; UINT uMaxSamples = *puMaxSamples; // if uMaxSamples == -1, restore the chunk size to the "raw" value (i.e. from disk). if ((int)uMaxSamples != -1 ) { if (uMaxSamples == 0) uMaxSamples = ABF_DEFAULTCHUNKSIZE / pFH->nADCNumChannels; else if (uMaxSamples > uLimSamples) uMaxSamples = uLimSamples; } UINT uAcqLenPerChannel = UINT(pFH->lActualAcqLength / pFH->nADCNumChannels); if (uMaxSamples > uAcqLenPerChannel) uMaxSamples = uAcqLenPerChannel; pFH->lNumSamplesPerEpisode = ABFLONG(uMaxSamples * pFH->nADCNumChannels); // Set the return value for the read chunk size. *puMaxSamples = (UINT)(pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels); // Scan through the synch array building up into full event sizes and then // subdividing down into multiples of the chunk size. if (pFI->GetSynchCount() <= 0) { // Only ABF_GAPFREEFILEs and ABF_WAVEFORMFILEs can optionally have synch arrays. ASSERT((pFH->nOperationMode == ABF_GAPFREEFILE) || (pFH->nOperationMode == ABF_WAVEFORMFILE)); // Gap-free files only have synch arrays if they have been paused during recording // If there is no synch array, work out how many chunks we have etc. // // Gapfree files without synch arrays need to know the size of the last episode // (this can be less than the episode size for gap-free data) UINT uMaxEpi = uAcqLenPerChannel / uMaxSamples; UINT uLastEpiSize = uAcqLenPerChannel % uMaxSamples; if (uLastEpiSize > 0) { uMaxEpi++; ASSERT(pFH->nOperationMode == ABF_GAPFREEFILE); } else uLastEpiSize = uMaxSamples; *pdwMaxEpi = uMaxEpi; pFI->SetLastEpiSize(uLastEpiSize * pFH->nADCNumChannels); } else if ((pFH->nOperationMode == ABF_GAPFREEFILE) || (pFH->nOperationMode == ABF_VARLENEVENTS)) { // Create a new synch array that we can build from the old one. CSynch NewSynchArray; if (!NewSynchArray.OpenFile()) return ErrorReturn(pnError, ABF_BADTEMPFILE); // Cache some useful constants const UINT uSampleSize = SampleSize(pFH); const UINT uSynchCount = pFI->GetSynchCount(); const UINT uMaxChunkSize = *puMaxSamples * UINT(pFH->nADCNumChannels); // Get the first entry. Synch LastItem = { 0 }; pFI->GetSynchEntry(1, &LastItem); // Loop through the rest of the entries. for (UINT i=2; i<=uSynchCount; i++) { // For event detected variable length data files, episodes may be larger then // wFullEpisodeSize. These will be broken up into multiple units of length // uMaxChunkSize or less, and the Synch array adjusted accordingly. // Calculate file offsets and expand out any episodes longer than // uMaxChunkSize to span multiple Synch entries. Synch SynchItem; pFI->GetSynchEntry(i, &SynchItem); // if there are no missing samples, add this length to the previous entry. if( SynchItem.dwStart == LastItem.dwStart + SamplesToSynchCounts(pFH, LastItem.dwLength) ) LastItem.dwLength += SynchItem.dwLength; else { ExpandSynchEntry(pFH, NewSynchArray, &LastItem, uMaxChunkSize, uSampleSize); LastItem = SynchItem; } } ExpandSynchEntry(pFH, NewSynchArray, &LastItem, uMaxChunkSize, uSampleSize); if (pFI->TestFlag(FI_READONLY)) NewSynchArray.SetMode(CSynch::eREADMODE); pFI->ChangeSynchArray(&NewSynchArray); *pdwMaxEpi = pFI->GetSynchCount(); } else { // ERRORMSG("ABF_SetChunkSize should only be used on ABF_GAPFREEFILE or ABF_VARLENEVENTS ABF files"); } // Set header variable for the number of episodes in the file. pFH->lActualEpisodes = *pdwMaxEpi; pFI->SetAcquiredEpisodes(*pdwMaxEpi); pFI->FreeReadBuffer(); return TRUE; } //=============================================================================================== // FUNCTION: _SetChunkSize // PURPOSE: This routine can be called on files of type ABF_GAPFREEFILE or ABF_VARLENEVENTS to change // the size of the data chunks returned by the read routines. // INPUT: // hFile ABF file number of this file (NOT the DOS handle) // pFH the current acquisition parameters for the data file // puMaxSamples points to the requested size of data blocks to be returned. // This is only used in the case of GAPFREE and EVENT-DETECTED- // VARIABLE-LENGTH acquisitions. Otherwise the size of the // Episode is used. 80x86 limitations require this to be // less than or equal to 64k. // pdwMaxEpi The maximum number of episodes to be read. // OUTPUT: // pFH the acquisition parameters that were read from the data file // puMaxSamples the maximum number of samples that can be read contiguously // from the data file. // pdwMaxEpi the number of episodes of puMaxSamples points that exist // in the data file. // static BOOL ABF2_SetChunkSize( CFileDescriptor *pFI, ABF2FileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError ) { // Check for valid parameters. // WPTRASSERT(puMaxSamples); // WPTRASSERT(pdwMaxEpi); // Check that requested chunk size is reasonable. // If chunk-size is zero, it is treated as a request for ABF to set a reasonable // chunk-size. An error is returned if chunk-size is given but too small. // If the size given is too big, it is set to the largest possible size. UINT uLimSamples = PCLAMP7_MAXSWEEPLEN_PERCHAN; UINT uMaxSamples = *puMaxSamples; // if uMaxSamples == -1, restore the chunk size to the "raw" value (i.e. from disk). if ((int)uMaxSamples != -1 ) { if (uMaxSamples == 0) uMaxSamples = ABF_DEFAULTCHUNKSIZE / pFH->nADCNumChannels; else if (uMaxSamples > uLimSamples) uMaxSamples = uLimSamples; } UINT uAcqLenPerChannel = UINT(pFH->lActualAcqLength / pFH->nADCNumChannels); if (uMaxSamples > uAcqLenPerChannel) uMaxSamples = uAcqLenPerChannel; pFH->lNumSamplesPerEpisode = ABFLONG(uMaxSamples * pFH->nADCNumChannels); // Set the return value for the read chunk size. *puMaxSamples = (UINT)(pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels); // Scan through the synch array building up into full event sizes and then // subdividing down into multiples of the chunk size. if (pFI->GetSynchCount() <= 0) { // Only ABF_GAPFREEFILEs and ABF_WAVEFORMFILEs can optionally have synch arrays. ASSERT((pFH->nOperationMode == ABF_GAPFREEFILE) || (pFH->nOperationMode == ABF_WAVEFORMFILE)); // Gap-free files only have synch arrays if they have been paused during recording // If there is no synch array, work out how many chunks we have etc. // // Gapfree files without synch arrays need to know the size of the last episode // (this can be less than the episode size for gap-free data) UINT uMaxEpi = uAcqLenPerChannel / uMaxSamples; UINT uLastEpiSize = uAcqLenPerChannel % uMaxSamples; if (uLastEpiSize > 0) { uMaxEpi++; ASSERT(pFH->nOperationMode == ABF_GAPFREEFILE); } else uLastEpiSize = uMaxSamples; *pdwMaxEpi = uMaxEpi; pFI->SetLastEpiSize(uLastEpiSize * pFH->nADCNumChannels); } else if ((pFH->nOperationMode == ABF_GAPFREEFILE) || (pFH->nOperationMode == ABF_VARLENEVENTS)) { // Create a new synch array that we can build from the old one. CSynch NewSynchArray; if (!NewSynchArray.OpenFile()) return ErrorReturn(pnError, ABF_BADTEMPFILE); // Cache some useful constants const UINT uSampleSize = ABF2_SampleSize(pFH); const UINT uSynchCount = pFI->GetSynchCount(); const UINT uMaxChunkSize = *puMaxSamples * UINT(pFH->nADCNumChannels); // Get the first entry. Synch LastItem = { 0 }; pFI->GetSynchEntry(1, &LastItem); // Loop through the rest of the entries. for (UINT i=2; i<=uSynchCount; i++) { // For event detected variable length data files, episodes may be larger then // wFullEpisodeSize. These will be broken up into multiple units of length // uMaxChunkSize or less, and the Synch array adjusted accordingly. // Calculate file offsets and expand out any episodes longer than // uMaxChunkSize to span multiple Synch entries. Synch SynchItem; pFI->GetSynchEntry(i, &SynchItem); // if there are no missing samples, add this length to the previous entry. if( SynchItem.dwStart == LastItem.dwStart + ABF2_SamplesToSynchCounts(pFH, LastItem.dwLength) ) LastItem.dwLength += SynchItem.dwLength; else { ABF2_ExpandSynchEntry(pFH, NewSynchArray, &LastItem, uMaxChunkSize, uSampleSize); LastItem = SynchItem; } } ABF2_ExpandSynchEntry(pFH, NewSynchArray, &LastItem, uMaxChunkSize, uSampleSize); if (pFI->TestFlag(FI_READONLY)) NewSynchArray.SetMode(CSynch::eREADMODE); pFI->ChangeSynchArray(&NewSynchArray); *pdwMaxEpi = pFI->GetSynchCount(); } else { // ERRORMSG("ABF_SetChunkSize should only be used on ABF_GAPFREEFILE or ABF_VARLENEVENTS ABF files"); } // Set header variable for the number of episodes in the file. pFH->lActualEpisodes = *pdwMaxEpi; pFI->SetAcquiredEpisodes(*pdwMaxEpi); pFI->FreeReadBuffer(); return TRUE; } //=============================================================================================== // FUNCTION: ReadEDVarLenSynch // PURPOSE: This function shifts and expands the temporary Synch buffer to the Synch // array for a Variable-Length-Event-Detected file. // static BOOL ReadEDVarLenSynch(CFileDescriptor *pFI, ABFFileHeader *pFH, DWORD *pdwMaxEpi, UINT *puMaxSamples, int *pnError) { WPTRASSERT(pFI); // ABFH_WASSERT(pFH); WPTRASSERT(pdwMaxEpi); // If a synch array exists, read it into the virtual synch array as is. if ((pFH->lSynchArraySize > 0) && (pFH->lSynchArrayPtr > 0)) { // All variable length and gapfree ABF files use use samples as synch time counts. // However, statistics ATF files read in via ATF2ABF32 use synch time units which // are NOT samples, so we need to handle that situation. // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // Read the synch array in chunks, writing it out to the virtual synch array. // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFileReadCache SynchFile; if (!SynchFile.Initialize(sizeof(ABFSynch), SYNCH_BUFFER_SIZE, pFI->GetFileHandle(), LONGLONG(pFH->lSynchArrayPtr) * ABF_BLOCKSIZE, pFH->lSynchArraySize)) return ErrorReturn(pnError, ABF_OUTOFMEMORY); UINT uSampleSize = SampleSize(pFH); UINT uAcqLength = UINT(pFH->lActualAcqLength); UINT uFileOffset = 0; UINT uLastStart = 0; for (UINT i=0; ilSynchArraySize); i++) { ABFSynch *pS = (ABFSynch *)SynchFile.Get(i); if (!pS) return ErrorReturn(pnError, ABF_EBADSYNCH); UINT uStart = pS->lStart; UINT uLength = pS->lLength; // Check synch entry length. if (uLength > uAcqLength) return ErrorReturn(pnError, ABF_EBADSYNCH); // check that entries are consecutive if( uStart < uLastStart ) return ErrorReturn(pnError, ABF_EBADSYNCH); uLastStart = uStart; pFI->PutSynchEntry(uStart, uLength, uFileOffset); uFileOffset += uLength * uSampleSize; uAcqLength -= uLength; } pFI->SetSynchMode( CSynch::eREADMODE ); } return _SetChunkSize( pFI, pFH, puMaxSamples, pdwMaxEpi, pnError ); } //=============================================================================================== // FUNCTION: _SetOverlap // PURPOSE: Changes the overlap flag and processes the synch array to edit redundant data out if no overlap. // static BOOL _SetOverlap(CFileDescriptor *pFI, const ABFFileHeader *pFH, BOOL bAllowOverlap, int *pnError) { // ABFH_ASSERT(pFH); // Only fixed length events files have overlapping events. if (pFH->nOperationMode != ABF_FIXLENEVENTS) return TRUE; // Fixed length events files always use samples for synch time units. ASSERT(pFH->fSynchTimeUnit==0.0F); // If none of the sweeps overlap there is nothing to do, get out now. if (!pFI->GetOverlappedFlag()) return TRUE; // Create a new synch array that we can build from the old one. CSynch NewSynchArray; if (!NewSynchArray.OpenFile()) return ErrorReturn(pnError, ABF_BADTEMPFILE); // Cache some useful constants const UINT uSynchCount = pFI->GetSynchCount(); if (bAllowOverlap) { Synch Item = { 0 }; UINT uSweepLength = UINT(pFH->lNumSamplesPerEpisode); // Loop through entries setting them all to the sweep length. for (UINT i=1; i<=uSynchCount; i++) { pFI->GetSynchEntry(i, &Item); NewSynchArray.Put(Item.dwStart, uSweepLength, Item.dwFileOffset); } } else { // Get the first entry. Synch LastItem = { 0 }; pFI->GetSynchEntry(1, &LastItem); // Loop through the rest of the entries. for (UINT i=2; i<=uSynchCount; i++) { Synch SynchItem; pFI->GetSynchEntry(i, &SynchItem); if ((SynchItem.dwStart != ABF_AVERAGESWEEPSTART) && (LastItem.dwStart != ABF_AVERAGESWEEPSTART)) { // If redundant data is found, then truncate this episode if // overlapped data is not to be allowed. if (LastItem.dwStart + LastItem.dwLength > SynchItem.dwStart) LastItem.dwLength = SynchItem.dwStart - LastItem.dwStart; } NewSynchArray.Put(LastItem.dwStart, LastItem.dwLength, LastItem.dwFileOffset); LastItem = SynchItem; } NewSynchArray.Put(LastItem.dwStart, LastItem.dwLength, LastItem.dwFileOffset); } if (pFI->TestFlag(FI_READONLY)) NewSynchArray.SetMode(CSynch::eREADMODE); pFI->ChangeSynchArray(&NewSynchArray); return TRUE; } //=============================================================================================== // FUNCTION: ReadEDFixLenSynch // PURPOSE: Reads a fixed length synch array off disk and stores it away in a synch buffer. // Overlapping episodes are truncated so that the user is only returned data once. // static BOOL ReadEDFixLenSynch(CFileDescriptor *pFI, const ABFFileHeader *pFH, DWORD *pdwMaxEpi, BOOL bAllowOverlap, int *pnError) { WPTRASSERT(pFI); WPTRASSERT(pdwMaxEpi); // ABFH_ASSERT(pFH); if ((pFH->lSynchArraySize <= 0) || (pFH->lSynchArrayPtr <= 0)) { // Only waveform files can optionally have a synch array. if (pFH->nOperationMode!=ABF_WAVEFORMFILE) return ErrorReturn(pnError, ABF_ENOSYNCHPRESENT); *pdwMaxEpi = pFH->lActualEpisodes; return TRUE; } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . // read the synch array in chunks, writing it out to the virtual synch array. // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFileReadCache SynchFile; if (!SynchFile.Initialize(sizeof(ABFSynch), SYNCH_BUFFER_SIZE, pFI->GetFileHandle(), LONGLONG(pFH->lSynchArrayPtr) * ABF_BLOCKSIZE, pFH->lSynchArraySize)) return ErrorReturn(pnError, ABF_OUTOFMEMORY); BOOL bOverlapFound = FALSE; UINT uFileOffset = 0; UINT uSampleSize = SampleSize(pFH); UINT uAcqLength = UINT(pFH->lActualAcqLength); // Get the first entry. ABFSynch *pS = (ABFSynch *)SynchFile.Get(0); if (!pS) return ErrorReturn(pnError, ABF_EBADSYNCH); UINT uStart = pS->lStart; UINT uLength = pS->lLength; // Loop n-1 times checking the entry against the following one. for (UINT i=1; ilSynchArraySize); i++) { // All episodes should be of the same length. ASSERT(uLength == UINT(pFH->lNumSamplesPerEpisode)); // Check synch entry range if (uLength > uAcqLength) return ErrorReturn(pnError, ABF_EBADSYNCH); // Event detected modes are described by a Synch array that specifies each // episode's position and length in the data file. pS = (ABFSynch *)SynchFile.Get(i); if (!pS) return ErrorReturn(pnError, ABF_EBADSYNCH); if ((pFH->nOperationMode!=ABF_WAVEFORMFILE) && (uStart!=ABF_AVERAGESWEEPSTART)) { // Only fix-len event detected files can have overlapping sweeps, and these // always use samples as synch time counts -- this simplifies comparisons. ASSERT(pFH->fSynchTimeUnit==0.0); // Some versions of AxoTape produced negative entries in the synch array. // DEMOTAPE (Axotape-for-DOS demo version) creates corrupted synch arrays... if (ABFLONG(uStart) < 0) return ErrorReturn(pnError, ABF_EBADSYNCH); // Check for redundant data in following episodes if (pS->lStart > -1) { // check that entries are consecutive if (UINT(pS->lStart) <= uStart) return ErrorReturn(pnError, ABF_EBADSYNCH); // If redundant data is found, then truncate this episode if // overlapped data is not to be allowed. if (uStart + uLength > UINT(pS->lStart)) bOverlapFound = TRUE; } } pFI->PutSynchEntry(uStart, uLength, uFileOffset); uFileOffset += uLength * uSampleSize; uAcqLength -= uLength; uStart = pS->lStart; uLength = pS->lLength; } // Put the last entry into the synch array. pFI->PutSynchEntry(uStart, uLength, uFileOffset); *pdwMaxEpi = UINT(pFH->lSynchArraySize); pFI->SetSynchMode( CSynch::eREADMODE ); pFI->SetOverlappedFlag(bOverlapFound); return _SetOverlap(pFI, pFH, bAllowOverlap, pnError); } //=============================================================================================== // FUNCTION: ReadOldSynchArray // PURPOSE: Reads a synch array from an old (pre ABF) data file and stores it away in the synch // buffer. Copes with the complexities of old synch arrays (non-trivial). // static BOOL ReadOldSynchArray(CFileDescriptor *pFI, ABFFileHeader *pFH, DWORD *pdwMaxEpi, int *pnError) { // WPTRASSERT(pFI); // ABFH_WASSERT(pFH); // WPTRASSERT(pdwMaxEpi); if ((pFH->lSynchArraySize <= 0) || (pFH->lSynchArrayPtr <= 0)) { if (pFH->nOperationMode != ABF_WAVEFORMFILE) return ErrorReturn(pnError, ABF_ENOSYNCHPRESENT); *pdwMaxEpi = UINT(pFH->lActualAcqLength / pFH->lNumSamplesPerEpisode); return TRUE; } // Get the length of the file. ABFLONG lFileLength = ABFLONG(pFI->GetFileSize()); ASSERT(lFileLength > 0); // Old Csynch arrays must be converted to the new style Synch array. // dwMaxEpi may be reduced as deleated and empty episodes are stripped out. // This conversion process also fills in file offset entries for each episode. // Allocate a temporary buffer and read the Synch array into it. // Old synch arrays are guaranteed to be less than 64k, so one read will do it. UINT uSize = (UINT)pFH->lSynchArraySize * 2; // two short entries per episode CArrayPtr pnOldSynch(uSize); if (pnOldSynch == NULL) return ErrorReturn(pnError, ABF_OUTOFMEMORY); // Seek to the start of the synch block. // VERIFY(pFI->Seek( LONGLONG(pFH->lSynchArrayPtr) * ABF_BLOCKSIZE, FILE_BEGIN)); // Read the Synch array into the buffer if (!pFI->Read(pnOldSynch, uSize*sizeof(short))) return ErrorReturn(pnError, ABF_EREADSYNCH); // Convert old Synch array to new Synch array, checking for edited // (missing) episodes in older file versions. UINT uMissing = 0; ABFLONG lStart = 0L; short *pn = pnOldSynch; for (ABFLONG lSrc=0; lSrc < pFH->lSynchArraySize; lSrc++) { int nCount = *pn++; int nLength = *pn++; ABFLONG lFileOffset = pFH->lNumSamplesPerEpisode * sizeof(short) * lSrc; if (nLength < 0) { // Zero length acquisition found (i.e. an episode with invalid // data) increment Missing% count, but not // destination index to effectively edit it out of the file for // analysis. // Negative Synch entry means that an episode was deleated. // Destination index is not incremented, and Missing% count is // updated. uMissing++; } else { ABFLONG lLength, lSkip; if (nCount == 0) { // Adjust the offset for incomplete episodes. lFileOffset += pFH->lNumSamplesPerEpisode * sizeof(short) - nLength; lSkip = 0; lLength = nLength / sizeof(short); // convert bytes to samples } else { // If count is != 0 a full episode was acquired, with possibly missing data before it started. lLength = pFH->lNumSamplesPerEpisode; lSkip = pFH->lNumSamplesPerEpisode * ABFLONG(nCount-1) + ABFLONG(nLength / sizeof(short)); // Old fetchan source code disregards MissingSamples if they are less than zero. if (lSkip < 0) lSkip = 0; } lStart += lSkip; // Check that episode is within the physical file. if (lFileOffset+lLength*ABFLONG(sizeof(short)) > lFileLength-1024) return ErrorReturn(pnError, ABF_EBADSYNCH); pFI->PutSynchEntry(lStart, lLength, lFileOffset); lStart += lLength; } } pFH->lSynchArraySize -= uMissing; *pdwMaxEpi = UINT(pFH->lSynchArraySize); pFI->SetSynchMode( CSynch::eREADMODE ); return TRUE; } //=============================================================================================== // FUNCTION: GetSynchEntry // PURPOSE: Gets a synch entry describing the requested episode (if possible). // RETURNS: TRUE = OK, FALSE = Episode number out of range. // NOTES: Episode number is one-relative! // static BOOL GetSynchEntry( const ABFFileHeader *pFH, CFileDescriptor *pFI, UINT uEpisode, Synch *pSynchEntry ) { if (!pFI->CheckEpisodeNumber(uEpisode)) return FALSE; // If a synch array is not present, create a synch entry for this chunk, // otherwise, read it from the synch array. if (pFI->GetSynchCount() == 0) { UINT uSampleSize = SampleSize(pFH); UINT uChunkSize = UINT(pFH->lNumSamplesPerEpisode); // Chunk size in samples // In continuous files, the last episode may be smaller than the episode size used // for the rest of the file. This is calculated in the ABF.Open routine. if ((pFH->nOperationMode == ABF_GAPFREEFILE) && (uEpisode == pFI->GetAcquiredEpisodes())) pSynchEntry->dwLength = pFI->GetLastEpiSize(); else pSynchEntry->dwLength = uChunkSize; pSynchEntry->dwFileOffset = uChunkSize * uSampleSize * (uEpisode - 1); pSynchEntry->dwStart = pSynchEntry->dwFileOffset / uSampleSize; return TRUE; } return pFI->GetSynchEntry( uEpisode, pSynchEntry ); } //=============================================================================================== // FUNCTION: GetSynchEntry // PURPOSE: Gets a synch entry describing the requested episode (if possible). // RETURNS: TRUE = OK, FALSE = Episode number out of range. // NOTES: Episode number is one-relative! // static BOOL ABF2_GetSynchEntry( const ABF2FileHeader *pFH, CFileDescriptor *pFI, UINT uEpisode, Synch *pSynchEntry ) { if (!pFI->CheckEpisodeNumber(uEpisode)) return FALSE; // If a synch array is not present, create a synch entry for this chunk, // otherwise, read it from the synch array. if (pFI->GetSynchCount() == 0) { UINT uSampleSize = ABF2_SampleSize(pFH); UINT uChunkSize = UINT(pFH->lNumSamplesPerEpisode); // Chunk size in samples // In continuous files, the last episode may be smaller than the episode size used // for the rest of the file. This is calculated in the ABF.Open routine. if ((pFH->nOperationMode == ABF_GAPFREEFILE) && (uEpisode == pFI->GetAcquiredEpisodes())) pSynchEntry->dwLength = pFI->GetLastEpiSize(); else pSynchEntry->dwLength = uChunkSize; pSynchEntry->dwFileOffset = uChunkSize * uSampleSize * (uEpisode - 1); pSynchEntry->dwStart = pSynchEntry->dwFileOffset / uSampleSize; return TRUE; } return pFI->GetSynchEntry( uEpisode, pSynchEntry ); } //=============================================================================================== // FUNCTION: ABF_MultiplexRead // PURPOSE: This routine reads an episode of data from the data file previously opened. // // INPUT: // nFile the file index into the g_FileData structure array // dwEpisode the episode number to be read. Episodes start at 1 // // OUTPUT: // pvBuffer the data buffer for the data // puSizeInSamples the number of valid points in the data buffer // BOOL WINAPI ABF_MultiplexRead(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, void *pvBuffer, UINT uBufferSize, UINT *puSizeInSamples, int *pnError) { // ABFH_ASSERT(pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // Set the sample size in the data. UINT uSampleSize = SampleSize(pFH); // UINT uBytesPerEpisode = UINT(pFH->lNumSamplesPerEpisode) * uSampleSize; // If a synch array is not present, create a synch entry for this chunk, // otherwise, read it from the synch array. Synch SynchEntry; if (!GetSynchEntry( pFH, pFI, dwEpisode, &SynchEntry )) return ErrorReturn(pnError, ABF_EEPISODERANGE); // return the size of the episode to be read. if (puSizeInSamples) *puSizeInSamples = UINT(SynchEntry.dwLength); // Add the distance to the start of the data to the data offset LONGLONG lFileOffset = LONGLONG(GetDataOffset(pFH)) + SynchEntry.dwFileOffset; // Seek to the calculated file position. VERIFY(pFI->Seek(lFileOffset, FILE_BEGIN)); UINT uSizeInBytes = SynchEntry.dwLength * uSampleSize; // ARRAYASSERT((BYTE *)pvBuffer, uSizeInBytes); // Do the file read if (!pFI->Read(pvBuffer, uSizeInBytes)) return ErrorReturn(pnError, ABF_EREADDATA); // If episode is not full, pad it out with 0's // Make sure that it is zero-padded to avoid this adventurous memset #if 0 if (uSizeInBytes < uBufferSize * uSampleSize) memset((char *)pvBuffer + uSizeInBytes, '\0', uBufferSize*uSampleSize - uSizeInBytes); #endif return TRUE; } //=============================================================================================== // FUNCTION: ABF_MultiplexRead // PURPOSE: This routine reads an episode of data from the data file previously opened. // // INPUT: // nFile the file index into the g_FileData structure array // dwEpisode the episode number to be read. Episodes start at 1 // // OUTPUT: // pvBuffer the data buffer for the data // puSizeInSamples the number of valid points in the data buffer // BOOL WINAPI ABF2_MultiplexRead(int nFile, const ABF2FileHeader *pFH, DWORD dwEpisode, void *pvBuffer, UINT uBufferSize, UINT *puSizeInSamples, int *pnError) { // ABFH_ASSERT(pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // Set the sample size in the data. UINT uSampleSize = ABF2_SampleSize(pFH); // UINT uBytesPerEpisode = UINT(pFH->lNumSamplesPerEpisode) * uSampleSize; // If a synch array is not present, create a synch entry for this chunk, // otherwise, read it from the synch array. Synch SynchEntry; if (!ABF2_GetSynchEntry( pFH, pFI, dwEpisode, &SynchEntry )) return ErrorReturn(pnError, ABF_EEPISODERANGE); // return the size of the episode to be read. if (puSizeInSamples) *puSizeInSamples = UINT(SynchEntry.dwLength); // Add the distance to the start of the data to the data offset LONGLONG lFileOffset = LONGLONG(ABF2_GetDataOffset(pFH)) + SynchEntry.dwFileOffset; // Seek to the calculated file position. VERIFY(pFI->Seek(lFileOffset, FILE_BEGIN)); UINT uSizeInBytes = SynchEntry.dwLength * uSampleSize; // ARRAYASSERT((BYTE *)pvBuffer, uSizeInBytes); // Do the file read if (!pFI->Read(pvBuffer, uSizeInBytes)) return ErrorReturn(pnError, ABF_EREADDATA); // If episode is not full, pad it out with 0's // Make sure that it is zero-padded to avoid this adventurous memset #if 0 if (uSizeInBytes < uBufferSize * uSampleSize) memset((char *)pvBuffer + uSizeInBytes, '\0', uBufferSize*uSampleSize - uSizeInBytes); #endif return TRUE; } #if 0 //=============================================================================================== // FUNCTION: SynchCountToSamples // PURPOSE: Rounds a synch count to the nearest sample count. // inline UINT SynchCountToSamples(const ABFFileHeader *pFH, UINT uSynchStart) { double dMS = 0.0; ABFH_SynchCountToMS(pFH, uSynchStart, &dMS); double dSampleInterval = ABFH_GetFirstSampleInterval(pFH); return UINT(dMS/dSampleInterval*1E3 + 0.5); } //=============================================================================================== // FUNCTION: ABF_MultiplexWrite // PURPOSE: This routine writes an episode of data from the end of the data file // previously opened with a ABF_WriteOpen call. Episodes may only be written // sequentially. // INPUT: // nFile the file index into the g_FileData structure array // uFlags flags governing the write process // uSizeInSamples the number of valid points in the data buffer // dwEpiStart the start time (in synch time units) of this episode // pvBuffer the data buffer for the data // BOOL WINAPI ABF_MultiplexWrite(int nFile, ABFFileHeader *pFH, UINT uFlags, const void *pvBuffer, DWORD dwEpiStart, UINT uSizeInSamples, int *pnError) { ABFH_WASSERT(pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag(FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); // Check parameters in a debug build. #ifdef _DEBUG if ((pFH->nOperationMode==ABF_WAVEFORMFILE) || (pFH->nOperationMode==ABF_HIGHSPEEDOSC) || (pFH->nOperationMode==ABF_FIXLENEVENTS)) { ASSERT(pFH->lNumSamplesPerEpisode==long(uSizeInSamples)); ASSERT((uFlags & ABF_APPEND) == 0); } #endif // Set the sample size in the data. UINT uSampleSize = SampleSize(pFH); UINT uSizeInBytes = uSizeInSamples * uSampleSize; ARRAYASSERT((short *)pvBuffer, uSizeInBytes/2); // Seek to the end of the file. VERIFY(pFI->Seek( 0L, FILE_END)); if (!pFI->Write(pvBuffer, uSizeInBytes)) return ErrorReturn(pnError, ABF_EDISKFULL); UINT uAcquiredEpisodes = pFI->GetAcquiredEpisodes(); UINT uAcquiredSamples = pFI->GetAcquiredSamples(); UINT uSynchCount = pFI->GetSynchCount(); // Clear the append flag if there is nothing to append to. if (uSynchCount == 0) uFlags &= ~ABF_APPEND; switch (pFH->nOperationMode) { case ABF_GAPFREEFILE: { UINT uEpiStartInSamples = SynchCountToSamples(pFH, dwEpiStart); // If there is a synch array already... if (uSynchCount != 0) { UINT uStartOfLast = SynchCountToSamples(pFH, pFI->EpisodeStart( uAcquiredEpisodes )); UINT uEndOfLast = uStartOfLast + pFI->EpisodeLength( uAcquiredEpisodes ); if (uEpiStartInSamples <= uEndOfLast) // If we are just appending onto the previous event... uFlags |= ABF_APPEND; // FALL THROUGH TO DEFAULT CASE FOR SYNCH ARRAY PROCESSING!!! } else // No synch array as yet - either append or add one. { // if the first block is being extended - no synch array required. if (uEpiStartInSamples <= uAcquiredSamples) { pFI->SetAcquiredEpisodes( 1 ); break; } // If some data has been acquired but no synch entries added... if (uAcquiredSamples > 0) { // Add in the first synch entry for data already written pFI->PutSynchEntry(0, uAcquiredSamples, 0); pFI->SetAcquiredEpisodes( 1 ); } // FALL THROUGH TO DEFAULT CASE FOR SYNCH ARRAY PROCESSING!!! } } default: if (uFlags & ABF_APPEND) pFI->IncreaseEventLength( uSizeInSamples ); else { pFI->PutSynchEntry(dwEpiStart, uSizeInSamples, uAcquiredSamples * uSampleSize); pFI->SetAcquiredEpisodes(++uAcquiredEpisodes); } break; } uAcquiredSamples += uSizeInSamples; pFI->SetAcquiredSamples(uAcquiredSamples); pFH->lActualAcqLength = (ABFLONG)uAcquiredSamples; pFH->lActualEpisodes = (ABFLONG)pFI->GetAcquiredEpisodes(); return TRUE; } //=============================================================================================== // FUNCTION: ABF_SetEpisodeStart // PURPOSE: Sets the start time of a given sweep in synch time units. // INPUT: // nFile the file index into the g_FileData structure array // uEpisode the (one based) episode number. // uEpiStart the start time (in synch time units) of this episode // BOOL WINAPI ABF_SetEpisodeStart(int nFile, UINT uEpisode, UINT uEpiStart, int *pnError) { CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag(FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); UINT uSynchCount = pFI->GetSynchCount(); if (uEpisode > uSynchCount) return ErrorReturn(pnError, ABF_EEPISODERANGE); pFI->SetEpisodeStart(uEpisode, uEpiStart); return TRUE; } //=============================================================================================== // FUNCTION: ABF_WriteRawData // PURPOSE: This routine writes a raw buffer of binary data to the current position of an // ABF file previously opened with a ABF_WriteOpen call. This routine is provided // for acquisition programs that buffer up episodic data and then write it out in // large chunks. This provides an alternative to retrieving the low-level file handle // and acting on it, as this can be non-portable, and assumptions would have to be // made regarding the type of file handle returned (DOS or C runtime). // INPUT: // nFile the file index into the g_FileData structure array // pvBuffer the data buffer for the data // dwSizeInBytes the number of bytes of data to write // BOOL WINAPI ABF_WriteRawData(int nFile, const void *pvBuffer, DWORD dwSizeInBytes, int *pnError) { CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; #ifdef _DEBUG // Return an error if writing is inappropriate. if (pFI->TestFlag( FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); #endif ARRAYASSERT((short *)pvBuffer, UINT(dwSizeInBytes/2)); if (!pFI->Write(pvBuffer, dwSizeInBytes)) return ErrorReturn(pnError, ABF_EDISKFULL); return TRUE; } #endif //=============================================================================================== // FUNCTION: PackSamples // PURPOSE: Packs the samples from the source array into the destination array, // assuming the given skip factor // INPUT: // pvSource the pointer to the source of data. // pvDestination the pointer to the destination of data. // uSourceLen the length of the data to be packed // uFirstSample the starting index of the first element // uSkip the skip factor for the packing // static void PackSamples(void *pvSource, void *pvDestination, UINT uSourceLen, UINT uFirstSample, UINT uSampleSize, UINT uSkip) { ASSERT(uSkip > 0); // ARRAYASSERT((BYTE *)pvSource, uSourceLen * uSampleSize); // ARRAYASSERT((BYTE *)pvDestination, (uSourceLen / uSkip) * uSampleSize); if (uSampleSize == sizeof(short)) { // adjust the starting offset short *piSource = (short *)pvSource; short *piDestination = (short *)pvDestination; for (UINT i=uFirstSample; ilNumSamplesPerEpisode/pFH->nADCNumChannels)); ARRAYASSERT(pnSource, (UINT)(pFH->lNumSamplesPerEpisode)); UINT uSkip = (UINT)pFH->nADCNumChannels; UINT uSourceLen = (UINT)pFH->lNumSamplesPerEpisode; float fValToUUFactor, fValToUUShift; ABFH_GetADCtoUUFactors( pFH, nChannel, &fValToUUFactor, &fValToUUShift); for (UINT i=uChannelOffset; ilNumSamplesPerEpisode/pFH->nADCNumChannels)); // ARRAYASSERT(pnSource, (UINT)(pFH->lNumSamplesPerEpisode)); UINT uSkip = (UINT)pFH->nADCNumChannels; UINT uSourceLen = (UINT)pFH->lNumSamplesPerEpisode; float fValToUUFactor, fValToUUShift; ABF2H_GetADCtoUUFactors( pFH, nChannel, &fValToUUFactor, &fValToUUShift); for (UINT i=uChannelOffset; i=0; i--) pfDestination[i] = pnSource[i] * fValToUUFactor + fValToUUShift; } //=============================================================================================== // FUNCTION: ConvertInPlace // PURPOSE: Convert a single channel of two byte integers to floats, in-place. // static void ABF2_ConvertInPlace(const ABF2FileHeader *pFH, int nChannel, UINT uNumSamples, void *pvBuffer) { // ABFH_ASSERT(pFH); // ARRAYASSERT((float *)pvBuffer, uNumSamples); ADC_VALUE *pnSource = ((ADC_VALUE *)pvBuffer); float *pfDestination = ((float *)pvBuffer); float fValToUUFactor, fValToUUShift; ABF2H_GetADCtoUUFactors( pFH, nChannel, &fValToUUFactor, &fValToUUShift); for (int i=uNumSamples-1; i>=0; i--) pfDestination[i] = pnSource[i] * fValToUUFactor + fValToUUShift; } //=============================================================================================== // FUNCTION: ConvertADCToResults // PURPOSE: Get the results array for the math channel. // static BOOL ConvertADCToResults(const ABFFileHeader *pFH, float *pfDestination, UINT uDestArrayLen, short *pnSource) { // ABFH_ASSERT(pFH); // ARRAYASSERT(pfDestination, (UINT)(pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels)); ARRAYASSERT(pnSource, (UINT)(pFH->lNumSamplesPerEpisode)); UINT uAOffset, uBOffset; short *pnSourceA, *pnSourceB; int nChannelA = pFH->nArithmeticADCNumA; int nChannelB = pFH->nArithmeticADCNumB; UINT i, uSkip = pFH->nADCNumChannels; UINT uSourceArrayLen = (UINT)pFH->lNumSamplesPerEpisode; float fValToUUFactorA, fValToUUShiftA; float fValToUUFactorB, fValToUUShiftB; float fUserUnitA, fUserUnitB; if (!ABFH_GetChannelOffset(pFH, nChannelA, &uAOffset)) return FALSE; if (!ABFH_GetChannelOffset(pFH, nChannelB, &uBOffset)) return FALSE; ABFH_GetADCtoUUFactors( pFH, nChannelA, &fValToUUFactorA, &fValToUUShiftA); ABFH_GetADCtoUUFactors( pFH, nChannelB, &fValToUUFactorB, &fValToUUShiftB); pnSourceA = pnSource + uAOffset; // adjust the starting offset pnSourceB = pnSource + uBOffset; // adjust the starting offset uSourceArrayLen -= max(uAOffset, uBOffset); for (i=0; ilNumSamplesPerEpisode/pFH->nADCNumChannels)); ARRAYASSERT(pnSource, (UINT)(pFH->lNumSamplesPerEpisode)); UINT uAOffset, uBOffset; short *pnSourceA, *pnSourceB; int nChannelA = pFH->nArithmeticADCNumA; int nChannelB = pFH->nArithmeticADCNumB; UINT i, uSkip = pFH->nADCNumChannels; UINT uSourceArrayLen = (UINT)pFH->lNumSamplesPerEpisode; float fValToUUFactorA, fValToUUShiftA; float fValToUUFactorB, fValToUUShiftB; float fUserUnitA, fUserUnitB; if (!ABF2H_GetChannelOffset(pFH, nChannelA, &uAOffset)) return FALSE; if (!ABF2H_GetChannelOffset(pFH, nChannelB, &uBOffset)) return FALSE; ABF2H_GetADCtoUUFactors( pFH, nChannelA, &fValToUUFactorA, &fValToUUShiftA); ABF2H_GetADCtoUUFactors( pFH, nChannelB, &fValToUUFactorB, &fValToUUShiftB); pnSourceA = pnSource + uAOffset; // adjust the starting offset pnSourceB = pnSource + uBOffset; // adjust the starting offset uSourceArrayLen -= max(uAOffset, uBOffset); for (i=0; ilNumSamplesPerEpisode/pFH->nADCNumChannels); ARRAYASSERT(pfSource, pFH->lNumSamplesPerEpisode); int nChannelA = pFH->nArithmeticADCNumA; int nChannelB = pFH->nArithmeticADCNumB; UINT uSkip = pFH->nADCNumChannels; UINT uSourceArrayLen = (UINT)pFH->lNumSamplesPerEpisode; UINT uAOffset, uBOffset; if (!ABFH_GetChannelOffset(pFH, nChannelA, &uAOffset)) return FALSE; if (!ABFH_GetChannelOffset(pFH, nChannelB, &uBOffset)) return FALSE; float *pfSourceA = pfSource + uAOffset; // adjust the starting offset float *pfSourceB = pfSource + uBOffset; // adjust the starting offset uSourceArrayLen -= max(uAOffset, uBOffset); for (UINT i=0; ilNumSamplesPerEpisode/pFH->nADCNumChannels); ARRAYASSERT(pfSource, pFH->lNumSamplesPerEpisode); int nChannelA = pFH->nArithmeticADCNumA; int nChannelB = pFH->nArithmeticADCNumB; UINT uSkip = pFH->nADCNumChannels; UINT uSourceArrayLen = (UINT)pFH->lNumSamplesPerEpisode; UINT uAOffset, uBOffset; if (!ABF2H_GetChannelOffset(pFH, nChannelA, &uAOffset)) return FALSE; if (!ABF2H_GetChannelOffset(pFH, nChannelB, &uBOffset)) return FALSE; float *pfSourceA = pfSource + uAOffset; // adjust the starting offset float *pfSourceB = pfSource + uBOffset; // adjust the starting offset uSourceArrayLen -= max(uAOffset, uBOffset); for (UINT i=0; i pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels (floats) // BOOL WINAPI ABF_ReadChannel(int nFile, const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, Vector_float& pfBuffer, UINT *puNumSamples, int *pnError) { #if defined(_WINDOWS) && !defined(__MINGW32__) // ABFH_ASSERT(pFH); // ARRAYASSERT(&pfBuffer[0], (UINT)(pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels)); #endif CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // Get the offset into the multiplexed data array for the first point UINT uChannelOffset; if (!ABFH_GetChannelOffset(pFH, nChannel, &uChannelOffset)) return ErrorReturn(pnError, ABF_EINVALIDCHANNEL); // If there is only one channel, read the data directly into the passed buffer, // converting it in-place if required. if ((pFH->nADCNumChannels == 1) && (nChannel >= 0)) { if (!ABF_MultiplexRead(nFile, pFH, dwEpisode, &pfBuffer[0], (UINT)pfBuffer.size(), puNumSamples, pnError)) return FALSE; if (pFH->nDataFormat == ABF_INTEGERDATA) // if data is 2byte ints, convert to floats ConvertInPlace(pFH, nChannel, *puNumSamples, &pfBuffer[0]); return TRUE; } // Set the sample size in the data. UINT uSampleSize = SampleSize(pFH); // Only create the read buffer on demand, it is freed when the file is closed. if (!pFI->GetReadBuffer()) { if (!pFI->AllocReadBuffer(pFH->lNumSamplesPerEpisode * uSampleSize)) return ErrorReturn(pnError, ABF_OUTOFMEMORY); } // Read the whole episode from the ABF file only if it is not already cached. UINT uEpisodeSize = pFI->GetCachedEpisodeSize(); if (dwEpisode != pFI->GetCachedEpisode()) { uEpisodeSize = (UINT)pFH->lNumSamplesPerEpisode; if (!ABF_MultiplexRead(nFile, pFH, dwEpisode, pFI->GetReadBuffer(), pFH->lNumSamplesPerEpisode * uSampleSize, &uEpisodeSize, pnError)) { pFI->SetCachedEpisode(UINT(-1), 0); return FALSE; } pFI->SetCachedEpisode(dwEpisode, uEpisodeSize); } // if data is 2byte ints, convert to floats if (pFH->nDataFormat == ABF_INTEGERDATA) { // Cast the read buffer to the appropriate format. ADC_VALUE *pnReadBuffer = (ADC_VALUE *)pFI->GetReadBuffer(); // A channel number of -1 refers to the results channel if (nChannel >= 0) ConvertADCToFloats(pFH, nChannel, uChannelOffset, &pfBuffer[0], (UINT)pfBuffer.size(), pnReadBuffer); else if (!ConvertADCToResults(pFH, &pfBuffer[0], (UINT)pfBuffer.size(), pnReadBuffer)) return ErrorReturn(pnError, ABF_BADMATHCHANNEL); } else // Data is 4-byte floats. { // Cast the read buffer to the appropriate format. float *pfReadBuffer = (float *)pFI->GetReadBuffer(); // A channel number of -1 refers to the results channel if (nChannel >= 0) PackSamples(pfReadBuffer, &pfBuffer[0], uEpisodeSize, uChannelOffset, uSampleSize, pFH->nADCNumChannels); else if (!ConvertToResults(pFH, &pfBuffer[0], (UINT)pfBuffer.size(), pfReadBuffer)) return ErrorReturn(pnError, ABF_BADMATHCHANNEL); } // Return the length of the data block. if (puNumSamples) *puNumSamples = uEpisodeSize / pFH->nADCNumChannels; return TRUE; } //=============================================================================================== // FUNCTION: ABF_ReadChannel // PURPOSE: This function reads a complete multiplexed episode from the data file and // then converts a single de-multiplexed channel to "UserUnits" in pfBuffer. // // The required size of the passed buffer is: // pfBuffer -> pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels (floats) // BOOL WINAPI ABF2_ReadChannel(int nFile, const ABF2FileHeader *pFH, int nChannel, DWORD dwEpisode, Vector_float& pfBuffer, UINT *puNumSamples, int *pnError) { // ABFH_ASSERT(pFH); // ARRAYASSERT(pfBuffer, (UINT)(pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels)); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // Get the offset into the multiplexed data array for the first point UINT uChannelOffset; if (!ABF2H_GetChannelOffset(pFH, nChannel, &uChannelOffset)) return ErrorReturn(pnError, ABF_EINVALIDCHANNEL); // If there is only one channel, read the data directly into the passed buffer, // converting it in-place if required. if ((pFH->nADCNumChannels == 1) && (nChannel >= 0)) { if (!ABF2_MultiplexRead(nFile, pFH, dwEpisode, &pfBuffer[0], (UINT)pfBuffer.size(), puNumSamples, pnError)) return FALSE; if (pFH->nDataFormat == ABF_INTEGERDATA) // if data is 2byte ints, convert to floats ABF2_ConvertInPlace(pFH, nChannel, *puNumSamples, &pfBuffer[0]); return TRUE; } // Set the sample size in the data. UINT uSampleSize = ABF2_SampleSize(pFH); // Only create the read buffer on demand, it is freed when the file is closed. if (!pFI->GetReadBuffer()) { if (!pFI->AllocReadBuffer(pFH->lNumSamplesPerEpisode * uSampleSize)) return ErrorReturn(pnError, ABF_OUTOFMEMORY); } // Read the whole episode from the ABF file only if it is not already cached. UINT uEpisodeSize = pFI->GetCachedEpisodeSize(); if (dwEpisode != pFI->GetCachedEpisode()) { uEpisodeSize = (UINT)pFH->lNumSamplesPerEpisode; if (!ABF2_MultiplexRead(nFile, pFH, dwEpisode, pFI->GetReadBuffer(), pFH->lNumSamplesPerEpisode * uSampleSize, &uEpisodeSize, pnError)) { pFI->SetCachedEpisode(UINT(-1), 0); return FALSE; } pFI->SetCachedEpisode(dwEpisode, uEpisodeSize); } // if data is 2byte ints, convert to floats if (pFH->nDataFormat == ABF_INTEGERDATA) { // Cast the read buffer to the appropriate format. ADC_VALUE *pnReadBuffer = (ADC_VALUE *)pFI->GetReadBuffer(); // A channel number of -1 refers to the results channel if (nChannel >= 0) ABF2_ConvertADCToFloats(pFH, nChannel, uChannelOffset, &pfBuffer[0], (UINT)pfBuffer.size(), pnReadBuffer); else if (!ABF2_ConvertADCToResults(pFH, &pfBuffer[0], (UINT)pfBuffer.size(), pnReadBuffer)) return ErrorReturn(pnError, ABF_BADMATHCHANNEL); } else // Data is 4-byte floats. { // Cast the read buffer to the appropriate format. float *pfReadBuffer = (float *)pFI->GetReadBuffer(); // A channel number of -1 refers to the results channel if (nChannel >= 0) PackSamples(pfReadBuffer, &pfBuffer[0], uEpisodeSize, uChannelOffset, uSampleSize, pFH->nADCNumChannels); else if (!ABF2_ConvertToResults(pFH, &pfBuffer[0], (UINT)pfBuffer.size(), pfReadBuffer)) return ErrorReturn(pnError, ABF_BADMATHCHANNEL); } // Return the length of the data block. if (puNumSamples) *puNumSamples = uEpisodeSize / pFH->nADCNumChannels; return TRUE; } #if 0 //=============================================================================================== // FUNCTION: ABF_ReadRawChannel // PURPOSE: This function reads a complete multiplexed episode from the data file and // then decimates it, returning single de-multiplexed channel in the raw data format. // // The required size of the passed buffer is: // pfBuffer -> pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels (floats) // BOOL WINAPI ABF_ReadRawChannel(int nFile, const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, void *pvBuffer, UINT *puNumSamples, int *pnError) { ABFH_ASSERT(pFH); // Set the sample size in the data. UINT uSampleSize = SampleSize(pFH); ARRAYASSERT((short *)pvBuffer, pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels*uSampleSize/2); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // Get the offset into the multiplexed data array for the first point UINT uChannelOffset; if (!ABFH_GetChannelOffset(pFH, nChannel, &uChannelOffset) || (nChannel < 0)) return ErrorReturn(pnError, ABF_EINVALIDCHANNEL); // If there is only one channel, read the data directly into the passed buffer, if (pFH->nADCNumChannels == 1) return ABF_MultiplexRead(nFile, pFH, dwEpisode, pvBuffer, puNumSamples, pnError); // Only create the read buffer on demand, it is freed when the file is closed. if (!pFI->GetReadBuffer()) { if (!pFI->AllocReadBuffer(pFH->lNumSamplesPerEpisode * uSampleSize)) return ErrorReturn(pnError, ABF_OUTOFMEMORY); } // Read the whole episode from the ABF file only if it is not already cached. UINT uEpisodeSize = pFI->GetCachedEpisodeSize(); if (dwEpisode != pFI->GetCachedEpisode()) { uEpisodeSize = (UINT)pFH->lNumSamplesPerEpisode; if (!ABF_MultiplexRead(nFile, pFH, dwEpisode, pFI->GetReadBuffer(), &uEpisodeSize, pnError)) { pFI->SetCachedEpisode(UINT(-1), 0); return FALSE; } pFI->SetCachedEpisode(dwEpisode, uEpisodeSize); } PackSamples(pFI->GetReadBuffer(), pvBuffer, uEpisodeSize, uChannelOffset, uSampleSize, pFH->nADCNumChannels); // Return the length of the data block. if (puNumSamples) *puNumSamples = uEpisodeSize / pFH->nADCNumChannels; return TRUE; } //=============================================================================================== // FUNCTION: ABF_ReadDACFileEpi // PURPOSE: This function reads an episode from the DACFile section. Users will normally // retrieve DAC file information transparently through the Get Waveform call. // BOOL WINAPI ABF_ReadDACFileEpi(int nFile, const ABFFileHeader *pFH, short *pnDACArray, DWORD dwEpisode, int *pnError) { return ABF_ReadDACFileEpiEx(nFile, pFH, pnDACArray, pFH->nActiveDACChannel, dwEpisode, pnError); } BOOL WINAPI ABF_ReadDACFileEpiEx(int nFile, const ABFFileHeader *pFH, short *pnDACArray, UINT nChannel, DWORD dwEpisode, int *pnError) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); #if USE_DACFILE_FIX // PRC DEBUG // UINT uNumSamples = NewFH.lNumSamplesPerEpisode / NewFH.nADCNumChannels; UINT uNumSamples = NewFH.lNumSamplesPerEpisode; #else UINT uNumSamples = NewFH.lNumSamplesPerEpisode / NewFH.nADCNumChannels; #endif ARRAYASSERT( pnDACArray, uNumSamples ); ASSERT( nChannel < ABF_WAVEFORMCOUNT ); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // If the requested episode is after the last one, then use the last one in the file. if( NewFH.lDACFileNumEpisodes[nChannel] < (ABFLONG)dwEpisode ) dwEpisode = (DWORD) NewFH.lDACFileNumEpisodes[nChannel]; if (NewFH.lDACFilePtr[nChannel]==0) { if (!pFI->GetDACFileSweep(nChannel, dwEpisode-1, pnDACArray, uNumSamples)) return ErrorReturn(pnError, ABF_EREADDACEPISODE); } else { UINT uOffset = NewFH.lDACFilePtr[nChannel] * ABF_BLOCKSIZE + (dwEpisode-1) * uNumSamples * sizeof(short); VERIFY(pFI->Seek( uOffset, FILE_BEGIN)); // Read the DACFile episode into the passed buffer UINT uBytesToRead = uNumSamples * sizeof(short); if (!pFI->Read(pnDACArray, uBytesToRead)) return ErrorReturn(pnError, ABF_EREADDACEPISODE); #if USE_DACFILE_FIX // PRC DEBUG // Tempory hack to decimate by number of channels. int nNumChans = NewFH.nADCNumChannels; if( nNumChans > 1 ) { for( UINT i=0; inActiveDACChannel, pnDACArray, pnError); } BOOL WINAPI ABF_WriteDACFileEpiEx(int nFile, ABFFileHeader *pFH, UINT uDACChannel, const short *pnDACArray, int *pnError) { ABFH_WASSERT(pFH); ASSERT( uDACChannel < ABF_WAVEFORMCOUNT ); // Coerce to safe value. if( uDACChannel >= ABF_WAVEFORMCOUNT ) { TRACE1( "ABF_WriteDACFileEpi: uDACChannel changed from %d to 0.\n", uDACChannel ); uDACChannel = 0; } ARRAYASSERT(pnDACArray, (UINT)(pFH->lNumSamplesPerEpisode)); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag( FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); // Take a copy of the passed in header to ensure it is 5k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); if (!pFI->PutDACFileSweep( uDACChannel, NewFH.lDACFileNumEpisodes[uDACChannel], pnDACArray, NewFH.lNumSamplesPerEpisode )) return ErrorReturn(pnError, ABF_EDISKFULL); NewFH.lDACFileNumEpisodes[uDACChannel]++; // Copy the original parameters back into the old header. ABFH_DemoteHeader( pFH, &NewFH ); return TRUE; } #if USE_DACFILE_FIX // PRC DEBUG static int s_nFudgeChannels = -1; #endif //=============================================================================================== // FUNCTION: ScaleDACBuffer // PURPOSE: Fill the float buffer with DAC UU values that correspond to a particular // multiplex offset. // static void ScaleDACBuffer(const ABFFileHeader *pFH, UINT uDACChannel, UINT uADCChannelOffset, short *pnReadBuffer, float *pfBuffer) { ABFH_ASSERT(pFH); ASSERT( uDACChannel < ABF_WAVEFORMCOUNT ); // Coerce to safe value. if( uDACChannel >= ABF_WAVEFORMCOUNT ) { TRACE1( "ScaleDACBuffer: uDACChannel changed from %d to 0.\n", uDACChannel ); uDACChannel = 0; } UINT uNumSamples = (UINT)pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels; #if USE_DACFILE_FIX // PRC DEBUG ARRAYASSERT(pnReadBuffer, pFH->lNumSamplesPerEpisode ); #else ARRAYASSERT(pnReadBuffer, uNumSamples); #endif ARRAYASSERT(pfBuffer, uNumSamples); float fDACToUUFactor, fDACToUUShift; ABFH_GetDACtoUUFactors( pFH, uDACChannel, &fDACToUUFactor, &fDACToUUShift ); #if USE_DACFILE_FIX UINT uNumDACFileChannels = pFH->nADCNumChannels + s_nFudgeChannels; for (UINT i=uADCChannelOffset; inActiveDACChannel, dwEpisode, pfBuffer, pnError); } BOOL WINAPI ABF_GetWaveformEx(int nFile, const ABFFileHeader *pFH, UINT uDACChannel, DWORD dwEpisode, float *pfBuffer, int *pnError) { ABFH_ASSERT(pFH); ARRAYASSERT(pfBuffer, (UINT)(pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels)); if( pFH->nOperationMode != ABF_WAVEFORMFILE ) return ErrorReturn(pnError, ABF_ENOWAVEFORM); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); if( (NewFH.nWaveformEnable[uDACChannel] == FALSE) || (NewFH.nWaveformSource[uDACChannel] == ABF_WAVEFORMDISABLED)) return ErrorReturn(pnError, ABF_ENOWAVEFORM); if (NewFH.nWaveformSource[uDACChannel] == ABF_EPOCHTABLEWAVEFORM) { if (!ABFH_GetWaveformEx( &NewFH, uDACChannel, dwEpisode, pfBuffer, NULL)) return ErrorReturn(pnError, ABF_EBADWAVEFORM); return TRUE; } ASSERT(NewFH.nWaveformSource[uDACChannel] == ABF_DACFILEWAVEFORM); #if USE_DACFILE_FIX // PRC DEBUG CArrayPtr pnWorkBuffer(NewFH.lNumSamplesPerEpisode); #else CArrayPtr pnWorkBuffer(NewFH.lNumSamplesPerEpisode / NewFH.nADCNumChannels); #endif if (!pnWorkBuffer) return ErrorReturn(pnError, ABF_OUTOFMEMORY); if (!ABF_ReadDACFileEpiEx(nFile, &NewFH, pnWorkBuffer, uDACChannel, dwEpisode, pnError)) return FALSE; ScaleDACBuffer(&NewFH, uDACChannel, 0, pnWorkBuffer, pfBuffer); return TRUE; } //=============================================================================================== // FUNCTION: ABF_WriteTag // PURPOSE: This function buffers tags to a temporary file through the CABFItem object in the // file descriptor. // BOOL WINAPI ABF_WriteTag(int nFile, ABFFileHeader *pFH, const ABFTag *pTag, int *pnError) { ABFH_WASSERT(pFH); WPTRASSERT(pTag); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag( FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); if (!pFI->PutTag(pTag)) return ErrorReturn(pnError, pFI->GetLastError()); pFH->lNumTagEntries = pFI->GetTagCount(); return TRUE; } //=============================================================================================== // FUNCTION: ABF_UpdateTag // PURPOSE: This function updates a tag entry in a writeable file. // BOOL WINAPI ABF_UpdateTag(int nFile, UINT uTag, const ABFTag *pTag, int *pnError) { WPTRASSERT(pTag); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag( FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); if (!pFI->UpdateTag(uTag, pTag)) return ErrorReturn(pnError, pFI->GetLastError()); return TRUE; } //=============================================================================================== // FUNCTION: ABF_ReadTags // PURPOSE: This function reads a tag array from the TagArray section // BOOL WINAPI ABF_ReadTags(int nFile, const ABFFileHeader *pFH, DWORD dwFirstTag, ABFTag *pTagArray, UINT uNumTags, int *pnError) { ABFH_ASSERT(pFH); ARRAYASSERT(pTagArray, uNumTags); UINT i; CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // If this file is being written, the tags will be in the virtual tag buffer. if (pFI->GetTagCount() > 0) { if (!pFI->ReadTags(dwFirstTag, pTagArray, uNumTags)) return ErrorReturn(pnError, ABF_EREADTAG); return TRUE; } // If there are no tags present, return an error. if ((pFH->lTagSectionPtr==0) || (pFH->lNumTagEntries==0)) return ErrorReturn(pnError, ABF_ENOTAGS); if (dwFirstTag+uNumTags > UINT(pFH->lNumTagEntries)) return ErrorReturn(pnError, ABF_EREADTAG); // Read and convert old FETCHEX tags. if (pFH->nFileType != ABF_ABFFILE) { // Seek to the start of the requested segment (first entry is the count of tags, this is // placed in pFH->lNumTagEntries when the header is read). UINT uSeekPos = UINT(pFH->lTagSectionPtr) * ABF_BLOCKSIZE + dwFirstTag * sizeof(ABFLONG) + sizeof(ABFLONG); VERIFY(pFI->Seek(uSeekPos, FILE_BEGIN)); // Allocate a temporary buffer to read the old tags into. CArrayPtr plTags(uNumTags); if (!plTags) return ErrorReturn(pnError, ABF_OUTOFMEMORY); // Do the read. if (!pFI->Read(plTags, uNumTags * sizeof(ABFLONG))) { TRACE( "Tags could not be read from the file.\n" ); // Do not flag the error - this allows the tags to be quietly ignored. // return ErrorReturn(pnError, ABF_EREADTAG); } // Convert the tags to ABFtags. for (i=0; i= 0 ) { pTagArray[i].lTagTime = plTags[i]; memset(pTagArray[i].sComment, ' ', ABF_TAGCOMMENTLEN); pTagArray[i].nTagType = ABF_TIMETAG; pTagArray[i].nVoiceTagNumber = 0; } } } else { // Seek to the start of the requested segment. LONGLONG llSeekPos = LONGLONG(pFH->lTagSectionPtr) * ABF_BLOCKSIZE + dwFirstTag * sizeof(ABFTag); VERIFY(pFI->Seek(llSeekPos, FILE_BEGIN)); // Read the Tag Array directly into the passed buffer UINT uBytesToRead = uNumTags * sizeof(ABFTag); if (!pFI->Read(pTagArray, uBytesToRead)) return ErrorReturn(pnError, ABF_EREADTAG); } // AxoTape V2.0 filled the comment field with '\0's - convert to spaces. if (pFH->fFileVersionNumber < 1.3F) { // Set the comment string to all spaces. for (i=0; isComment; UINT i=0; for (i=0; isComment, ABF_TAGCOMMENTLEN-i); szRval[ABF_TAGCOMMENTLEN-i] = '\0'; } else LoadString(g_hInstance, IDS_NONE, szRval, sizeof(szRval)); return szRval; } //=============================================================================================== // FUNCTION: ABF_FormatTag // PURPOSE: This function reads a tag TagArray section and formats it as ASCII text. // NOTE: If tag number -1 is requested, the ASCII text returns column headings. // BOOL WINAPI ABF_FormatTag(int nFile, const ABFFileHeader *pFH, ABFLONG lTagNumber, char *pszBuffer, UINT uSize, int *pnError) { ABFH_ASSERT(pFH); ARRAYASSERT(pszBuffer, uSize); BOOL bEpisodic = ((pFH->nOperationMode==ABF_WAVEFORMFILE) || (pFH->nOperationMode==ABF_HIGHSPEEDOSC)); if (lTagNumber < 0) { int nStringID = bEpisodic ? IDS_EPITAGHEADINGS : IDS_CONTTAGHEADINGS; return (BOOL)LoadString(g_hInstance, nStringID, pszBuffer, uSize); } ABFTag Tag; char szBuf[ABF_MAXTAGFORMATLEN+4]; if (!ABF_ReadTags(nFile, pFH, UINT(lTagNumber), &Tag, 1, pnError)) return FALSE; double dTimeInMS = 0.0; ABFH_SynchCountToMS(pFH, Tag.lTagTime, &dTimeInMS); char szTagTime[32]; ABFU_FormatDouble(dTimeInMS/1E3, 10, szTagTime, sizeof(szTagTime)); char *ps = GetTagComment(&Tag); if (bEpisodic) { DWORD dwEpisode = 1; DWORD dwSynchCount = Tag.lTagTime; ABF_EpisodeFromSynchCount(nFile, pFH, &dwSynchCount, &dwEpisode, NULL); // "Tag # Time (s) Episode Comment" sprintf(szBuf, "%4ld %11.11s %4ld %-56.56s", lTagNumber+1, szTagTime, dwEpisode, ps); // NOTE: the above must NOT expand out to more than ABF_MAXTAGFORMATLEN } else // "Tag # Time (s) Comment" sprintf(szBuf, "%4ld %11.11s %-56.56s", lTagNumber+1, szTagTime, ps); strncpy(pszBuffer, szBuf, uSize-1); pszBuffer[uSize-1] = '\0'; return TRUE; } //=============================================================================================== // FUNCTION: ABF_WriteDelta // PURPOSE: This function buffers tags to a temporary file through the CABFItem object in the // file descriptor. // BOOL WINAPI ABF_WriteDelta(int nFile, ABFFileHeader *pFH, const ABFDelta *pDelta, int *pnError) { ABFH_WASSERT(pFH); WPTRASSERT(pDelta); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag( FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); if (!pFI->PutDelta(pDelta)) return ErrorReturn(pnError, pFI->GetLastError()); pFH->lNumDeltas = pFI->GetDeltaCount(); return TRUE; } //=============================================================================================== // FUNCTION: ABF_ReadDeltas // PURPOSE: This function reads a Delta array from the DeltaArray section // BOOL WINAPI ABF_ReadDeltas(int nFile, const ABFFileHeader *pFH, DWORD dwFirstDelta, ABFDelta *pDeltaArray, UINT uNumDeltas, int *pnError) { ABFH_ASSERT(pFH); ARRAYASSERT(pDeltaArray, uNumDeltas); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // If this file is being written, the Deltas will be in the virtual Delta buffer. if (pFI->GetDeltaCount() > 0) { if (!pFI->ReadDeltas(dwFirstDelta, pDeltaArray, uNumDeltas)) return ErrorReturn(pnError, ABF_EREADDELTA); return TRUE; } // If there are no Deltas present, return an error. if ((pFH->lDeltaArrayPtr==0) || (pFH->lNumDeltas==0)) return ErrorReturn(pnError, ABF_ENODELTAS); if (dwFirstDelta+uNumDeltas > UINT(pFH->lNumDeltas)) return ErrorReturn(pnError, ABF_EREADDELTA); // Seek to the start of the requested segment. LONGLONG llSeekPos = LONGLONG(pFH->lDeltaArrayPtr) * ABF_BLOCKSIZE + dwFirstDelta * sizeof(ABFDelta); VERIFY(pFI->Seek(llSeekPos, FILE_BEGIN)); // Read the Delta Array directly into the passed buffer UINT uBytesToRead = uNumDeltas * sizeof(ABFDelta); if (!pFI->Read(pDeltaArray, uBytesToRead)) return ErrorReturn(pnError, ABF_EREADTAG); return TRUE; } //=============================================================================================== // FUNCTION: FormatAsBinary // PURPOSE: Formats a . // static int FormatAsBinary(UINT uValue, LPSTR pszBuffer, UINT uBufferLength) { UINT uNumBits = 8; if (uNumBits >= uBufferLength) uNumBits = uBufferLength - 1; for (UINT i=0; ilParameterID) { case ABF_DELTA_HOLDING0: case ABF_DELTA_HOLDING1: case ABF_DELTA_HOLDING2: case ABF_DELTA_HOLDING3: { UINT uDAC = pDelta->lParameterID - ABF_DELTA_HOLDING0; char szSignal[ABF_DACNAMELEN+1] = { '#', char(uDAC+'0'), '\0' }; char szUnits[ABF_DACUNITLEN+2] = { ' ', '\0' }; ABF_GET_STRING(szSignal, pFH->sDACChannelName[uDAC], sizeof(szSignal)); ABF_GET_STRING(szUnits+1, pFH->sDACChannelUnits[uDAC], sizeof(szUnits)-1); _snprintf(szText, sizeof(szText), "Holding on '%s' => %g", szSignal, pDelta->fNewParamValue); if (szUnits[1] != '\0') strcat(szText, szUnits); break; } case ABF_DELTA_DIGITALOUTS: { char szBuffer[9]; FormatAsBinary(UINT(pDelta->lNewParamValue), szBuffer, sizeof(szBuffer)); _snprintf(szText, sizeof(szText), "Digital Outputs => %s", szBuffer); break; } case ABF_DELTA_THRESHOLD: _snprintf(szText, sizeof(szText), "Threshold => %g", pDelta->fNewParamValue); break; case ABF_DELTA_PRETRIGGER: _snprintf(szText, sizeof(szText), "Pre-trigger => %d", (int)( pDelta->lNewParamValue / pFH->nADCNumChannels ) ); break; default: if ((pDelta->lParameterID >= ABF_DELTA_AUTOSAMPLE_GAIN) && (pDelta->lParameterID < ABF_DELTA_AUTOSAMPLE_GAIN+ABF_ADCCOUNT)) { _snprintf(szText, sizeof(szText), "Autosample gain => %g", pDelta->fNewParamValue); break; } ERRORMSG1("ABFDelta: Unexpected parameter ID '%d'.", pDelta->lParameterID); return ErrorReturn(pnError, ABF_EBADDELTAID); } strncpy(pszText, szText, uTextLen-1); pszText[uTextLen-1] = '\0'; return TRUE; } //=============================================================================================== // FUNCTION: ABF_EpisodeFromSynchCount // PURPOSE: This routine returns the episode number for the synch count that is // passed as an argument. // INPUT: // nFile the file index into the g_FileData structure array // pdwSynchCount the synch count to search for. // // OUTPUT: // pdwEpisode the episode number which contains the requested sample // pdwSynchCount the synch count of the start of the episode // BOOL WINAPI ABF_EpisodeFromSynchCount(int nFile, const ABFFileHeader *pFH, DWORD *pdwSynchCount, DWORD *pdwEpisode, int *pnError) { ABFH_ASSERT(pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; UINT uAcquiredEpisodes = pFI->GetAcquiredEpisodes(); // For data that is continuous in time or for a Waveform data file, just // calculate the episode number by dividing the synch count by the episode // size in samples. if (pFI->GetSynchCount() == 0) // (old ABF_WAVEFORMFILE or ABF_GAPFREEFILE) { UINT uEpiSize = UINT(pFH->lNumSamplesPerEpisode); UINT uEpisode = *pdwSynchCount / uEpiSize + 1; if (uEpisode > uAcquiredEpisodes) uEpisode = uAcquiredEpisodes; *pdwSynchCount = uEpiSize * (uEpisode - 1); *pdwEpisode = uEpisode; return TRUE; } // Search the data file for the target sample number, taking into account // the missing samples between episodes. UINT uEpiStart = pFI->EpisodeStart(1); if (uEpiStart > *pdwSynchCount) { *pdwEpisode = 1; *pdwSynchCount = uEpiStart; return TRUE; } // Do a linear search on the synch array to find the episode that corresponds // to this sample number. This may be changed to a binary search in the future if // it seems to be too slow on really big data files. UINT uCounter = uEpiStart; for (UINT i=2; i <= uAcquiredEpisodes; i++) { uEpiStart = pFI->EpisodeStart(i); if (uEpiStart > *pdwSynchCount) { *pdwEpisode = i - 1; *pdwSynchCount = uCounter; return TRUE; } uCounter = uEpiStart; } // Return the results. *pdwEpisode = uAcquiredEpisodes; *pdwSynchCount = uCounter; return TRUE; } //=============================================================================================== // FUNCTION: ABF_SynchCountFromEpisode // PURPOSE: This routine returns the synch count for the start of the given // episode number that is passed as an argument. // INPUT: // nFile the file index into the g_FileData structure array // pdwEpisode the episode number which is being searched for // // OUTPUT: // pdwSynchCount the synch count of the start of the episode // BOOL WINAPI ABF_SynchCountFromEpisode(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, DWORD *pdwSynchCount, int *pnError) { ABFH_ASSERT(pFH); WPTRASSERT(pdwSynchCount); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // For data that is continuous in time or is a Waveform data file then just // calculate the synch count by multiplying the episode number by the // episode size in samples. if (pFI->GetSynchCount() != 0) *pdwSynchCount = pFI->EpisodeStart(dwEpisode); else if (pFH->nOperationMode != ABF_WAVEFORMFILE) *pdwSynchCount = UINT(pFH->lNumSamplesPerEpisode) * (dwEpisode - 1); else { // (old ABF_WAVEFORMFILE) double dStartToStartUS = 0.0; ABFH_GetEpisodeStartToStart(pFH, &dStartToStartUS); *pdwSynchCount= ABFH_MSToSynchCount(pFH, dStartToStartUS/1E3 * (dwEpisode-1)); } return TRUE; } //=============================================================================================== // FUNCTION: ABF_GetEpisodeFileOffset // PURPOSE: This routine returns the sample point offset in the ABF file for the start of the given // episode number that is passed as an argument. // INPUT: // nFile the file index into the g_FileData structure array // pdwEpisode the episode number which is being searched for // // OUTPUT: // plFileOffset the Sample point number of the first point in the episode (per channel). // BOOL WINAPI ABF_GetEpisodeFileOffset(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, DWORD *pdwFileOffset, int *pnError) { ABFH_ASSERT(pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // For data that is continuous in time or is a Waveform data file then just // calculate the sample number by multiplying the episode number by the // episode size in samples. if (pFI->GetSynchCount() == 0) // (ABF_WAVEFORMFILE or ABF_GAPFREEFILE) { UINT uEpiSize = (UINT)(pFH->lNumSamplesPerEpisode / pFH->nADCNumChannels); *pdwFileOffset = uEpiSize * (dwEpisode - 1); } else *pdwFileOffset = pFI->FileOffset(dwEpisode) / pFH->nADCNumChannels / SampleSize(pFH); return TRUE; } //=============================================================================================== // FUNCTION: ABF_GetMissingSynchCount // PURPOSE: This routine returns the number of samples missing for event detected data for // the episode number passed as an argument. // INPUT: // nFile the file index into the g_FileData structure array // dwEpisode the episode number of interest // // OUTPUT: // pdwMissingSynchCount the number of synch counts absent prior to this episode // BOOL WINAPI ABF_GetMissingSynchCount(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, DWORD *pdwMissingSynchCount, int *pnError) { ABFH_ASSERT(pFH); DWORD dwSynchCount = 0; if (!ABF_SynchCountFromEpisode(nFile, pFH, dwEpisode, &dwSynchCount, pnError)) return FALSE; UINT uMissing = 0; if (dwEpisode == 1) uMissing = dwSynchCount; else { ASSERT(dwEpisode > 1); DWORD dwLastSynchCount = 0; if (!ABF_SynchCountFromEpisode(nFile, pFH, dwEpisode-1, &dwLastSynchCount, pnError)) return FALSE; // Get the duration in ms. double dDurationMS = 0.0; if (!ABF_GetEpisodeDuration(nFile, pFH, dwEpisode-1, &dDurationMS, pnError)) return FALSE; // Convert the duration to synch count. dwLastSynchCount += ABFH_MSToSynchCount(pFH, dDurationMS); // Calculate the number of missing synch counts. if (dwLastSynchCount > dwSynchCount) uMissing = 0; else uMissing = dwSynchCount - dwLastSynchCount; } *pdwMissingSynchCount = uMissing; return TRUE; } //=============================================================================================== // FUNCTION: ABF_HasOverlappedData // PURPOSE: Returns true if the file contains overlapped data. // BOOL WINAPI ABF_HasOverlappedData(int nFile, BOOL *pbHasOverlapped, int *pnError) { WPTRASSERT(pbHasOverlapped); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (!pFI->TestFlag(FI_READONLY)) return ErrorReturn(pnError, ABF_EWRITEONLYFILE); *pbHasOverlapped = pFI->GetOverlappedFlag(); return TRUE; } #endif //=============================================================================================== // FUNCTION: ABF_GetNumSamples // PURPOSE: This routine returns the number of samples per channel in a given episode. // INPUT: // nFile the file index into the g_FileData structure array // dwEpisode the episode number of interest // // OUTPUT: // NumSamples% the number of data points in this episode // BOOL WINAPI ABF_GetNumSamples(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, UINT *puNumSamples, int *pnError) { // ABFH_ASSERT(pFH); UINT uRealSize; CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); if (pFI->GetSynchCount() == 0) /// (ABF_WAVEFORMFILE or ABF_GAPFREEFILE) { if ((pFH->nOperationMode == ABF_GAPFREEFILE) && (dwEpisode == pFI->GetAcquiredEpisodes())) uRealSize = pFI->GetLastEpiSize(); else uRealSize = UINT(pFH->lNumSamplesPerEpisode); } else uRealSize = (UINT)pFI->EpisodeLength(dwEpisode); *puNumSamples = uRealSize / pFH->nADCNumChannels; return TRUE; } //=============================================================================================== // FUNCTION: ABF_GetNumSamples // PURPOSE: This routine returns the number of samples per channel in a given episode. // INPUT: // nFile the file index into the g_FileData structure array // dwEpisode the episode number of interest // // OUTPUT: // NumSamples% the number of data points in this episode // BOOL WINAPI ABF2_GetNumSamples(int nFile, const ABF2FileHeader *pFH, DWORD dwEpisode, UINT *puNumSamples, int *pnError) { // ABFH_ASSERT(pFH); UINT uRealSize; CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->CheckEpisodeNumber(dwEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); if (pFI->GetSynchCount() == 0) /// (ABF_WAVEFORMFILE or ABF_GAPFREEFILE) { if ((pFH->nOperationMode == ABF_GAPFREEFILE) && (dwEpisode == pFI->GetAcquiredEpisodes())) uRealSize = pFI->GetLastEpiSize(); else uRealSize = UINT(pFH->lNumSamplesPerEpisode); } else uRealSize = (UINT)pFI->EpisodeLength(dwEpisode); *puNumSamples = uRealSize / pFH->nADCNumChannels; return TRUE; } #if 0 //=============================================================================================== // FUNCTION: ABF_GetEpisodeDuration // PURPOSE: Get the duration of a given episode in ms. // BOOL WINAPI ABF_GetEpisodeDuration(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, double *pdDuration, int *pnError) { ABFH_ASSERT(pFH); ASSERT(dwEpisode >0); WPTRASSERT(pdDuration); *pdDuration = 0.0; double dDurationUS = 0.0; if (pFH->nOperationMode == ABF_WAVEFORMFILE) ABFH_GetEpisodeDuration(pFH, &dDurationUS); else { UINT uNumSamples; if (!ABF_GetNumSamples(nFile, pFH, dwEpisode, &uNumSamples, pnError)) return FALSE; // Calculate the duration in us. dDurationUS = ABFH_GetFirstSampleInterval(pFH) * uNumSamples * pFH->nADCNumChannels; } *pdDuration = dDurationUS / 1E3; // Convert from us to ms. ASSERT(*pdDuration != 0.0); return TRUE; } //=============================================================================================== // FUNCTION: ABF_GetTrialDuration // PURPOSE: Calculate the trial duration in ms. // This is the duration between the start of the file and the last sample in the file. // BOOL WINAPI ABF_GetTrialDuration(int nFile, const ABFFileHeader *pFH, double *pdDuration, int *pnError) { ABFH_ASSERT(pFH); WPTRASSERT(pdDuration); *pdDuration = 0.0; // Get the start time of the last sweep. double dLastSweepStart = 0; if( !ABF_GetStartTime( nFile, pFH, pFH->nADCSamplingSeq[0], pFH->lActualEpisodes, &dLastSweepStart, pnError ) ) return FALSE; // Now the duration of the last sweep. double dLastSweepDuration = 0; if( !ABF_GetEpisodeDuration( nFile, pFH, pFH->lActualEpisodes, &dLastSweepDuration, pnError ) ) return FALSE; double dTotalDuration = dLastSweepStart + dLastSweepDuration; ASSERT( dTotalDuration > 0 ); *pdDuration = dTotalDuration; return TRUE; } //=============================================================================================== // FUNCTION: ABF_GetStartTime // PURPOSE: Get the start time for the first sample of the given episode in ms. // BOOL WINAPI ABF_GetStartTime(int nFile, const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, double *pdStartTime, int *pnError) { ABFH_ASSERT(pFH); WPTRASSERT(pdStartTime); ASSERT(dwEpisode > 0); DWORD dwSynchCount = 0; if (!ABF_SynchCountFromEpisode(nFile, pFH, dwEpisode, &dwSynchCount, pnError)) return FALSE; // test for the average sweep if ( dwSynchCount == ABF_AVERAGESWEEPSTART ) { *pdStartTime = 0.0; return TRUE; } ABFH_SynchCountToMS(pFH, dwSynchCount, pdStartTime); // Get the offset into the multiplexed data array for the first point UINT uChannelOffset; if (!ABFH_GetChannelOffset(pFH, nChannel, &uChannelOffset)) return ErrorReturn(pnError, ABF_EINVALIDCHANNEL); *pdStartTime += uChannelOffset * ABFH_GetFirstSampleInterval(pFH) / 1E3; return TRUE; } //############################################################################################### //### //### Functions to read and write scope configuration data. //### //############################################################################################### //=============================================================================================== // FUNCTION: _UpdateOldDisplayEntries // PURPOSE: Updates the old display entries in the ABF header for backward compatability. // static void _UpdateOldDisplayEntries(ABFFileHeader *pFH, const ABFScopeConfig *pCfg) { if ((pFH->nOperationMode == ABF_WAVEFORMFILE) || (pFH->nOperationMode == ABF_HIGHSPEEDOSC)) { pFH->lStartDisplayNum = ABFLONG(pCfg->fDisplayStart); pFH->lFinishDisplayNum= ABFLONG(pCfg->fDisplayEnd); } else pFH->lSamplesPerTrace = ABFLONG(pCfg->fDisplayEnd); for (int i=0; inADCNumChannels); i++) { float fGain = 1.0F; float fOffset = 0.0F; int nChannel = pFH->nADCSamplingSeq[i]; const ABFSignal *pT = pCfg->TraceList; for (int j=0; jnTraceCount; j++, pT++) if ((pT->nMxOffset==i) && !pT->bFloatData) { fGain = pT->fDisplayGain; fOffset = pT->fDisplayOffset; break; } pFH->fADCDisplayAmplification[nChannel] = fGain; pFH->fADCDisplayOffset[nChannel] = fOffset; } } #include //=============================================================================================== // FUNCTION: ABF_WriteScopeConfig // PURPOSE: Saves the current scope configuration info to the data file. // BOOL WINAPI ABF_WriteScopeConfig(int nFile, ABFFileHeader *pFH, int nScopes, const ABFScopeConfig *pCfg, int *pnError) { ABFH_WASSERT(pFH); if (nScopes == 0) { pFH->lNumScopes = 0; pFH->lScopeConfigPtr = 0; return TRUE; } BOOL bHasData = ABF_HasData(nFile, pFH); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag(FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); if (!pFI->FillToNextBlock(&pFH->lScopeConfigPtr)) return ErrorReturn(pnError, ABF_EDISKFULL); // The ABFScopeConfig has been extended for ABF file v1.68. // The original scope configurations defined as 'Section1' are written out to file first, // to keep backwards comapatability. // The new configuration data, known as 'Section2' will be appended to the scope configuration data. UINT uSizeofVersion1 = offsetof(ABFScopeConfig,nSizeofOldStructure); UINT uSizeofVersion2 = sizeof(ABFScopeConfig) - uSizeofVersion1; UINT uSizeofWhole = uSizeofVersion2 + uSizeofVersion1; ASSERT( uSizeofWhole == sizeof(ABFScopeConfig) ); // Prevent compiler warnings. uSizeofWhole = uSizeofWhole; // Write out section1 ABF scope configuration for backwards compatability. for( int i = 0; i < nScopes; i ++ ) { if (!pFI->Write( &pCfg[i], uSizeofVersion1 )) { pFH->lScopeConfigPtr = 0; return ErrorReturn(pnError, ABF_EDISKFULL); } } // Write the new section2 ABFScopeConfig data. for(int i = 0; i < nScopes; i ++ ) { if (!pFI->Write( (char*)&pCfg[i] + uSizeofVersion1, uSizeofVersion2 )) { pFH->lScopeConfigPtr = 0; return ErrorReturn(pnError, ABF_EDISKFULL); } } // Update the number of scopes in the header. pFH->lNumScopes = nScopes; if (!bHasData && !pFI->FillToNextBlock(&pFH->lDataSectionPtr)) return ErrorReturn(pnError, ABF_EDISKFULL); _UpdateOldDisplayEntries(pFH, pCfg); LONGLONG llHere = 0; VERIFY(pFI->Seek(0, FILE_CURRENT, &llHere)); // Update the header on disk. VERIFY(pFI->Seek( 0, FILE_BEGIN)); UINT uBytesToWrite = sizeof(ABFFileHeader); if (!pFI->Write( pFH, uBytesToWrite )) { pFH->lScopeConfigPtr = 0; return ErrorReturn(pnError, ABF_EDISKFULL); } VERIFY(pFI->Seek(llHere, FILE_BEGIN)); return TRUE; } //=============================================================================================== // FUNCTION: ABF_ReadScopeConfig // PURPOSE: Retrieves the scope configuration info from the data file. // BOOL WINAPI ABF_ReadScopeConfig(int nFile, ABFFileHeader *pFH, ABFScopeConfig *pCfg, UINT uMaxScopes, int *pnError) { ABFH_WASSERT(pFH); ARRAYASSERT(pCfg, (UINT)(pFH->lNumScopes)); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if ((pFH->lNumScopes < 1) || (pFH->lScopeConfigPtr == 0)) { pFH->lNumScopes = 1; ABFH_InitializeScopeConfig(pFH, pCfg); return TRUE; } UINT uOffset = pFH->lScopeConfigPtr * ABF_BLOCKSIZE; VERIFY(pFI->Seek( uOffset, FILE_BEGIN)); UINT uScopes = (uMaxScopes < UINT(pFH->lNumScopes)) ? uMaxScopes : UINT(pFH->lNumScopes); // The ABFScopeConfig has been extended for ABF file v1.68. // The original scope configurations defined as 'Section1' are read in first, // to keep backwards compatability. // The new configuration data, known as 'Section2' is appended after the scope configuration data // and is read last, and only for the new files that support it. UINT uSizeofSection1 = offsetof(ABFScopeConfig,nSizeofOldStructure); UINT uSizeofSection2 = sizeof(ABFScopeConfig) - uSizeofSection1; UINT uSizeofWhole = uSizeofSection2 + uSizeofSection1; ASSERT( uSizeofWhole == sizeof(ABFScopeConfig) ); // Prevent compiler warnings. uSizeofWhole = uSizeofWhole; // Read old section of the scope config structure for( int i = 0; i < pFH->lNumScopes; i ++ ) { if (!pFI->Read( &pCfg[i], uSizeofSection1)) return ErrorReturn(pnError, ABF_EREADSCOPECONFIG); } // Read the new section ABFScopeConfig structures into the buffer if( pFH->fHeaderVersionNumber >= 1.68F ) { for(int i = 0; i < pFH->lNumScopes; i++ ) { if (!pFI->Read( (char*)&pCfg[i] + uSizeofSection1, uSizeofSection2)) return ErrorReturn(pnError, ABF_EREADSCOPECONFIG); } } pFH->lNumScopes = uScopes; if (pFH->fFileVersionNumber < 1.5) { for (UINT i=0; iTestFlag(FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); if (!pFI->FillToNextBlock(&pFH->lStatisticsConfigPtr)) return ErrorReturn(pnError, ABF_EDISKFULL); if (!pFI->Write( pCfg, sizeof(ABFScopeConfig))) { pFH->lStatisticsConfigPtr = 0; return ErrorReturn(pnError, ABF_EDISKFULL); } if (!bHasData && !pFI->FillToNextBlock(&pFH->lDataSectionPtr)) return ErrorReturn(pnError, ABF_EDISKFULL); LONGLONG llHere = 0; VERIFY(pFI->Seek(0, FILE_CURRENT, &llHere)); // Update the header on disk. VERIFY(pFI->Seek( 0, FILE_BEGIN)); if (!pFI->Write( pFH, sizeof(ABFFileHeader) )) { pFH->lStatisticsConfigPtr = 0; return ErrorReturn(pnError, ABF_EDISKFULL); } VERIFY(pFI->Seek(llHere, FILE_BEGIN)); return TRUE; } //=============================================================================================== // FUNCTION: ABF_ReadStatisticsConfig // PURPOSE: Read the scope config structure for the statistics window in form the ABF file. // BOOL WINAPI ABF_ReadStatisticsConfig( int nFile, const ABFFileHeader *pFH, ABFScopeConfig *pCfg, int *pnError) { ABFH_ASSERT(pFH); WPTRASSERT(pCfg); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (pFH->lStatisticsConfigPtr == 0) return ErrorReturn(pnError, ABF_ENOSTATISTICSCONFIG); UINT uOffset = pFH->lStatisticsConfigPtr * ABF_BLOCKSIZE; VERIFY(pFI->Seek( uOffset, FILE_BEGIN)); // The ABFScopeConfig structure has been extended for ABF file version 1.68. // If the file is a new file, reading is unaffected as only one structure is saved for the statistics config. // If the file is an older file, only the size of section1 of the scope config is read to avoid reading junk data. if( pFH->fFileVersionNumber >= 1.68F ) { if (!pFI->Read(pCfg, sizeof(ABFScopeConfig))) return ErrorReturn(pnError, ABF_EREADSTATISTICSCONFIG); } else { UINT uSizeofSection1 = offsetof(ABFScopeConfig,nSizeofOldStructure); // Read only size of version 1. if ( !pFI->Read(pCfg, uSizeofSection1 )) return ErrorReturn(pnError, ABF_EREADSTATISTICSCONFIG); } return TRUE; } //############################################################################################### //### //### Functions to read and write voice tags. //### //############################################################################################### //=============================================================================================== // FUNCTION: ABF_SaveVoiceTag // PURPOSE: Saves a reference to a temporary file containing a voice tag. // BOOL WINAPI ABF_SaveVoiceTag( int nFile, LPCSTR pszFileName, ABFLONG lDataOffset, ABFVoiceTagInfo *pVTI, int *pnError) { LPSZASSERT(pszFileName); WPTRASSERT(pVTI); // Get the file descriptor for this ABF file. CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (!pFI->SaveVoiceTag( pszFileName, lDataOffset, pVTI )) return ErrorReturn( pnError, pFI->GetLastError() ); return TRUE; } //=============================================================================================== // FUNCTION: ABF_GetVoiceTag // PURPOSE: Retrieves a voice tag into a new file, leaving space for a header. // BOOL WINAPI ABF_GetVoiceTag( int nFile, const ABFFileHeader *pFH, UINT uTag, LPCSTR pszFileName, ABFLONG lDataOffset, ABFVoiceTagInfo *pVTI, int *pnError) { LPSZASSERT(pszFileName); WPTRASSERT(pVTI); // Get the file descriptor for this ABF file. CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; if (ABFLONG(uTag) >= pFH->lVoiceTagEntries) return ErrorReturn( pnError, ABF_EREADTAG ); if (!pFI->GetVoiceTag( uTag, pszFileName, lDataOffset, pVTI, pFH->lVoiceTagPtr )) return ErrorReturn( pnError, pFI->GetLastError() ); return TRUE; } #endif //=============================================================================================== // FUNCTION: ABF_BuildErrorText // PURPOSE: This routine returns the last error as a text string. // BOOL WINAPI ABF_BuildErrorText(int nErrorNum, const char *szFileName, char *sTxtBuf, UINT uMaxLen) { // LPSZASSERT(szFileName); // ARRAYASSERT(sTxtBuf, uMaxLen); if (uMaxLen < 2) { // ERRORMSG("String too short!"); return FALSE; } if (nErrorNum > ABFH_FIRSTERRORNUMBER) return ABFH_GetErrorText( nErrorNum, sTxtBuf, uMaxLen); BOOL rval = TRUE; // OK return value char szTemplate[128]; #if defined(_WINDOWS) && !defined(__MINGW32__) if (!LoadStringA(g_hInstance, nErrorNum, szTemplate, sizeof(szTemplate))) #else if (!c_LoadString(g_hInstance, nErrorNum, szTemplate, sizeof(szTemplate))) #endif { char szErrorMsg[128]; #if defined(_WINDOWS) && !defined(__MINGW32__) LoadStringA(g_hInstance, IDS_ENOMESSAGESTR, szTemplate, sizeof(szTemplate)); #else c_LoadString(g_hInstance, IDS_ENOMESSAGESTR, szTemplate, sizeof(szTemplate)); #endif snprintf(szErrorMsg, sizeof(szErrorMsg), szTemplate, nErrorNum); // ERRORMSG(szErrorMsg); strncpy(sTxtBuf, szErrorMsg, uMaxLen-1); sTxtBuf[uMaxLen-1] = '\0'; rval = FALSE; } else #if defined(_WINDOWS) && !defined(__MINGW32__) _snprintf(sTxtBuf, uMaxLen, szTemplate, szFileName); #else snprintf(sTxtBuf, uMaxLen, szTemplate, szFileName); #endif return rval; } #if 0 //=============================================================================================== // FUNCTION: ABF_SetErrorCallback // PURPOSE: This routine sets a callback function to be called in the event of an error occuring. // BOOL WINAPI ABF_SetErrorCallback(int nFile, ABFCallback fnCallback, void *pvThisPointer, int *pnError) { CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; return pFI->SetErrorCallback(fnCallback, pvThisPointer); } // *********************************************************************************************** // *********************************************************************************************** // *** // *** ABF_GetSynchArray exposes an internal synch object to enable direct access to the // *** synch array by real-time data acquisition components. // *** // *********************************************************************************************** // *********************************************************************************************** //=============================================================================================== // FUNCTION: ABF_GetFileHandle // PURPOSE: Returns the DOS file handle for the ABF file. // BOOL WINAPI ABF_GetFileHandle(int nFile, HANDLE *phHandle, int *pnError) { CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; *phHandle = pFI->GetFileHandle(); return TRUE; } //=============================================================================================== // FUNCTION: ABF_GetSynchArray // PURPOSE: Returns a pointer to the CSynch object used to buffer the Synch array to disk. // Use with care!! // void *WINAPI ABF_GetSynchArray(int nFile, int *pnError) { CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return NULL; return pFI->GetSynchObject(); } // *********************************************************************************************** // *********************************************************************************************** // *** // *** Functions used to implement "modifiable ABF". // *** // *********************************************************************************************** // *********************************************************************************************** //=============================================================================================== // FUNCTION: ABF_UpdateEpisodeSamples // PURPOSE: This function updates a selection of samples in a particular episode. // NOTES: Only floating point data may be modified with this function -- integer data is sacrosanct. // Math channels may not be written to. // uStartSample is zero-based // uNumSamples os on-based. // BOOL WINAPI ABF_UpdateEpisodeSamples(int nFile, const ABFFileHeader *pFH, int nChannel, UINT uEpisode, UINT uStartSample, UINT uNumSamples, float *pfBuffer, int *pnError) { ABFH_ASSERT(pFH); ASSERT( uNumSamples > 0 ); ARRAYASSERT(pfBuffer, uNumSamples); UINT uPerChannel = (UINT)(pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels); ASSERT(uStartSample+uNumSamples <= uPerChannel); // Prevent compiler warnings. uPerChannel = uPerChannel; // Writing is not allowed for two-byte integer files. ASSERT(pFH->nDataFormat != ABF_INTEGERDATA); if (pFH->nDataFormat == ABF_INTEGERDATA) return ErrorReturn(pnError, ABF_EWRITERAWDATAFILE); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Check that the episode number is in range. if (!pFI->CheckEpisodeNumber(uEpisode)) return ErrorReturn(pnError, ABF_EEPISODERANGE); // Cannot write to a math channel. if (nChannel < 0) return ErrorReturn(pnError, ABF_EWRITEMATHCHANNEL); // Get the offset into the multiplexed data array for the first point UINT uChannelOffset; if (!ABFH_GetChannelOffset(pFH, nChannel, &uChannelOffset)) return ErrorReturn(pnError, ABF_EINVALIDCHANNEL); // Set the sample size in the data. UINT uSampleSize = SampleSize(pFH); // Only create the read buffer on demand, it is freed when the file is closed. if (!pFI->GetReadBuffer()) { if (!pFI->AllocReadBuffer(pFH->lNumSamplesPerEpisode * uSampleSize)) return ErrorReturn(pnError, ABF_OUTOFMEMORY); } // Read the whole episode from the ABF file only if it is not already cached. if (uEpisode != pFI->GetCachedEpisode()) { UINT uEpisodeSize = (UINT)pFH->lNumSamplesPerEpisode; if (!ABF_MultiplexRead(nFile, pFH, uEpisode, pFI->GetReadBuffer(), &uEpisodeSize, pnError)) { pFI->SetCachedEpisode(UINT(-1), 0); return FALSE; } pFI->SetCachedEpisode(uEpisode, uEpisodeSize); } // Update the samples in the episode cache. UINT uEpisodeOffset = uStartSample * pFH->nADCNumChannels; float *pfEpisodeBuffer = (float *)pFI->GetReadBuffer() + uEpisodeOffset; float *pfData = pfEpisodeBuffer + uChannelOffset; for (UINT i=0; inADCNumChannels; } // Commit the change to file. BOOL bReadOnly = pFI->TestFlag(FI_READONLY); if (bReadOnly) VERIFY(pFI->Reopen(FALSE)); Synch SynchEntry = { 0 }; VERIFY(GetSynchEntry( pFH, pFI, uEpisode, &SynchEntry )); UINT uOffset = GetDataOffset(pFH) + SynchEntry.dwFileOffset + uEpisodeOffset * sizeof(float); pFI->Seek(uOffset, FILE_BEGIN); pFI->Write(pfEpisodeBuffer, uNumSamples*pFH->nADCNumChannels*sizeof(float)); if (bReadOnly) VERIFY(pFI->Reopen(TRUE)); return TRUE; } #endif //=============================================================================================== // FUNCTION: ABF2_SetChunkSize // PURPOSE: This routine can be called on files of type ABF_GAPFREEFILE or ABF_VARLENEVENTS to change // the size of the data chunks returned by the read routines. // INPUT: // hFile ABF file number of this file (NOT the DOS handle) // pFH the current acquisition parameters for the data file // puMaxSamples points to the requested size of data blocks to be returned. // This is only used in the case of GAPFREE and EVENT-DETECTED- // VARIABLE-LENGTH acquisitions. Otherwise the size of the // Episode is used. 80x86 limitations require this to be // less than or equal to 64k. // pdwMaxEpi The maximum number of episodes to be read. // OUTPUT: // pFH the acquisition parameters that were read from the data file // puMaxSamples the maximum number of samples that can be read contiguously // from the data file. // pdwMaxEpi the number of episodes of puMaxSamples points that exist // in the data file. // BOOL WINAPI ABF2_SetChunkSize( int nFile, ABF2FileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError ) { // ASSERT(nFile != ABF_INVALID_HANDLE); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; return ABF2_SetChunkSize( pFI, pFH, puMaxSamples, pdwMaxEpi, pnError ); } #if 0 //=============================================================================================== // FUNCTION: ABF_SetOverlap // PURPOSE: Changes the overlap flag and processes the synch array to edit redundant data out if no overlap. // BOOL WINAPI ABF_SetOverlap(int nFile, const ABFFileHeader *pFH, BOOL bAllowOverlap, int *pnError) { ASSERT(nFile != ABF_INVALID_HANDLE); ABFH_ASSERT(pFH); // Get the file descriptor. CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; return _SetOverlap(pFI, pFH, bAllowOverlap, pnError); } // *********************************************************************************************** // *********************************************************************************************** // *** // *** Functions used to read and write annotations. // *** // *********************************************************************************************** // *********************************************************************************************** //=============================================================================================== // FUNCTION: ABF_WriteAnnotation // PURPOSE: Write an annotation to the Annotations Section of the ABF file. // BOOL WINAPI ABF_WriteAnnotation( int nFile, ABFFileHeader *pFH, LPCSTR pszText, int *pnError ) { ASSERT(nFile != ABF_INVALID_HANDLE); ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Return an error if writing is inappropriate. if (pFI->TestFlag( FI_PARAMFILE | FI_READONLY)) return ErrorReturn(pnError, ABF_EREADONLYFILE); if (!pFI->PutAnnotation( pszText)) return ErrorReturn(pnError, pFI->GetLastError()); NewFH.lNumAnnotations = pFI->GetAnnotationCount(); ABFH_DemoteHeader( pFH, &NewFH ); return TRUE; } BOOL WINAPI ABF_WriteStringAnnotation( int nFile, ABFFileHeader *pFH, LPCSTR pszName, LPCSTR pszData, int *pnError ) { LPSZASSERT(pszName); LPSZASSERT(pszData); const char c_pszTag[] = ""; CArrayPtrEx Ann(strlen(pszName)+strlen(c_pszTag)+strlen(pszData)+1); if (!Ann) return ErrorReturn(pnError, ABF_OUTOFMEMORY); AXU_strncpyz(Ann, pszName, Ann.GetCount()); AXU_strncatz(Ann, c_pszTag, Ann.GetCount()); AXU_strncatz(Ann, pszData, Ann.GetCount()); return ABF_WriteAnnotation( nFile, pFH, Ann, pnError ); } BOOL WINAPI ABF_WriteIntegerAnnotation( int nFile, ABFFileHeader *pFH, LPCSTR pszName, int nData, int *pnError ) { LPSZASSERT(pszName); const char c_pszTag[] = ""; CArrayPtrEx Ann(strlen(pszName)+strlen(c_pszTag)+32+1); if (!Ann) return ErrorReturn(pnError, ABF_OUTOFMEMORY); AXU_strncpyz(Ann, pszName, Ann.GetCount()); AXU_strncatz(Ann, c_pszTag, Ann.GetCount()); itoa(nData, Ann+strlen(Ann), 10); return ABF_WriteAnnotation( nFile, pFH, Ann, pnError ); } //=============================================================================================== // FUNCTION: ABF_ReadAnnotation // PURPOSE: Read an annotation to the Annotations Section of the ABF file.. // BOOL WINAPI ABF_ReadAnnotation( int nFile, const ABFFileHeader *pFH, DWORD dwIndex, LPSTR pszText, DWORD dwBufSize, int *pnError ) { ASSERT( nFile != ABF_INVALID_HANDLE ); ABFH_ASSERT( pFH ); ARRAYASSERT( pszText, dwBufSize); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // If there are no annotations present, return an error. if( NewFH.lNumAnnotations==0 ) return ErrorReturn(pnError, ABF_ENOANNOTATIONS); // If there are annotations in the file, but not in the virtual buffer, read them now. if( (NewFH.lAnnotationSectionPtr>0) && (pFI->GetAnnotationCount() == 0) ) { if( !pFI->ReadAllAnnotations( NewFH.lAnnotationSectionPtr ) ) return ErrorReturn(pnError, ABF_EREADANNOTATION); } if( !pFI->ReadAnnotation( dwIndex, pszText, dwBufSize ) ) return ErrorReturn(pnError, ABF_EREADANNOTATION); return TRUE; } //=============================================================================================== // FUNCTION: ABF_ParseStringAnnotation // PURPOSE: This function parses a String annotation. // e.g. NameValue // BOOL WINAPI ABF_ParseStringAnnotation( LPCSTR pszAnn, LPSTR pszName, UINT uSizeName, LPSTR pszValue, UINT uSizeValue, int *pnError) { LPCSTR pszStart = pszAnn; while (*pszStart==' ') ++pszStart; LPCSTR pszEnd = strchr(pszStart, '<'); if (pszEnd) { AXU_strncpyz(pszName, pszStart, min(uSizeName, UINT(pszEnd-pszStart+1))); pszEnd = strchr(pszEnd, '>'); if (!pszEnd) return ErrorReturn(pnError, ABF_EREADANNOTATION); pszStart = pszEnd+1; } AXU_strncpyz(pszValue, pszStart, uSizeValue); return true; } //=============================================================================================== // FUNCTION: ABF_ReadStringAnnotation // PURPOSE: This function reads and parses a String annotation. // e.g. NameValue // BOOL WINAPI ABF_ReadStringAnnotation( int nFile, const ABFFileHeader *pFH, DWORD dwIndex, LPSTR pszName, UINT uSizeName, LPSTR pszValue, UINT uSizeValue, int *pnError ) { ARRAYASSERT( pszName, uSizeName); ARRAYASSERT( pszValue, uSizeValue); UINT uLen = ABF_GetMaxAnnotationSize( nFile, pFH ); if (!uLen) return ErrorReturn(pnError, ABF_EREADANNOTATION); CArrayPtrEx Ann(uLen); if (!Ann) return ErrorReturn(pnError, ABF_OUTOFMEMORY); if (!ABF_ReadAnnotation( nFile, pFH, dwIndex, Ann, Ann.GetCount(), pnError )) return FALSE; return ABF_ParseStringAnnotation( Ann, pszName, uSizeName, pszValue, uSizeValue, pnError); } //=============================================================================================== // FUNCTION: ABF_ReadIntegerAnnotation // PURPOSE: This function reads and parses an integer annotation. // e.g. NameValue // and parses the name and value // BOOL WINAPI ABF_ReadIntegerAnnotation( int nFile, const ABFFileHeader *pFH, DWORD dwIndex, LPSTR pszName, UINT uSizeName, int *pnValue, int *pnError ) { ARRAYASSERT( pszName, uSizeName); UINT uLen = ABF_GetMaxAnnotationSize( nFile, pFH ); if (!uLen) return ErrorReturn(pnError, ABF_EREADANNOTATION); CArrayPtrEx Ann(uLen); if (!Ann) return ErrorReturn(pnError, ABF_OUTOFMEMORY); if (!ABF_ReadAnnotation( nFile, pFH, dwIndex, Ann, Ann.GetCount(), pnError )) return FALSE; LPCSTR pszStart = AXU_StripWhiteSpace(Ann); LPCSTR pszEnd = strchr(pszStart, '<'); if (pszEnd) { AXU_strncpyz(pszName, pszStart, min(uSizeName, UINT(pszEnd-pszStart+1))); pszEnd = strchr(pszEnd, '>'); if (!pszEnd) return ErrorReturn(pnError, ABF_EREADANNOTATION); pszStart = pszEnd+1; if (pszStart[0]!='i' || pszStart[1] != ',') return ErrorReturn(pnError, ABF_EREADANNOTATION); } if (pnValue) *pnValue = atoi(pszStart); return true; } //=============================================================================================== // FUNCTION: ABF_GetMaxAnnotationSize // PURPOSE: Return the size in bytes of the largest annotation in the file. // DWORD WINAPI ABF_GetMaxAnnotationSize( int nFile, const ABFFileHeader *pFH ) { ASSERT(nFile != ABF_INVALID_HANDLE); ABFH_ASSERT( pFH ); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); CFileDescriptor *pFI = NULL; int nError = 0; if( !GetFileDescriptor( &pFI, nFile, &nError ) ) return 0; // If there are annotations in the file, but not in the virtual buffer, read them now. if( (NewFH.lAnnotationSectionPtr>0) && (pFI->GetAnnotationCount() == 0) ) { if( !pFI->ReadAllAnnotations( pFH->lAnnotationSectionPtr ) ) return ErrorReturn( &nError, ABF_EREADANNOTATION); } // If this file is being written, the annotations will be in the virtual buffer. if (pFI->GetAnnotationCount() > 0) return pFI->GetMaxAnnotationSize(); return 0; } //=============================================================================================== // FUNCTION: ABF_GetFileName // PURPOSE: Return the filename from a currently open file. // BOOL WINAPI ABF_GetFileName( int nFile, LPSTR pszFilename, UINT uTextLen, int *pnError ) { WARRAYASSERT( pszFilename, uTextLen ); // Get the File Descriptor. CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; AXU_strncpyz( pszFilename, pFI->GetFileName(), uTextLen ); return TRUE; } //============================================================================================== // FUNCTION: ABF_ValidateFileCRC // PURPOSE: Function to validate the file using the CRC embedded in the ABF header. // The CRC is generated at the time of writing the file and can be used to // check if the file has been modified outside the application. // RETURNS: TRUE if CRC validation is OK. // FALSE if validation failed. // BOOL WINAPI ABF_ValidateFileCRC( int nFile, int *pnError ) { int nError = 0; ABFFileHeader NewFH; CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, nFile, pnError)) return FALSE; // Read the data file parameters. if (!ABFH_ParamReader(pFI->GetFileHandle(), &NewFH, &nError)) { nError = (nError == ABFH_EUNKNOWNFILETYPE) ? ABF_EUNKNOWNFILETYPE : ABF_EBADPARAMETERS; return ErrorReturn( pnError, nError ); } // Validate checksum. if( !ValidateFileCRC( pFI, &NewFH, sizeof( ABFFileHeader ) ) ) { nError = ABF_ECRCVALIDATIONFAILED; return ErrorReturn(pnError, nError); } return TRUE; } // *********************************************************************************************** // *********************************************************************************************** // *** // *** Superceded functions. // *** // *********************************************************************************************** // *********************************************************************************************** #ifdef __cplusplus extern "C" { #endif // __cplusplus BOOL WINAPI ABF_UpdateAfterAcquisition(int nFile, ABFFileHeader *pFH, DWORD dwAcquiredEpisodes, DWORD dwAcquiredSamples, int *pnError); #ifdef __cplusplus } #endif //=============================================================================================== // FUNCTION: ABF_UpdateAfterAcquisition // PURPOSE: Update ABF internal housekeeping of acquired data, this must be called // before ABF_UpdateHeader if the file has been written to through the handle // retrieved by ABF_GetFileHandle. // BOOL WINAPI ABF_UpdateAfterAcquisition(int nFile, ABFFileHeader *pFH, DWORD dwAcquiredEpisodes, DWORD dwAcquiredSamples, int *pnError) { ABFH_ASSERT(pFH); ERRORMSG("ABF_UpdateAfterAcquisition has been retired.\n"); return FALSE; } #if 0 //=============================================================================================== // FUNCTION: ABF_AppendOpen // PURPOSE: This routine opens an existing data file for appending. // INPUT: // szFileName the name of the data file that will be opened // puMaxSamples points to the requested size of data blocks to be returned. // This is only used in the case of GAPFREE and EVENT-DETECTED- // VARIABLE-LENGTH acquisitions. Otherwise the size of the // Episode is used. 80x86 limitations require this to be // less than or equal to 64k. // pdwMaxEpi The maximum number of episodes to be read. // OUTPUT: // pFH the acquisition parameters that were read from the data file // phFile pointer to the ABF file number of this file (NOT the DOS handle) // puMaxSamples the maximum number of samples that can be read contiguously // from the data file. // pdwMaxEpi the number of episodes of puMaxSamples points that exist // in the data file. // BOOL WINAPI ABF_AppendOpen(LPCSTR szFileName, int *phFile, ABFFileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError) { LPSZASSERT(szFileName); WPTRASSERT(phFile); ABFH_WASSERT(pFH); WPTRASSERT(puMaxSamples); WPTRASSERT(pdwMaxEpi); // Open the file for reading. int hFile = ABF_INVALID_HANDLE; if (!ABF_ReadOpen(szFileName, phFile, ABF_DATAFILE, pFH, puMaxSamples, pdwMaxEpi, pnError)) return FALSE; // Get the File Descriptor. CFileDescriptor *pFI = NULL; if (!GetFileDescriptor(&pFI, *phFile, pnError)) { ABF_Close(*phFile, NULL); return FALSE; } // Fix up file descriptor etc... // if (!pFI->ChangeStatus()) // { // ABF_Close(hFile, NULL); // return ErrorReturn( pnError, ABF_EOPENFILE ); // } // Read the tags into a temporary file. if (pFH->lNumTagEntries > 0) { ERRORMSG("Transfer tags to temp file!!!"); ABF_Close(hFile, NULL); return FALSE; } // Seek to the end of the Data section. UINT uOffset = GetDataOffset(pFH) + pFH->lActualAcqLength * SampleSize(pFH); pFI->Seek( uOffset, FILE_BEGIN); return TRUE; } #endif #endif stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/abfoldnx.h0000775000175000017500000002130014750344764016615 //*********************************************************************************************** // // Copyright (c) 1993-1997 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // This is ABFOLDNX.H; a header file containing definition of parameter // numbers for old pCLAMP binary data files // // NOTE: arrays are 0 relative in C, but 1 relative in BASIC #ifndef __ABFOLDNX_H__ #define __ABFOLDNX_H__ 1 #define ABF_OLDUNITLEN 16 // length of old ADC/DAC units strings #define ABF_OLDCOMMENTLEN 77 // length of old descriptor comment #define ABF_OLDCONDITLEN 64 // length of old conditioning string #define F53_EXPERIMENTTYPE 0 #define F53_ADCNUMCHANNELS 1 #define F53_SAMPLESPEREPISODE 2 #define F53_ACTUALEPISODESPERFILE 3 #define F53_ADCSAMPLEINTERVAL 4 // F53_UNUSED6 5 #define F53_FILESTARTTIME 6 #define F53_FILEELAPSEDTIME 7 #define F53_FILEVERSIONNUMBER 8 #define F53_FILESTARTDATE 9 // F53_UNUSED11 10 #define F53_SEGMENTSPEREPISODE 11 #define F53_OLDSAMPLESPEREPISODE 11 #define F53_EPISODESPERFILE 12 #define F53_REQUESTEDSAMPLEINTERVAL 13 #define F53_OPERATIONMODE 14 // F53_UNUSED16 15 // F53_UNUSED17 16 #define F53_POSTTRIGGERPORTION 17 // F53_UNUSED19 18 // F53_UNUSED20 19 #define F53_NUMPOINTSIGNORED 20 // F53_UNUSED22 21 // LongDescriptionPtr ___ never used #define F53_TAGSECTIONPTR 22 #define F53_TIMEOUTWAIT 23 #define F53_DAC0HOLDINGLEVEL 24 #define F53_NUMTAGENTRIES 25 // Was unused, used in translation // F53_UNUSED27 26 // F53_UNUSED28 27 // F53_UNUSED29 28 // F53_UNUSED30 29 #define F53_ADCNUMBERINGSTRATEGY 30 #define F53_ADCFIRSTLOGICALCHANNEL 31 #define F53_GAINDACTOCELL 32 #define F53_TAPEWINDUPTIME 33 #define F53_ENVIRONMENTALINFO 34 #define F53_CELLID1 35 #define F53_CELLID2 36 // F53_UNUSED38 37 #define F53_THRESHOLDCURRENT 38 #define F53_ADDITINSTGAIN 39 #define F53_INSTRUMENTFILTER 40 #define F53_AUTOSAMPLEINSTRUMENT 41 // F53_UNUSED43 42 #define F53_UNUSED44 43 #define F53_UNUSED45 44 #define F53_UNUSED46 45 #define F53_UNUSED47 46 #define F53_UNUSED48 47 // was copy of ADCNUMCHANNELS #define F53_CHANNEL0GAIN 48 #define F53_INVALIDLASTDATA 49 #define F53_UNUSED51 50 // F53_UNUSED52 51 #define F53_ADCRANGE 52 #define F53_DACRANGE 53 #define F53_ADCRESOLUTION 54 #define F53_DACRESOLUTION 55 // F53_UNUSED57 56 // F53_UNUSED58 57 // F53_UNUSED59 58 // F53_UNUSED60 59 #define F53_AMPLIFICATIONFACTOR 60 #define F53_VERTICALOFFSET 61 // F53_UNUSED63 62 // F53_UNUSED64 63 // F53_UNUSED65 64 // F53_UNUSED66 65 // F53_UNUSED67 66 // F53_UNUSED68 67 // F53_UNUSED69 68 #define F53_DATADISPLAYMODE 69 // F53_UNUSED71 70 // F53_UNUSED72 71 // F53_UNUSED73 72 // F53_UNUSED74 73 // F53_UNUSED75 74 // F53_UNUSED76 75 // F53_UNUSED77 76 // F53_UNUSED78 77 // F53_UNUSED79 78 // F53_UNUSED80 79 #define F53_INSTOFFSET 96 #define F53_INSTSCALEFACTOR 112 #define F53_ADCDISPLAYGAIN 128 #define F53_ADCDISPLAYOFFSET 144 // ============================================================================= // CLAMPEX Data file version 5.2 Param() index #defines #define C52_EXPERIMENTTYPE 0 #define C52_ADCNUMCHANNELS 1 #define C52_SAMPLESPEREPISODE 2 #define C52_EPISODESPERFILE 3 #define C52_FIRSTCLOCKPERIOD 4 #define C52_SECONDCLOCKPERIOD 5 #define C52_FILESTARTTIME 6 #define C52_FILEELAPSEDTIME 7 #define C52_FILEVERSIONNUMBER 8 #define C52_FILESTARTDATE 9 #define C52_INTEREPISODETIME 10 #define C52_RUNSPERFILE 11 #define C52_EPISODESPERRUN 12 #define C52_FIRSTCLOCKINTERVAL 13 #define C52_STARTDELAY 14 #define C52_NUMTRIALS 15 #define C52_STARTEPISODENUM 16 #define C52_GAINMULTIPLIER 17 #define C52_OLDPROTOCOLTYPE 17 #define C52_TRIGGERMODE 18 #define C52_PULSESAMPLECH1 19 #define C52_FIRSTTRIGGEREPISODE 20 #define C52_LASTTRIGGEREPISODE 21 #define C52_PULSESAMPLECH2 22 #define C52_SEGMENTSPEREPISODE 23 #define C52_DAC0HOLDINGLEVEL 24 #define C52_EPOCHALEVELINIT 25 #define C52_EPOCHAINCREMENT 26 #define C52_EPOCHBLEVELINIT 27 #define C52_EPOCHBINCREMENT 28 #define C52_EPOCHAINITDURATION 29 #define C52_UNUSED31 30 #define C52_ADCFIRSTLOGICALCHANNEL 31 #define C52_OLDEPOCHALEVEL 31 #define C52_GAINDACTOCELL 32 #define C52_PULSESINTRAIN 33 #define C52_PRECONDURATION 34 #define C52_PRECONLEVEL 35 #define C52_CONDURATION 36 #define C52_CONLEVEL 37 #define C52_POSTCONDURATION 38 #define C52_POSTCONLEVEL 39 #define C52_FILTERCUTOFF 40 #define C52_CH1PULSE 41 #define C52_CH2PULSE 42 #define C52_EPOCHCLEVELINIT 43 #define C52_EPOCHCINCREMENT 44 #define C52_EPOCHCINITDURATION 45 #define C52_SECONDCLOCKRATE 46 #define C52_OLDMULTIPLEXCODE 47 #define C52_AUTOSAMPLEINSTRUMENT 48 #define C52_INTEREPISODEAMP 49 #define C52_OLDCHANNEL0GAIN 48 #define C52_OLDCHANNEL1GAIN 49 // C52_UNUSED51 50 #define C52_INTEREPISODEWRITE 51 #define C52_ADCRANGE 52 #define C52_DACRANGE 53 #define C52_ADCRESOLUTION 54 #define C52_DACRESOLUTION 55 #define C52_EPOCHBINITDURATION 56 #define C52_EPOCHBDURATIONINC 57 #define C52_CONDITVARIABLE 58 #define C52_EPOCHADURATIONINC 59 #define C52_CH0DISPLAYAMPLIFICATION 60 #define C52_CH0DISPLAYOFFSET 61 #define C52_CH1DISPLAYAMPLIFICATION 62 #define C52_CH1DISPLAYOFFSET 63 #define C52_AUTOPEAKCHANNEL 63 #define C52_AVERAGEDDATADISPLAY 64 #define C52_AUTOPEAKSEARCHMODE 65 #define C52_AUTOPEAKCENTER 66 #define C52_AUTOPEAKAVPOINTS 67 #define C52_AUTOERASE 68 #define C52_DATADISPLAYMODE 69 #define C52_BASELINECALCULATION 70 #define C52_AUTOPEAKDESTINATION 71 #define C52_DISPLAYSEGMENTNUM 72 #define C52_PLOTDENSITY 73 // C52_UNUSED75 74 // C52_UNUSED76 75 // C52_UNUSED77 76 // C52_UNUSED78 77 // C52_UNUSED79 78 // C52_UNUSED80 79 #define C52_EPOCHCDURATIONINC 80 #define C52_EPOCHDLEVELINIT 81 #define C52_EPOCHDINCREMENT 82 #define C52_EPOCHDINITDURATION 83 #define C52_EPOCHDDURATIONINC 84 // C52_UNUSED86 85 #define C52_EPOCHATYPE 86 #define C52_EPOCHBTYPE 87 #define C52_EPOCHCTYPE 88 #define C52_EPOCHDTYPE 89 #define C52_PNNUMPULSES 90 #define C52_PNADCNUM 91 #define C52_PNHOLDINGLEVEL 92 #define C52_PNSETTLINGTIME 93 #define C52_PNINTERPULSE 94 #define C52_AUTOSAMPLEADCNUM 95 #define C52_INSTOFFSET 96 #define C52_INSTSCALEFACTOR 112 #define C52_ADCDISPLAYGAIN 128 #define C52_ADCDISPLAYOFFSET 144 #endif /* __ABFOLDNX_H__ */ stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/abffiles.h0000775000175000017500000003255314750344764016607 //*********************************************************************************************** // // Copyright (c) 1993-2003 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** #ifndef INC_ABFFILES_H #define INC_ABFFILES_H #include "../AxAbfFio32/AxAbffio32.h" // Include the description of the ABFFileHeader structure #ifndef RC_INVOKED #include "../AxAbfFio32/abfheadr.h" #include "../../axon2/abf2headr.h" #endif #include #include "./../../../stfio.h" // #include "../AxAbfFio32/filedesc.hpp" // File descriptors for ABF files. #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ // This is ABFFILES.H; a companion file to ABFFILES.C #define ABF_INVALID_HANDLE NULL //-1 // Error numbers for routines in this module. // Only positive numbers are used. #define ABF_SUCCESS 0 #define ABF_EUNKNOWNFILETYPE 1001 #define ABF_EBADFILEINDEX 1002 #define ABF_TOOMANYFILESOPEN 1003 #define ABF_EOPENFILE 1004 #define ABF_EBADPARAMETERS 1005 #define ABF_EREADDATA 1006 #define ABF_OUTOFMEMORY 1008 #define ABF_EREADSYNCH 1009 #define ABF_EBADSYNCH 1010 #define ABF_EEPISODERANGE 1011 #define ABF_EINVALIDCHANNEL 1012 #define ABF_EEPISODESIZE 1013 #define ABF_EREADONLYFILE 1014 #define ABF_EDISKFULL 1015 #define ABF_ENOTAGS 1016 #define ABF_EREADTAG 1017 #define ABF_ENOSYNCHPRESENT 1018 #define ABF_EREADDACEPISODE 1019 #define ABF_ENOWAVEFORM 1020 #define ABF_EBADWAVEFORM 1021 #define ABF_BADMATHCHANNEL 1022 #define ABF_BADTEMPFILE 1023 #define ABF_NODOSFILEHANDLES 1025 #define ABF_ENOSCOPESPRESENT 1026 #define ABF_EREADSCOPECONFIG 1027 #define ABF_EBADCRC 1028 #define ABF_ENOCOMPRESSION 1029 #define ABF_EREADDELTA 1030 #define ABF_ENODELTAS 1031 #define ABF_EBADDELTAID 1032 #define ABF_EWRITEONLYFILE 1033 #define ABF_ENOSTATISTICSCONFIG 1034 #define ABF_EREADSTATISTICSCONFIG 1035 #define ABF_EWRITERAWDATAFILE 1036 #define ABF_EWRITEMATHCHANNEL 1037 #define ABF_EWRITEANNOTATION 1038 #define ABF_EREADANNOTATION 1039 #define ABF_ENOANNOTATIONS 1040 #define ABF_ECRCVALIDATIONFAILED 1041 // Notifications that can be passed to the registered callback function. #define ABF_NVOICETAGSTART 2000 #define ABF_NWRITEVOICETAG 2001 #define ABF_NVOICETAGEND 2002 // Constants for the ABF_ReadOpen and ABF_WriteOpen functions #define ABF_DATAFILE 0 #define ABF_PARAMFILE 1 #define ABF_ALLOWOVERLAP 2 // If this flag is not set, overlapping data in fixed-length // event-detected data will be edited out by adjustment of // the synch array. (ABF_ReadOpen only!) // Constants for ABF_MultiplexWrite #define ABF_APPEND 2 // Episodes may be appended to the current // episode when writing ABF_VARLNEEVENTS files // Constant for ABF_FormatTag #define ABF_MAXTAGFORMATLEN 84 // Start time saved in the synch array for the oscilloscope mode average sweep #define ABF_AVERAGESWEEPSTART DWORD(-1) //---------------------- Exported Function Definitions ------------------------- // Definitions of the procedures provided by Module ABFFILES.BAS BOOL ABF_Initialize(); /* void ABF_Cleanup(void); */ BOOL WINAPI ABF_ReadOpen( LPCTSTR szFileName, int *phFile, UINT fFlags, ABFFileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError ); /* BOOL WINAPI ABF_WriteOpen( LPCSTR szFileName, int *phFile, UINT fFlags, ABFFileHeader *pFH, int *pnError ); BOOL WINAPI ABF_UpdateHeader(int nFile, ABFFileHeader *pFH, int *pnError); BOOL WINAPI ABF_IsABFFile(const char *szFileName, int *pnDataFormat, int *pnError); */ BOOL WINAPI ABF_HasData(int nFile, const ABFFileHeader *pFH); BOOL WINAPI ABF_Close(int nFile, int *pnError); BOOL WINAPI ABF_MultiplexRead(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, void *pvBuffer, UINT uBufferSize, UINT *puSizeInSamples, int *pnError); BOOL WINAPI ABF2_MultiplexRead(int nFile, const ABF2FileHeader *pFH, DWORD dwEpisode, void *pvBuffer, UINT uBufferSize, UINT *puSizeInSamples, int *pnError); /* BOOL WINAPI ABF_MultiplexWrite(int nFile, ABFFileHeader *pFH, UINT uFlags, const void *pvBuffer, DWORD dwEpiStart, UINT uSizeInSamples, int *pnError); BOOL WINAPI ABF_WriteRawData(int nFile, const void *pvBuffer, DWORD dwSizeInBytes, int *pnError); */ BOOL WINAPI ABF_ReadChannel(int nFile, const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, Vector_float& pfBuffer, UINT *puNumSamples, int *pnError); BOOL WINAPI ABF2_ReadChannel(int nFile, const ABF2FileHeader *pFH, int nChannel, DWORD dwEpisode, Vector_float& pfBuffer, UINT *puNumSamples, int *pnError); /* BOOL WINAPI ABF_ReadRawChannel(int nFile, const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, void *pvBuffer, UINT *puNumSamples, int *pnError); BOOL WINAPI ABF_ReadDACFileEpi(int nFile, const ABFFileHeader *pFH, short *pnDACArray, DWORD dwEpisode, int *pnError); BOOL WINAPI ABF_ReadDACFileEpiEx(int nFile, const ABFFileHeader *pFH, short *pnDACArray, UINT nChannel, DWORD dwEpisode, int *pnError); BOOL WINAPI ABF_WriteDACFileEpi(int nFile, ABFFileHeader *pFH, const short *pnDACArray, int *pnError); BOOL WINAPI ABF_WriteDACFileEpiEx(int nFile, ABFFileHeader *pFH, UINT uDACChannel, const short *pnDACArray, int *pnError); BOOL WINAPI ABF_GetWaveform(int nFile, const ABFFileHeader *pFH, int nADCChannel, DWORD dwEpisode, float *pfBuffer, int *pnError); BOOL WINAPI ABF_GetWaveformEx(int nFile, const ABFFileHeader *pFH, UINT uDACChannel, DWORD dwEpisode, float *pfBuffer, int *pnError); BOOL WINAPI ABF_WriteTag(int nFile, ABFFileHeader *pFH, const ABFTag *pTag, int *pnError); BOOL WINAPI ABF_UpdateTag(int nFile, UINT uTag, const ABFTag *pTag, int *pnError); BOOL WINAPI ABF_ReadTags(int nFile, const ABFFileHeader *pFH, DWORD dwFirstTag, ABFTag *pTagArray, UINT uNumTags, int *pnError); BOOL WINAPI ABF_FormatTag(int nFile, const ABFFileHeader *pFH, ABFLONG lTagNumber, char *pszBuffer, UINT uSize, int *pnError); BOOL WINAPI ABF_EpisodeFromSynchCount(int nFile, const ABFFileHeader *pFH, DWORD *pdwSynchCount, DWORD *pdwEpisode, int *pnError); BOOL WINAPI ABF_SynchCountFromEpisode(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, DWORD *pdwSynchCount, int *pnError); BOOL WINAPI ABF_GetEpisodeFileOffset(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, DWORD *pdwFileOffset, int *pnError); BOOL WINAPI ABF_GetMissingSynchCount(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, DWORD *pdwMissingSynchCount, int *pnError); BOOL WINAPI ABF_HasOverlappedData(int nFile, BOOL *pbHasOverlapped, int *pnError); */ BOOL WINAPI ABF_GetNumSamples(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, UINT *puNumSamples, int *pnError); BOOL WINAPI ABF2_GetNumSamples(int nFile, const ABF2FileHeader *pFH, DWORD dwEpisode, UINT *puNumSamples, int *pnError); /* BOOL WINAPI ABF_GetStartTime(int nFile, const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, double *pdStartTime, int *pnError); BOOL WINAPI ABF_GetEpisodeDuration(int nFile, const ABFFileHeader *pFH, DWORD dwEpisode, double *pdDuration, int *pnError); BOOL WINAPI ABF_GetTrialDuration(int nFile, const ABFFileHeader *pFH, double *pdDuration, int *pnError); BOOL WINAPI ABF_WriteScopeConfig( int nFile, ABFFileHeader *pFH, int nScopes, const ABFScopeConfig *pCfg, int *pnError); BOOL WINAPI ABF_ReadScopeConfig( int nFile, ABFFileHeader *pFH, ABFScopeConfig *pCfg, UINT uMaxScopes, int *pnError); BOOL WINAPI ABF_WriteStatisticsConfig( int nFile, ABFFileHeader *pFH, const ABFScopeConfig *pCfg, int *pnError); BOOL WINAPI ABF_ReadStatisticsConfig( int nFile, const ABFFileHeader *pFH, ABFScopeConfig *pCfg, int *pnError); BOOL WINAPI ABF_SaveVoiceTag( int nFile, LPCSTR pszFileName, ABFLONG lDataOffset, ABFVoiceTagInfo *pVTI, int *pnError); BOOL WINAPI ABF_GetVoiceTag( int nFile, const ABFFileHeader *pFH, UINT uTag, LPCSTR pszFileName, ABFLONG lDataOffset, ABFVoiceTagInfo *pVTI, int *pnError); BOOL WINAPI ABF_PlayVoiceTag( int nFile, const ABFFileHeader *pFH, UINT uTag, int *pnError); BOOL WINAPI ABF_WriteDelta(int nFile, ABFFileHeader *pFH, const ABFDelta *pDelta, int *pnError); BOOL WINAPI ABF_ReadDeltas(int nFile, const ABFFileHeader *pFH, DWORD dwFirstDelta, ABFDelta *pDeltaArray, UINT uNumDeltas, int *pnError); BOOL WINAPI ABF_FormatDelta(const ABFFileHeader *pFH, const ABFDelta *pDelta, char *pszText, UINT uTextLen, int *pnError); BOOL WINAPI ABF_GetFileHandle(int nFile, HANDLE *phHandle, int *pnError); BOOL WINAPI ABF_GetFileName( int nFile, LPSTR pszFilename, UINT uTextLen, int *pnError ); */ BOOL WINAPI ABF_BuildErrorText(int nErrorNum, const char *szFileName, char *sTxtBuf, UINT uMaxLen); /* typedef BOOL (CALLBACK *ABFCallback)(void *pvThisPointer, int nError); BOOL WINAPI ABF_SetErrorCallback(int nFile, ABFCallback fnCallback, void *pvThisPointer, int *pnError); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BOOL WINAPI ABF_AppendOpen(LPCSTR szFileName, int *phFile, ABFFileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError); BOOL WINAPI ABF_UpdateEpisodeSamples(int nFile, const ABFFileHeader *pFH, int nChannel, UINT uEpisode, UINT uStartSample, UINT uNumSamples, float *pfBuffer, int *pnError); */ BOOL WINAPI ABF2_SetChunkSize( int hFile, ABF2FileHeader *pFH, UINT *puMaxSamples, DWORD *pdwMaxEpi, int *pnError ); /* BOOL WINAPI ABF_SetOverlap(int nFile, const ABFFileHeader *pFH, BOOL bAllowOverlap, int *pnError); BOOL WINAPI ABF_SetEpisodeStart(int nFile, UINT uEpisode, UINT uEpiStart, int *pnError); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void *WINAPI ABF_GetSynchArray(int nFile, int *pnError); BOOL WINAPI ABF_WriteAnnotation( int nFile, ABFFileHeader *pFH, LPCSTR pszText, int *pnError ); BOOL WINAPI ABF_ReadAnnotation( int nFile, const ABFFileHeader *pFH, DWORD dwIndex, LPSTR pszText, DWORD dwBufSize, int *pnError ); DWORD WINAPI ABF_GetMaxAnnotationSize( int nFile, const ABFFileHeader *pFH ); BOOL WINAPI ABF_WriteStringAnnotation( int nFile, ABFFileHeader *pFH, LPCSTR pszName, LPCSTR pszData, int *pnError ); BOOL WINAPI ABF_WriteIntegerAnnotation( int nFile, ABFFileHeader *pFH, LPCSTR pszName, int nData, int *pnError ); BOOL WINAPI ABF_ReadStringAnnotation( int nFile, const ABFFileHeader *pFH, DWORD dwIndex, LPSTR pszName, UINT uSizeName, LPSTR pszValue, UINT uSizeValue, int *pnError ); BOOL WINAPI ABF_ReadIntegerAnnotation( int nFile, const ABFFileHeader *pFH, DWORD dwIndex, LPSTR pszName, UINT uSizeName, int *pnValue, int *pnError ); BOOL WINAPI ABF_ParseStringAnnotation( LPCSTR pszAnn, LPSTR pszName, UINT uSizeName, LPSTR pszValue, UINT uSizeValue, int *pnError); BOOL WINAPI ABF_ValidateFileCRC( int nFile, int *pnError ); */ //=============================================================================================== // Macros and functions to deal with returning error return codes through a pointer if given. #define ERRORRETURN(p, e) return ErrorReturn(p, e); // BOOL ErrorReturn(int *pnError, int nErrorNum); //=============================================================================================== // FUNCTION: GetNewFileDescriptor // PURPOSE: Allocate a new file descriptor and return it. // #ifdef __cplusplus } #endif #endif // INC_ABFFILES_H stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/csynch.hpp0000775000175000017500000001303614750344764016656 //*********************************************************************************************** // // Copyright (c) 1993-1997 Axon Instruments. // All rights reserved. // //*********************************************************************************************** // HEADER: CSYNCH.HPP // PURPOSE: Contains cclass definition for CSynch for creating and maintaining a Synch array. // AUTHOR: BHI May 1994 // #ifndef INC_CSYNCH_HPP #define INC_CSYNCH_HPP #include "../Common/axodefn.h" #include "../Common/axodebug.h" //----------------------------------------------------------------------------------------------- // Local constants: #define SYNCH_BUFFER_SIZE 100 // buffer 100 synch entries at a time. // Synch structure definition. struct Synch { DWORD dwStart; DWORD dwLength; DWORD dwFileOffset; }; //----------------------------------------------------------------------------------------------- // CSynch class definition class CSynch { public: enum eMODE { eWRITEMODE, eREADMODE }; private: // Member variables. #if defined(_WINDOWS) && !defined(__MINGW32__) char m_szFileName[_MAX_PATH]; // Filename for array virtualization #endif FILEHANDLE m_hfSynchFile; // Handle to temporary file. eMODE m_eMode; // Mode flag for buffering algorithm. UINT m_uSynchCount; // Total count of entries in the synch array UINT m_uCacheCount; // Count of entries in the cache UINT m_uCacheStart; // Number of first entry in the cache. Synch m_SynchBuffer[SYNCH_BUFFER_SIZE]; // Buffer for caching synch entries. Synch m_LastEntry; // Last entry written (write only). private: // Declare but don't define copy constructor to prevent use of default CSynch(const CSynch &CS); const CSynch &operator=(const CSynch &CS); private: // Private member functions. void _Initialize(); BOOL _Flush(); /* BOOL _PackBuffer(UINT uAcquiredSamples, UINT &uEntries, UINT uSampleSize); // BOOL _Read(LPVOID lpBuf, DWORD dwBytesToRead); */ BOOL Read(LPVOID lpBuf, DWORD dwFilePos, DWORD dwEntriesToRead); BOOL _GetReadMode( UINT uFirstEntry, Synch *pSynch, UINT uEntries ); BOOL _GetWriteMode( UINT uFirstEntry, Synch *pSynch, UINT uEntries ); BOOL _IsFileOpen(); public: // Public member functions CSynch(); ~CSynch(); void Clone(CSynch *pCS); BOOL OpenFile(); void CloseFile(); void SetMode(eMODE eMode); BOOL Put( UINT uStart, UINT uLength, UINT uOffset=0 ); /* void UpdateLength( DWORD dwLength ); void IncreaseLastLength( DWORD dwIncrease ); BOOL GetLastEntry(Synch *pSynch); */ BOOL Get( UINT uFirstEntry, Synch *pSynch, UINT uEntries ); /* BOOL Update( UINT uEntry, const Synch *pSynch ); */ UINT GetCount() const; /* BOOL Write( HANDLE hDataFile, UINT uAcquiredSamples, UINT *puSynchCount, UINT uSampleSize ); */ }; //=============================================================================================== // PROCEDURE: GetCount // PURPOSE: Returns the current count of synch elements. // inline UINT CSynch::GetCount() const { // MEMBERASSERT(); return m_uSynchCount; } //=============================================================================================== // PROCEDURE: Read // PURPOSE: Reads a block and returns FALSE on ERROR. // inline BOOL CSynch::Read(LPVOID lpBuf, DWORD dwFirstEntry, DWORD dwEntriesToRead) { // MEMBERASSERT(); DWORD dwBytesToRead= dwEntriesToRead * sizeof(Synch); // ARRAYASSERT(LPSTR(lpBuf), dwBytesToRead); // Save the current file position and seek to the desired position. DWORD dwCurrentPos = c_SetFilePointer( m_hfSynchFile, 0, NULL, FILE_CURRENT ); if (dwCurrentPos == INVALID_SEEK_VALUE) return FALSE; c_SetFilePointer( m_hfSynchFile, dwFirstEntry * sizeof(Synch), NULL, FILE_BEGIN ); DWORD dwBytesRead = 0; BOOL bOK = c_ReadFile(m_hfSynchFile, lpBuf, dwBytesToRead, &dwBytesRead, NULL); // Restore the original file. c_SetFilePointer( m_hfSynchFile, dwCurrentPos, NULL, FILE_BEGIN ); // Debug error messages. if( !bOK ) { TRACE( (char*)"CSynch::Read - ReadFile failed");// with the following error:\n" ); // SHOW_SYSTEM_ERROR( GetLastError() ); } if( dwBytesRead != dwBytesToRead ) { // TRACE2( "CSynch::Read - error reading from file: dwBytesToRead %d, dwBytesRead %d.\n", // dwBytesToRead, dwBytesRead ); } return (bOK && (dwBytesRead==dwBytesToRead)); } //=============================================================================================== // PROCEDURE: Get // PURPOSE: Retrieves synch entries from the virtualized array. // inline BOOL CSynch::Get( UINT uFirstEntry, Synch *pSynch, UINT uEntries ) { // MEMBERASSERT(); // ASSERT(uEntries > 0); // ARRAYASSERT(pSynch, uEntries); // ASSERT(uFirstEntry+uEntries <= m_uSynchCount); if (m_eMode == eREADMODE) return _GetReadMode( uFirstEntry, pSynch, uEntries ); else return _GetWriteMode( uFirstEntry, pSynch, uEntries ); } //=============================================================================================== // PROCEDURE: _IsFileOpen // PURPOSE: Returns TRUE if the temp file was opened ok. // inline BOOL CSynch::_IsFileOpen() { return (m_hfSynchFile != FILE_NULL); } #endif // INC_CSYNCH_HPP stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/abfhwave.cpp0000775000175000017500000022672714750344764017162 //*********************************************************************************************** // // Copyright (c) 1993-2000 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // This is ABFHWAVE.CPP; a set of routines for returning the waveform from // an ABF header definition. // // An ANSI C compiler should be used for compilation. // Compile with the large memory model option. // (e.g. CL -c -AL ABFFILES.C) #include "../Common/wincpp.hpp" #include "abfheadr.h" /* #include "abfutil.h" #include "./../Common/ArrayPtr.hpp" #include "UserList.hpp" #include "PopulateEpoch.hpp" #define ERRORRETURN(p, e) return ErrorReturn(p, e); static BOOL ErrorReturn(int *pnError, int nErrorNum) { if (pnError) *pnError = nErrorNum; return FALSE; } */ //=============================================================================================== // FUNCTION: ABFH_GetChannelOffset // PURPOSE: Get the offset in the sampling sequence for the given physical channel. // BOOL WINAPI ABFH_GetChannelOffset(const ABFFileHeader *pFH, int nChannel, UINT *puChannelOffset) { // ABFH_ASSERT(pFH); // WPTRASSERT(puChannelOffset); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); int nOffset; // check the ADC channel number, -1 refers to the math channel if (nChannel < 0) { if (!FH.nArithmeticEnable) { if (puChannelOffset) *puChannelOffset = 0; // return the offset to this channel return FALSE; // channel not found in sampling sequence } nChannel = FH.nArithmeticADCNumA; } for (nOffset = 0; nOffset < FH.nADCNumChannels; nOffset++) { if (FH.nADCSamplingSeq[nOffset] == nChannel) { if (puChannelOffset) *puChannelOffset = UINT(nOffset); // return the offset to this channel return TRUE; } } if (puChannelOffset) *puChannelOffset = 0; // return the offset to this channel return FALSE; } /* //=============================================================================================== // FUNCTION: GetListEntry // PURPOSE: Gets the entry in the list that corresponds to the given episode number. // static LPSTR GetListEntry( const ABFFileHeader *pFH, UINT uListNum, UINT uEpisode, LPSTR szList, UINT uListSize ) { ABFH_ASSERT(pFH); ASSERT(uEpisode > 0); ASSERT(uListSize <= ABF_USERLISTLEN+1); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); // Turn the list field into an ASCIIZ string. strncpy(szList, FH.sULParamValueList[uListNum], uListSize-1); szList[uListSize-1] = '\0'; char *psItem = strtok(szList, ","); if (!psItem) { szList[0] = '\0'; psItem = szList; } else { for (UINT i=0; i= ABF_EPOCHINITDURATION) && (nEpoch == FH.nULParamToVary[uDACChannel] - ABF_EPOCHINITDURATION)) return GetIntegerEntry(pFH, uDACChannel, uEpisode); return FH.lEpochInitDuration[uDACChannel][nEpoch] + (int)(uEpisode-1) * FH.lEpochDurationInc[uDACChannel][nEpoch]; } //=============================================================================================== // FUNCTION: ABFH_GetEpochLevel // PURPOSE: Get the level of an Epoch that corresponds to the given episode number. // float WINAPI ABFH_GetEpochLevel(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); if (FH.nULEnable[uDACChannel] && (FH.nULParamToVary[uDACChannel] >= ABF_EPOCHINITLEVEL) && (FH.nULParamToVary[uDACChannel] < ABF_EPOCHINITDURATION) && (nEpoch == FH.nULParamToVary[uDACChannel] - ABF_EPOCHINITLEVEL)) return GetFloatEntry(pFH, uDACChannel, uEpisode); return FH.fEpochInitLevel[uDACChannel][nEpoch] + (uEpisode-1) * FH.fEpochLevelInc[uDACChannel][nEpoch]; } BOOL WINAPI ABFH_GetEpochLevelRange(const ABFFileHeader *pFH, UINT uDACChannel, int nEpoch, float *pfMin, float *pfMax) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); if (FH.nEpochType[uDACChannel][nEpoch] == ABF_EPOCHDISABLED ) { return FALSE; } if (FH.nULEnable[uDACChannel] && (FH.nULParamToVary[uDACChannel] >= ABF_EPOCHINITLEVEL) && (FH.nULParamToVary[uDACChannel] < ABF_EPOCHINITDURATION) && (nEpoch == FH.nULParamToVary[uDACChannel] - ABF_EPOCHINITLEVEL)) { *pfMin = 1e9; *pfMax = -1e9; // Iterate over all possible levels. // If lEpisodesPerRun less than number of user list values then only // check up to lEpisodesPerRun user list values. CUserList UserList; UserList.Initialize( &FH, uDACChannel ); UINT uListEntries = UserList.GetNumEntries(); int nCount = min( FH.lEpisodesPerRun, (int)uListEntries ); for ( int n = 0; n= ABF_PARALLELVALUE) && (FH.nULParamToVary[uListNum] < ABF_EPOCHINITLEVEL) && (nEpoch == FH.nULParamToVary[uListNum] - ABF_PARALLELVALUE)) { CUserList UL; UL.Initialize( &FH, uListNum ); UserListItem ULitem = UL.GetItem( uEpisode, NULL ); return ULitem.n; } if( uDigitalChannel == (UINT)FH.nActiveDACChannel ) return FH.nDigitalValue[nEpoch]; else return FH.nAlternateDigitalValue[nEpoch]; } //=============================================================================================== // FUNCTION: GetDigitalTrainEpochLevel // PURPOSE: Get the level of a digital Epoch that corresponds to the given episode number. // static DWORD GetDigitalTrainEpochLevel(const ABFFileHeader *pFH, UINT uEpisode, int nEpoch, UINT uDigitalChannel) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); UINT uListNum = FH.nActiveDACChannel; if (FH.nULEnable[uListNum] && (FH.nULParamToVary[uListNum] >= ABF_PARALLELVALUE) && (FH.nULParamToVary[uListNum] < ABF_EPOCHINITLEVEL) && (nEpoch == FH.nULParamToVary[uListNum] - ABF_PARALLELVALUE)) { CUserList UL; UL.Initialize( &FH, uListNum ); UserListItem ULitem = UL.GetDigitalTrainItem( uEpisode, NULL ); return ULitem.n; } if( uDigitalChannel == (UINT)FH.nActiveDACChannel ) return FH.nDigitalTrainValue[nEpoch]; else return FH.nAlternateDigitalTrainValue[nEpoch]; } //=============================================================================================== // FUNCTION: GetPostTrainPeriod // PURPOSE: Get the post train period. // static float GetPostTrainPeriod(const ABFFileHeader *pFH, UINT uDAC, UINT uEpisode) { ABFH_ASSERT(pFH); ASSERT( uDAC < ABF_WAVEFORMCOUNT ); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); if (FH.nULEnable[uDAC] && (FH.nULParamToVary[uDAC] == ABF_CONDITPOSTTRAINDURATION)) return GetFloatEntry(pFH, uDAC, uEpisode); return FH.fPostTrainPeriod[uDAC]; } //=============================================================================================== // FUNCTION: GetPostTrainLevel // PURPOSE: Get the post train level. // static float GetPostTrainLevel(const ABFFileHeader *pFH, UINT uDAC, UINT uEpisode) { ABFH_ASSERT(pFH); ASSERT( uDAC < ABF_WAVEFORMCOUNT ); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); if (FH.nULEnable[uDAC] && (FH.nULParamToVary[uDAC] == ABF_CONDITPOSTTRAINLEVEL)) return GetFloatEntry(pFH, uDAC, uEpisode); return FH.fPostTrainLevel[uDAC]; } //=============================================================================================== // FUNCTION: GetEpochTrainPeriod // PURPOSE: Get the train period of an Epoch that corresponds to the given episode number. // static int GetEpochTrainPeriod(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); if (FH.nULEnable[uDACChannel] && (FH.nActiveDACChannel == (int)uDACChannel) && // User list must be active channel at present. (FH.nULParamToVary[uDACChannel] >= ABF_EPOCHTRAINPERIOD) && (FH.nULParamToVary[uDACChannel] < ABF_EPOCHTRAINPULSEWIDTH) && (nEpoch == FH.nULParamToVary[uDACChannel] - ABF_EPOCHTRAINPERIOD)) { CUserList UL; UL.Initialize( &FH, uDACChannel ); return UL.GetItem( uEpisode, NULL ).n; } return (int)FH.lEpochPulsePeriod[uDACChannel][nEpoch]; } //=============================================================================================== // FUNCTION: GetEpochTrainPulseWidth // PURPOSE: Get the train pulse width of an Epoch that corresponds to the given episode number. // static int GetEpochTrainPulseWidth(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); if (FH.nULEnable[uDACChannel] && (FH.nActiveDACChannel == (int)uDACChannel) && // User list must be active channel at present. (FH.nULParamToVary[uDACChannel] >= ABF_EPOCHTRAINPULSEWIDTH) && (FH.nULParamToVary[uDACChannel] < ABF_EPOCHTRAINPULSEWIDTH + ABF_EPOCHCOUNT) && (nEpoch == FH.nULParamToVary[uDACChannel] - ABF_EPOCHTRAINPULSEWIDTH)) { CUserList UL; UL.Initialize( &FH, uDACChannel ); return UL.GetItem( uEpisode, NULL ).n; } return (int)FH.lEpochPulseWidth[uDACChannel][nEpoch]; } //=============================================================================================== // FUNCTION: GetHoldingLength // PURPOSE: Get the duration of the first/last holding period. // static int _GetHoldingLength(int nSweepLength, int nNumChannels) { ASSERT((nSweepLength % nNumChannels)==0); // Calculate holding count. int nHoldingCount = nSweepLength / ABFH_HOLDINGFRACTION; // Round down to nearest sequence length. nHoldingCount -= nHoldingCount % nNumChannels; // If less than one sequence, round up to one sequence. if (nHoldingCount < nNumChannels) nHoldingCount = nNumChannels; return nHoldingCount; } //=============================================================================================== // FUNCTION: ABFH_GetHoldingDuration // PURPOSE: Get the duration of the first holding period. // UINT WINAPI ABFH_GetHoldingDuration(const ABFFileHeader *pFH) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); // Only waveform files have first/last holding points. if( !FH.nWaveformEnable[0] && !FH.nWaveformEnable[1] && (FH.nWaveformSource[0] == ABF_WAVEFORMDISABLED) && (FH.nWaveformSource[1] == ABF_WAVEFORMDISABLED) && !FH.nDigitalEnable ) return 0; // Old data files used a different number of holding points. if (FH.nFileType == ABF_CLAMPEX) return 6 * (UINT)(FH.lNumSamplesPerEpisode / 512L); return _GetHoldingLength(FH.lNumSamplesPerEpisode, FH.nADCNumChannels); } //=============================================================================================== // FUNCTION: ABFH_SweepLenFromUserLen // PURPOSE: Get the full sweep length given the length available to epochs. // int WINAPI ABFH_SweepLenFromUserLen(int nUserLength, int nNumChannels) { ASSERT((nUserLength % nNumChannels)==0); // UserLen = SweepLen - 2 * HoldingLen // where HoldingLen = SweepLen/64 rounded to nearest sequence. // => UserLen = SweepLen * (1 - 2/64) // => UserLen = SweepLen * (31/32) // => SweepLen = UserLen * (32/31) // But this may not be exact because of the rounding of the holding level, // hence the iterative solution below: // We will start with the user length and keep adding sequence lengths until we get to // the sweep length that corresponds. int nSweepLength = nUserLength; while (ABFH_UserLenFromSweepLen(nSweepLength, nNumChannels) < nUserLength) nSweepLength += nNumChannels; return nSweepLength; } //=============================================================================================== // FUNCTION: ABFH_UserLenFromSweepLen // PURPOSE: Get the length available to epochs given the full sweep length. // int WINAPI ABFH_UserLenFromSweepLen(int nSweepLength, int nNumChannels) { ASSERT((nSweepLength % nNumChannels)==0); // UserLen = SweepLen - 2 * HoldingLen // where HoldingLen = SweepLen/64 rounded to nearest sequence. // Calculate holding count. int nHoldingCount = _GetHoldingLength(nSweepLength, nNumChannels); ASSERT(nSweepLength > nHoldingCount * 2); return nSweepLength - nHoldingCount * 2; } //=============================================================================================== // FUNCTION: GetHoldingLevel // PURPOSE: Calculate the holding level for this episode, allowing for user lists, // presweep pulses and "use last epoch" holding strategies. // static float GetHoldingLevel(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode) { ABFH_ASSERT(pFH); ASSERT( uDACChannel < ABF_WAVEFORMCOUNT ); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); float fCurrentHolding = FH.fDACHoldingLevel[uDACChannel]; if (FH.nConditEnable[uDACChannel]) { if (GetPostTrainPeriod(pFH, uDACChannel, uEpisode) > 0.0F) return GetPostTrainLevel(pFH, uDACChannel, uEpisode); else return fCurrentHolding; } if (!FH.nInterEpisodeLevel[uDACChannel]) return fCurrentHolding; int i; for (i=ABF_EPOCHCOUNT-1; i>=0; i--) if (FH.nEpochType[uDACChannel][i]) break; if ((i < 0) || (uEpisode < 2)) return fCurrentHolding; return ABFH_GetEpochLevel(pFH, uDACChannel, uEpisode-1, i); } //=============================================================================================== // FUNCTION: GetDigitalHoldingLevel // PURPOSE: Calculate the digital holding level for this episode, allowing for user lists, // and "use last epoch" holding strategies. // static UINT GetDigitalHoldingLevel(const ABFFileHeader *pFH, UINT uEpisode) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); UINT uCurrentHolding = FH.nDigitalHolding; UINT uListNum = FH.nActiveDACChannel; if (FH.nULEnable[uListNum] && (FH.nULParamToVary[uListNum] == ABF_DIGITALHOLDING)) uCurrentHolding = GetBinaryEntry(pFH, uListNum, uEpisode); if (!FH.nDigitalInterEpisode) return uCurrentHolding; int i=0; for (i=ABF_EPOCHCOUNT-1; i>=0; i--) if (FH.nEpochType[uListNum][i]) break; if ((i < 0) || (uEpisode < 2)) return uCurrentHolding; return GetDigitalEpochLevel(pFH, uEpisode-1, i, FH.nActiveDACChannel); } //=============================================================================================== // FUNCTION: ABFH_GetEpochLimits // PURPOSE: Return the bounds of a given epoch in a given episode. // Values returned are ZERO relative. // BOOL WINAPI ABFH_GetEpochLimits(const ABFFileHeader *pFH, int nADCChannel, DWORD dwEpisode, int nEpoch, UINT *puEpochStart, UINT *puEpochEnd, int *pnError) { return ABFH_GetEpochLimitsEx(pFH, nADCChannel, pFH->nActiveDACChannel, dwEpisode, nEpoch, puEpochStart, puEpochEnd, pnError); } BOOL WINAPI ABFH_GetEpochLimitsEx(const ABFFileHeader *pFH, int nADCChannel, UINT uDACChannel, DWORD dwEpisode, int nEpoch, UINT *puEpochStart, UINT *puEpochEnd, int *pnError) { ABFH_ASSERT(pFH); WPTRASSERT(puEpochStart); WPTRASSERT(puEpochEnd); ASSERT(dwEpisode > 0); if( pFH->nOperationMode != ABF_WAVEFORMFILE ) ERRORRETURN(pnError, ABFH_ENOWAVEFORM); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); if ((nADCChannel < 0) && (NewFH.nArithmeticEnable != 0)) nADCChannel = NewFH.nArithmeticADCNumA; UINT uChannelOffset; if (!ABFH_GetChannelOffset(&NewFH, nADCChannel, &uChannelOffset)) ERRORRETURN(pnError, ABFH_CHANNELNOTSAMPLED); if (NewFH.nWaveformSource[uDACChannel] == ABF_WAVEFORMDISABLED) ERRORRETURN(pnError, ABFH_EPOCHNOTPRESENT); UINT uHoldingDuration = ABFH_GetHoldingDuration(&NewFH); int nEpochStart, nEpochEnd; if (nEpoch == ABFH_FIRSTHOLDING) { if (uChannelOffset >= uHoldingDuration) ERRORRETURN(pnError, ABFH_EPOCHNOTPRESENT); nEpochStart = 0; nEpochEnd = uHoldingDuration - 1; } else { if ((nEpoch!=ABFH_LASTHOLDING) && (!NewFH.nEpochType[uDACChannel][nEpoch])) ERRORRETURN(pnError, ABFH_EPOCHNOTPRESENT); nEpochStart = uHoldingDuration; int nEpochDuration = 0; for (int i=0; i<=nEpoch; i++) { if (!NewFH.nEpochType[uDACChannel][i]) { nEpochDuration = 0; continue; } nEpochDuration = ABFH_GetEpochDuration(&NewFH, uDACChannel, dwEpisode, i); nEpochDuration *= NewFH.nADCNumChannels; nEpochDuration = max(nEpochDuration, 0); if (i == nEpoch) break; nEpochStart += nEpochDuration; } if (nEpoch == ABFH_LASTHOLDING) nEpochEnd = (UINT)NewFH.lNumSamplesPerEpisode - 1; else if( nEpochDuration > 0 ) nEpochEnd = nEpochStart + nEpochDuration - 1; else nEpochEnd = nEpochStart; } *puEpochStart = (UINT)(nEpochStart / NewFH.nADCNumChannels); *puEpochEnd = (UINT)(nEpochEnd / NewFH.nADCNumChannels); if (*puEpochEnd < *puEpochStart) ERRORRETURN(pnError, ABFH_EPOCHNOTPRESENT); return TRUE; } //=============================================================================================== // FUNCTION: GenerateWaveform // PURPOSE: Build the waveform as an array of UU floats. // static BOOL GenerateWaveform(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, float *pfBuffer) { ABFH_ASSERT(pFH); WARRAYASSERT(pfBuffer, (UINT)pFH->lNumSamplesPerEpisode); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); UINT uHoldingDuration = ABFH_GetHoldingDuration(pFH); double dHoldingLevel = GetHoldingLevel(pFH, uDACChannel, uEpisode); double dLevel = dHoldingLevel; double dStartLevel = dHoldingLevel; int nDuration = 0; bool bSetToHolding = false; // Set every other episode to holding if we are in alternating DAC episodic mode if (FH.nAlternateDACOutputState != 0) { if( uEpisode % 2 == 0 && uDACChannel == 0 ) bSetToHolding = true; else if( uEpisode % 2 != 0 && uDACChannel == 1 ) bSetToHolding = true; } // If this sweep is not included in protocol (i.e. sweeps // added in off-line analysis), simply fill with holding level. if( uEpisode > (UINT)FH.lEpisodesPerRun ) { for( int nSample = 0; nSample < FH.lNumSamplesPerEpisode; nSample++ ) *pfBuffer++ = (float)dHoldingLevel; return TRUE; } // Populate the first holding with the holding level int nPoints = uHoldingDuration; for (int nSample = 0; nSample < (int)uHoldingDuration; nSample++) *pfBuffer++ = (float)dHoldingLevel; int nEndHolding = (UINT)FH.lNumSamplesPerEpisode - uHoldingDuration; // Reconstruct all epochs for (int nEpoch = 0; nEpoch < ABF_EPOCHCOUNT; nEpoch++) { if (FH.nEpochType[uDACChannel][nEpoch] == ABF_EPOCHDISABLED ) continue; nDuration = ABFH_GetEpochDuration(pFH, uDACChannel, uEpisode, nEpoch) * FH.nADCNumChannels; if ( nDuration <= 0 ) continue; dLevel = ABFH_GetEpochLevel(pFH, uDACChannel, uEpisode, nEpoch); int nPeriod = GetEpochTrainPeriod( pFH, uDACChannel, uEpisode, nEpoch ) * FH.nADCNumChannels; int nWidth = GetEpochTrainPulseWidth( pFH, uDACChannel, uEpisode, nEpoch ) * FH.nADCNumChannels; nPoints += nDuration; if( nPoints > (int)FH.lNumSamplesPerEpisode ) return FALSE; // Allocate doubles to build the waveform double * pdValue = new double[nDuration]; WARRAYASSERT(pdValue, (UINT)nDuration); // Set to holding if alternating if( bSetToHolding ) { PopulateStep( nDuration, dHoldingLevel, pdValue ); } else { // Build the appropriate waveform switch (FH.nEpochType[uDACChannel][nEpoch]) { case ABF_EPOCHDISABLED: break; case ABF_EPOCHSTEPPED: PopulateStep( nDuration, dLevel, pdValue ); break; case ABF_EPOCHRAMPED: PopulateRamp( nDuration, dStartLevel, dLevel, pdValue ); break; case ABF_EPOCH_TYPE_RECTANGLE: PopulateRectangle( nDuration, dStartLevel, dLevel, nPeriod, nWidth, pdValue ); break; case ABF_EPOCH_TYPE_BIPHASIC: PopulateBiphasic( nDuration, dStartLevel, dLevel, nPeriod, nWidth, pdValue ); break; case ABF_EPOCH_TYPE_TRIANGLE: PopulateTriangle( nDuration, dStartLevel, dLevel, nPeriod, nWidth, pdValue ); break; case ABF_EPOCH_TYPE_COSINE: PopulateCosine( nDuration, dStartLevel, dLevel, nPeriod, pdValue ); break; case ABF_EPOCH_TYPE_RESISTANCE: PopulateResistance( nDuration, dLevel, dHoldingLevel, pdValue ); break; } } // Fill buffer with floats (from double) for ( int nSample = 0; nSample < nDuration; nSample++) *pfBuffer++ = (float)pdValue[nSample]; delete [] pdValue; dStartLevel = dLevel; nEndHolding -= nDuration; } if (!FH.nInterEpisodeLevel[uDACChannel]) dStartLevel = FH.fDACHoldingLevel[uDACChannel]; nPoints += nEndHolding; if( nPoints > (int)FH.lNumSamplesPerEpisode ) return FALSE; // Populate the last holding with the holding level for(int nSample = 0; nSample < nEndHolding; nSample++) *pfBuffer++ = (float)dStartLevel; return TRUE; } //=============================================================================================== // FUNCTION: GenerateDigitalWaveform // PURPOSE: Build the waveform as an array of DWORDs. // static void GenerateDigitalWaveform(const ABFFileHeader *pFH, UINT uEpisode, DWORD *pdwBuffer) { ABFH_ASSERT(pFH); ARRAYASSERT(pdwBuffer, (UINT)pFH->lNumSamplesPerEpisode); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); UINT uHoldingDuration = ABFH_GetHoldingDuration(pFH); UINT uHoldingLevel = GetDigitalHoldingLevel(pFH, uEpisode); UINT uEpochLevel = uHoldingLevel; UINT uDigitalTrainLevel = uHoldingLevel; long nPeriod = 0; long nWidth = 0; long nEndOfLastPulse = 0; // If this sweep is not included in protocol (i.e. sweeps added in off-line analysis), // simply fill with holding level. if( uEpisode > (UINT)FH.lEpisodesPerRun ) { for(int j=0; j 0 && uDigitalTrainLevel > 0 && uEpochDuration > 0; if( bDigitalTrains ) { nPeriod = GetEpochTrainPeriod( pFH, uDigitalChannel, uEpisode, uEpoch ) * FH.nADCNumChannels; nWidth = GetEpochTrainPulseWidth( pFH, uDigitalChannel, uEpisode, uEpoch ) * FH.nADCNumChannels; nEndOfLastPulse = uEpochDuration; // This if statement should only be accessed if digital trains are enabled. // nPeriod == 0 is not valid. ASSERT( nPeriod > 0 ); long nSample = 0; // Fill as many pulses as we can for ( nSample = 0; nSample < nEndOfLastPulse; ++nSample) { DWORD dwValue; if ((nSample % nPeriod) < nWidth) { // Invert the logic of the digital train if the Active High Logic is not selected, if( FH.nDigitalTrainActiveLogic ) dwValue = uDigitalTrainLevel | uEpochLevel; else dwValue = uHoldingLevel | uEpochLevel; } else { // Invert the logic of the digital train if the Active High Logic is not selected, if( FH.nDigitalTrainActiveLogic ) dwValue = uHoldingLevel | uEpochLevel; else dwValue = uDigitalTrainLevel | uEpochLevel; } *pdwBuffer++ = dwValue; } uEndHolding -= uEpochDuration; } else { for (UINT j=0; jlNumSamplesPerEpisode*uElementSize); ARRAYASSERT(pbyDest, (UINT)(pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels)*uElementSize); UINT uNumSamples = (UINT)pFH->lNumSamplesPerEpisode; UINT uSkip = pFH->nADCNumChannels; // Set the source pointer to the first item. pbySrce += (uChannelOffset * uElementSize); // Loop through the source array picking out the items that // correspond to the given channel. for (UINT i=uChannelOffset; i FH.lNumSamplesPerEpisode / FH.nADCNumChannels (floats) // BOOL WINAPI ABFH_GetWaveform( const ABFFileHeader *pFH, int nADCChannel, DWORD dwEpisode, float *pfBuffer, int *pnError) { // Note: we now ignore the nADCChannel parameter. return ABFH_GetWaveformEx( pFH, pFH->nActiveDACChannel, dwEpisode, pfBuffer, pnError); } BOOL WINAPI ABFH_GetWaveformEx( const ABFFileHeader *pFH, UINT uDACChannel, DWORD dwEpisode, float *pfBuffer, int *pnError) { // Check that the buffer is as large as it should be. ARRAYASSERT(pfBuffer, UINT(pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels)); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); if (dwEpisode > (DWORD)NewFH.lActualEpisodes) ERRORRETURN(pnError, ABFH_ENOWAVEFORM); if( !NewFH.nWaveformEnable[uDACChannel] || (NewFH.nWaveformSource[uDACChannel] == ABF_WAVEFORMDISABLED) ) ERRORRETURN(pnError, ABFH_ENOWAVEFORM); if (NewFH.nWaveformSource[uDACChannel] == ABF_DACFILEWAVEFORM) ERRORRETURN(pnError, ABFH_EDACFILEWAVEFORM); if (NewFH.nADCNumChannels == 1) { if( !GenerateWaveform(&NewFH, uDACChannel, dwEpisode, pfBuffer) ) ERRORRETURN(pnError, ABFH_EBADWAVEFORM); } else { CArrayPtr pfWorkBuffer(NewFH.lNumSamplesPerEpisode); if (!pfWorkBuffer) ERRORRETURN(pnError, ABFH_ENOMEMORY); if( !GenerateWaveform(&NewFH, uDACChannel, dwEpisode, pfWorkBuffer) ) ERRORRETURN(pnError, ABFH_EBADWAVEFORM); GetChannelEntries(&NewFH, 0, pfBuffer, pfWorkBuffer, sizeof(*pfBuffer)); } return TRUE; } //=============================================================================================== // FUNCTION: ABFH_GetDigitalWaveform // PURPOSE: This function forms the de-multiplexed Digital output waveform for the // particular channel in the pdwBuffer, as a bit mask. Digital OUT 0 is in bit 0. // // The required size of the passed buffer is: // pdwBuffer -> FH.lNumSamplesPerEpisode / FH.nADCNumChannels (floats) // BOOL WINAPI ABFH_GetDigitalWaveform( const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, DWORD *pdwBuffer, int *pnError) { ABFH_ASSERT(pFH); // Check that the buffer is as large as it should be. ARRAYASSERT(pdwBuffer, UINT(pFH->lNumSamplesPerEpisode/pFH->nADCNumChannels)); UINT uChannelOffset = 0; if (dwEpisode > (DWORD)pFH->lActualEpisodes) ERRORRETURN(pnError, ABFH_ENOWAVEFORM); if (!ABFH_GetChannelOffset(pFH, nChannel, &uChannelOffset)) ERRORRETURN(pnError, ABFH_CHANNELNOTSAMPLED); if (pFH->nDigitalEnable == FALSE) ERRORRETURN(pnError, ABFH_ENOWAVEFORM); if (pFH->nADCNumChannels == 1) GenerateDigitalWaveform(pFH, dwEpisode, pdwBuffer); else { CArrayPtr pdwWorkBuffer(pFH->lNumSamplesPerEpisode); if (!pdwWorkBuffer) ERRORRETURN(pnError, ABFH_ENOMEMORY); GenerateDigitalWaveform(pFH, dwEpisode, pdwWorkBuffer); GetChannelEntries(pFH, uChannelOffset, pdwBuffer, pdwWorkBuffer, sizeof(*pdwBuffer)); } return TRUE; } //=============================================================================================== // FUNCTION: ABFH_GetWaveformVector // PURPOSE: Returns vector pairs for displaying a waveform made up of epochs. // The clipping limits are PER CHANNEL sample numbers. // BOOL WINAPI ABFH_GetWaveformVector(const ABFFileHeader *pFH, UINT uDACChannel, DWORD dwEpisode, UINT uStart, UINT uFinish, float *pfLevels, float *pfTimes, int *pnVectors, int *pnError) { ABFH_ASSERT(pFH); ERRORMSG("This function has not been implemented as yet."); ERRORRETURN(pnError, ABFH_ENOWAVEFORM); } // This function is no longer supported. #if 0 BOOL WINAPI ABFH_GetWaveformVector(const ABFFileHeader *pFH, DWORD dwEpisode, UINT uStart, UINT uFinish, float *pfLevels, float *pfTimes, int *pnVectors, int *pnError) { ABFH_ASSERT(pFH); WPTRASSERT(pnVectors); ARRAYASSERT(pfLevels, ABFH_MAXVECTORS); ARRAYASSERT(pfTimes, ABFH_MAXVECTORS); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); int i = 0; int j = 0; if( !NewFH.nWaveformEnable[uDACChannel] || (NewFH.nWaveformSource[uDACChannel] == ABF_WAVEFORMDISABLED) || (dwEpisode > (DWORD)NewFH.lActualEpisodes) ) ERRORRETURN(pnError, ABFH_ENOWAVEFORM); if (NewFH.nWaveformSource[uDACChannel] != ABF_EPOCHTABLEWAVEFORM) ERRORRETURN(pnError, ABFH_EDACFILEWAVEFORM); // First build the waveform vectors in terms of samples. int nHere = 0; float *pfL = pfLevels; float *pfT = pfTimes; UINT uHoldingDuration = ABFH_GetHoldingDuration(&NewFH); float fHoldingLevel = GetHoldingLevel(&NewFH, uDACChannel, dwEpisode); *pfL++ = fHoldingLevel; *pfT++ = (float)nHere; *pfL++ = fHoldingLevel; *pfT++ = (float)(nHere+=uHoldingDuration); int nEndHolding = (UINT)NewFH.lNumSamplesPerEpisode - uHoldingDuration; float fEpochLevel = 0.0F; for (i=0; i= uStart) break; } if (i==nVectors) { *pnVectors = 0; return TRUE; } if (i > 0) { float fLevel = (pfLevels[i] - pfLevels[i-1]) / (pfTimes[i] - pfTimes[i-1]); fLevel *= uStart - pfTimes[i]; fLevel += pfLevels[i]; pfL = pfLevels; pfT = pfTimes; i--; pfTimes[0] = (float)uStart; pfLevels[0] = fLevel; for (j=1; j= uFinish) break; } if (i uClockChange) break; } if ((i < nVectors) && (pfTimes[i-1] < uClockChange)) { float fLevel = (pfLevels[i] - pfLevels[i-1]) / (pfTimes[i] - pfTimes[i-1]); fLevel *= uClockChange - pfTimes[i]; fLevel += pfLevels[i]; for (j=nVectors; j>i; j--) { pfTimes[j] = pfTimes[j-1]; pfLevels[j] = pfLevels[j-1]; } pfTimes[i] = (float)uClockChange; pfLevels[i] = fLevel; nVectors++; } } // return the number of vectors generated. *pnVectors = nVectors; // Convert samples to time offsets. float fTimeInc = NewFH.fADCSampleInterval / 1E3F; for (i=0; i uClockChange)) break; pfTimes[i] = (fSample - uHoldingDuration) * fTimeInc; } if (i < nVectors) { float fSplitTime = (uClockChange - uHoldingDuration) * fTimeInc; fTimeInc = NewFH.fADCSecondSampleInterval / 1E3F; for (j=i; j void GetTimebase(const ABFFileHeader *pFH, T TimeOffset, T *pBuffer, UINT uBufferSize); template void GetTimebase(const ABFFileHeader *pFH, T TimeOffset, T *pBuffer, UINT uBufferSize) { ABFH_ASSERT(pFH); ARRAYASSERT(pBuffer, uBufferSize); UINT i, j; UINT uSamplesPerSweep = UINT(pFH->lNumSamplesPerEpisode); UINT uClockChange = ABFH_GetClockChange(pFH); double dTime = (T)TimeOffset; double dTimeInc = ABFH_GetFirstSampleInterval(pFH) * pFH->nADCNumChannels; dTimeInc = dTimeInc / 1E3; for (i=0; inADCNumChannels) { if (i >= uClockChange) break; if (uBufferSize-- == 0) return; *pBuffer++ = (T)dTime; dTime += dTimeInc; } if (i < uSamplesPerSweep) { dTimeInc = ABFH_GetSecondSampleInterval(pFH) * pFH->nADCNumChannels; dTimeInc = dTimeInc / 1E3; for (j=i; jnADCNumChannels) { if (uBufferSize-- == 0) return; *pBuffer++ = (T)dTime; dTime += dTimeInc; } } } //=============================================================================================== // FUNCTION: ABFH_GetTimebase // PURPOSE: Calculates the timebase array for the file. // void WINAPI ABFH_GetTimebase(const ABFFileHeader *pFH, float fTimeOffset, float *pfBuffer, UINT uBufferSize) { GetTimebase( pFH, fTimeOffset, pfBuffer, uBufferSize ); } //=============================================================================================== // FUNCTION: ABFH_GetTimebaseEx // PURPOSE: Calculates the timebase array (in doubles) for the file. // void WINAPI ABFH_GetTimebaseEx(const ABFFileHeader *pFH, double dTimeOffset, double *pdBuffer, UINT uBufferSize) { GetTimebase( pFH, dTimeOffset, pdBuffer, uBufferSize ); } //============================================================================================== // FUNCTION: ABFH_GetNumberOfChangingSweeps // PURPOSE: Count the number of changing sweeps. // In waveform preview we restrict the number of displayed sweeps // to the number of changing sweeps so as to decrease redraw time. // UINT WINAPI ABFH_GetNumberOfChangingSweeps( const ABFFileHeader *pFH ) { ABFH_ASSERT(pFH); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); UINT uNumChangingSweeps = 1; UINT uMaxChangingSweeps = 1; UINT uNumEpisodes = NewFH.lEpisodesPerRun; if( uNumEpisodes > 1 ) { for( int nDAC = 0; nDAC < ABF_WAVEFORMCOUNT; nDAC++ ) { // Just two sweeps change if alternating output is set if( NewFH.nAlternateDACOutputState || NewFH.nAlternateDigitalOutputState ) uNumChangingSweeps = 2; // Get number of entries of user list if( NewFH.nULEnable[ nDAC ] ) { CUserList UserList; UserList.Initialize( &NewFH, nDAC ); UINT uListEntries = UserList.GetNumEntries(); ASSERT( uListEntries > 0 ); if( uListEntries > uNumChangingSweeps ) uNumChangingSweeps = min(uListEntries, uNumEpisodes ); } // All sweeps are assumed to change if increments are set for( int nEpoch = 0; nEpoch < ABF_EPOCHCOUNT; nEpoch++ ) { if( (NewFH.fEpochLevelInc[ nDAC ][ nEpoch ] != 0.0F) || (NewFH.lEpochDurationInc[ nDAC ][ nEpoch ] != 0) ) { uNumChangingSweeps = NewFH.lEpisodesPerRun; } } uMaxChangingSweeps = max(uMaxChangingSweeps, uNumChangingSweeps); } } return uMaxChangingSweeps; } //=============================================================================================== // FUNCTION: ABFH_IsConstantWaveform // PURPOSE: Checks whether the waveform varies from episode to episode. // BOOL WINAPI ABFH_IsConstantWaveform(const ABFFileHeader *pFH) { return ABFH_IsConstantWaveformEx(pFH, pFH->nActiveDACChannel); } BOOL WINAPI ABFH_IsConstantWaveformEx(const ABFFileHeader *pFH, UINT uDACChannel) { ABFH_ASSERT(pFH); ASSERT( uDACChannel < ABF_WAVEFORMCOUNT ); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); int i=0; if( !NewFH.nWaveformEnable[uDACChannel] || NewFH.nWaveformSource[uDACChannel] == ABF_WAVEFORMDISABLED) return TRUE; if (NewFH.nWaveformSource[uDACChannel] == ABF_DACFILEWAVEFORM) return ( NewFH.lDACFileNumEpisodes[uDACChannel] == 1 ); if (NewFH.nConditEnable[uDACChannel] && NewFH.nULEnable[uDACChannel]) { if ((NewFH.nULParamToVary[uDACChannel] == ABF_CONDITPOSTTRAINLEVEL) && (NewFH.fPostTrainPeriod[uDACChannel] > 0.0F)) return FALSE; if (NewFH.nULParamToVary[uDACChannel] == ABF_CONDITPOSTTRAINDURATION) return FALSE; if ((NewFH.nULParamToVary[uDACChannel] == ABF_CONDITSTEPLEVEL) && (NewFH.fPostTrainPeriod[uDACChannel] == 0.0F)) return FALSE; } for (i=0; i= ABF_EPOCHINITLEVEL) && (NewFH.nULParamToVary[uDACChannel] < ABF_EPOCHINITDURATION) && (i == NewFH.nULParamToVary[uDACChannel] - ABF_EPOCHINITLEVEL)) return FALSE; if (NewFH.nULEnable[uDACChannel] && (NewFH.nULParamToVary[uDACChannel] >= ABF_EPOCHINITDURATION) && (i == NewFH.nULParamToVary[uDACChannel] - ABF_EPOCHINITDURATION)) return FALSE; if (NewFH.nULEnable[uDACChannel] && (NewFH.nULParamToVary[uDACChannel] >= ABF_EPOCHTRAINPERIOD) && (i == NewFH.nULParamToVary[uDACChannel] - ABF_EPOCHTRAINPERIOD)) return FALSE; if (NewFH.nULEnable[uDACChannel] && (NewFH.nULParamToVary[uDACChannel] >= ABF_EPOCHTRAINPULSEWIDTH) && (i == NewFH.nULParamToVary[uDACChannel] - ABF_EPOCHTRAINPULSEWIDTH)) return FALSE; if (NewFH.fEpochLevelInc[uDACChannel][i] != 0.0F) return FALSE; if (NewFH.lEpochDurationInc[uDACChannel][i] != 0) return FALSE; } if( NewFH.nAlternateDACOutputState ) return FALSE; return TRUE; } //=============================================================================================== // FUNCTION: ABFH_IsConstantDigitalOutput // PURPOSE: Checks whether the waveform varies from episode to episode. // BOOL WINAPI ABFH_IsConstantDigitalOutput(const ABFFileHeader *pFH) { return ABFH_IsConstantDigitalOutputEx(pFH, pFH->nActiveDACChannel); } BOOL WINAPI ABFH_IsConstantDigitalOutputEx(const ABFFileHeader *pFH, UINT uDACChannel) { ABFH_ASSERT(pFH); ASSERT( uDACChannel < ABF_WAVEFORMCOUNT ); // Take a copy of the passed in header to ensure it is 6k long. ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); int i=0; if( !(NewFH.nDigitalEnable) || NewFH.nWaveformSource[uDACChannel] == ABF_WAVEFORMDISABLED) return TRUE; if (NewFH.nWaveformSource[uDACChannel] == ABF_DACFILEWAVEFORM) return ( NewFH.lDACFileNumEpisodes[uDACChannel] == 1 ); for (i=0; i= ABF_EPOCHINITDURATION) && (i == NewFH.nULParamToVary[uDACChannel] - ABF_EPOCHINITDURATION)) return FALSE; if (NewFH.lEpochDurationInc[uDACChannel][i] != 0) return FALSE; } if( NewFH.nAlternateDigitalOutputState ) return FALSE; return TRUE; } //============================================================================================== // FUNCTION: _IsMultipleOf // PURPOSE: Determines whether a number is a multiple of another number. // static BOOL _IsMultipleOf(double dSampleInterval, double dGranularity) { double dDelta = fmod(dSampleInterval, dGranularity); if (dDelta > dGranularity/2) dDelta -= dGranularity; double dCompare = max(dSampleInterval, dGranularity)/1E6; return (fabs(dDelta) < dCompare); } //============================================================================================== // FUNCTION: _Granularity // PURPOSE: Returns the granularity at the given interval. // static double _Granularity(double dSampleInterval, float fClockResolution) { // If less than 20us allow full board resolution. // >20us but <=200us must be multiple of 5us. // >200us but <=400us must be multiple of 10us. // >400us must be multiple of 20us. // This assumes that the digitizer resolution is at least 0.5us if (dSampleInterval < 20.0) return fClockResolution; if (dSampleInterval < 200.0) return 5.0; if (dSampleInterval < 400.0) return 10.0; return 20.0; } //============================================================================================== // FUNCTION: ABFH_CheckSampleIntervals // PURPOSE: Checks that the sample intervals in the header are valid. //{{ // All intervals are in PROTOCOL units. // (100 uS, 2 channels == 50uS) //}} BOOL WINAPI ABFH_CheckSampleIntervals(const ABFFileHeader *pFH, float fClockResolution, int *pnError) { if (!_IsMultipleOf(pFH->fADCSampleInterval, fClockResolution)) ERRORRETURN(pnError, ABFH_BADSAMPLEINTERVAL); if (pFH->nOperationMode!=ABF_WAVEFORMFILE) return TRUE; double dFirstInterval = pFH->fADCSampleInterval; double dSecondInterval = pFH->fADCSecondSampleInterval; double dMinInterval = dFirstInterval; // If the second interval comes into play, check that it is valid. if (dSecondInterval != 0.0) { if (!_IsMultipleOf(dSecondInterval, fClockResolution)) ERRORRETURN(pnError, ABFH_BADSECONDSAMPLEINTERVAL); dMinInterval = min(dFirstInterval, dSecondInterval); double dMaxInterval = max(dFirstInterval, dSecondInterval); if (!_IsMultipleOf(dMaxInterval, dMinInterval)) ERRORRETURN(pnError, ABFH_BADSAMPLEINTERVALS); } else dSecondInterval = dFirstInterval; double dGranularity = _Granularity(dMinInterval, fClockResolution); if (!_IsMultipleOf(dMinInterval, dGranularity)) { if (dFirstInterval <= dSecondInterval) ERRORRETURN(pnError, ABFH_BADSAMPLEINTERVAL); ERRORRETURN(pnError, ABFH_BADSECONDSAMPLEINTERVAL); } return TRUE; } //============================================================================================== // FUNCTION: ClipInterval // PURPOSE: Clips the interval to be within the proscribed range. // static float ClipInterval(double dInterval, float fMax, float fMin) { if (dInterval > fMax) return fMax; if (dInterval < fMin) return fMin; return float(dInterval); } //============================================================================================== // FUNCTION: ABFH_GetClosestSampleIntervals // PURPOSE: Gets the closest sample intervals higher and lower than the passed interval. // void WINAPI ABFH_GetClosestSampleIntervals(float fSampleInterval, float fClockResolution, int nOperationMode, float fMinPeriod, float fMaxPeriod, float *pfHigher, float *pfLower) { double dSampleInterval = fSampleInterval; double dGranularity = fClockResolution; if (nOperationMode==ABF_WAVEFORMFILE) dGranularity = _Granularity(dSampleInterval, fClockResolution); double dRemainder = fmod(dSampleInterval, dGranularity); double dMin = dSampleInterval - dRemainder; double dMax = dMin + dGranularity; if (pfLower) *pfLower = ClipInterval(dMin, fMaxPeriod, fMinPeriod); if (pfHigher) *pfHigher = ClipInterval(dMax, fMaxPeriod, fMinPeriod); } //=============================================================================================== // FUNCTION: ABFH_SetupSamplingList // PURPOSE: Sets up the list for the spinner to drive the sampling interval through. // RETURNS: The number of items added to the list. // UINT WINAPI ABFH_SetupSamplingList(UINT uNumChannels, float fMinPeriod, float fMaxPeriod, float *pfIntervalList, UINT uListEntries) { float fMultiplier = 0.0F; switch (uNumChannels) { case 1: case 2: case 5: case 10: fMultiplier = 1.0F; break; case 4: case 8: fMultiplier = 2.0F; break; case 3: case 6: fMultiplier = 3.0F; break; default: fMultiplier = float(uNumChannels); break; } // Build the list of sampling intervals. const UINT uMAX_DECADES = 7; UINT uEntries = min(uMAX_DECADES*3, uListEntries); uEntries -= uEntries % 3; float fDecade = 1.0F; for (UINT i=0; i fMaxInterval) uEntries--; // Put the minimum interval in at the start of the list if it is not there. if ((uShift > 0) && (pfIntervalList[uShift] > fMinInterval * 1.01)) pfIntervalList[--uShift] = fMinInterval; // If any entries were taken out of the front of the list, // pack the list down. if (uShift > 0) for (int i=0; ilNumSamplesPerEpisode); // If no change, return the full sweep length. if( (pFH->fADCSecondSampleInterval==0.0F) || (pFH->fADCSampleInterval==pFH->fADCSecondSampleInterval ) || (pFH->nOperationMode!=ABF_WAVEFORMFILE)) return uSamplesPerSweep; // If the clock change point is zero it means change at the halfway point. UINT uClockChange = (pFH->lClockChange > 0) ? UINT(pFH->lClockChange) : uSamplesPerSweep/2; // Round it to the next lowest input sequence boundary. uClockChange -= uClockChange % UINT(pFH->nADCNumChannels); return uClockChange; } //============================================================================================== // FUNCTION: ABFH_GetEpisodeDuration // PURPOSE: Gets the duration of the Waveform Episode (in us), allowing for split clock etc. // void WINAPI ABFH_GetEpisodeDuration(const ABFFileHeader *pFH, double *pdEpisodeDuration) { ABFH_ASSERT(pFH); WPTRASSERT(pdEpisodeDuration); UINT uClockChange = ABFH_GetClockChange(pFH); *pdEpisodeDuration = uClockChange * ABFH_GetFirstSampleInterval(pFH) + UINT(pFH->lNumSamplesPerEpisode-uClockChange) * ABFH_GetSecondSampleInterval(pFH); } //============================================================================================== // FUNCTION: ABFH_GetPNDuration // PURPOSE: Gets the duration of a P/N sequence (in us), including settling times. // void WINAPI ABFH_GetPNDuration(const ABFFileHeader *pFH, double *pdPNDuration) { ABFH_ASSERT(pFH); ABFH_GetPNDurationEx( pFH, pFH->nActiveDACChannel, pdPNDuration); } #pragma warning( disable : 4189) //For the unused int pFH below void WINAPI ABFH_GetPNDurationEx(const ABFFileHeader *pFH, UINT uDAC, double *pdPNDuration) { WPTRASSERT(pdPNDuration); ABFH_ASSERT(pFH); ASSERT( uDAC < ABF_WAVEFORMCOUNT ); ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); { // Prevent use of pFH int pFH = 0; *pdPNDuration = 0.0; if ((NewFH.nOperationMode!=ABF_WAVEFORMFILE) || !NewFH.nPNEnable[uDAC]) return; // Get sweep duration in us. double dEpisodeDuration = 0.0; ABFH_GetEpisodeDuration( &NewFH, &dEpisodeDuration ); // Convert to ms. dEpisodeDuration /= 1000.0; // Get the P/N start to start time in ms. double dPNEpisodeDuration = max(dEpisodeDuration, double(NewFH.fPNInterpulse)); // Calculate the total duration in ms. double dPNDuration = (NewFH.nPNNumPulses-1) * dPNEpisodeDuration + dEpisodeDuration + 2 * NewFH.fPNSettlingTime; // Return the total duration in us. *pdPNDuration = dPNDuration * 1000.0; } } #pragma warning( default : 4189) //============================================================================================== // FUNCTION: ABFH_GetTrainDuration // PURPOSE: Gets the duration of a presweep train in us. // void WINAPI ABFH_GetTrainDuration(const ABFFileHeader *pFH, double *pdTrainDuration) { ABFH_ASSERT(pFH); ABFH_GetTrainDurationEx (pFH, pFH->_nConditChannel, pdTrainDuration); } #pragma warning( disable : 4189) //For the unused int pFH below void WINAPI ABFH_GetTrainDurationEx (const ABFFileHeader *pFH, UINT uDAC, double *pdTrainDuration) { WPTRASSERT(pdTrainDuration); ABFH_ASSERT(pFH); ASSERT( uDAC < ABF_WAVEFORMCOUNT ); ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); { // Protect against accidental use of pFH. int pFH = 0; *pdTrainDuration = 0.0; if ((NewFH.nOperationMode!=ABF_WAVEFORMFILE) || !NewFH.nConditEnable[uDAC]) return; // Calculate pulse duration in us. double dPulseDuration = double(NewFH.fBaselineDuration[uDAC] + NewFH.fStepDuration[uDAC]) * 1000.0; // Return train duration in us. *pdTrainDuration = NewFH.lConditNumPulses[uDAC] * dPulseDuration + NewFH.fPostTrainPeriod[uDAC] * 1000.0; } } #pragma warning( default : 4189) //============================================================================================== // FUNCTION: ABFH_GetMetaEpisodeDuration // PURPOSE: Gets the duration of a whole meta-episode (in us). // void WINAPI ABFH_GetMetaEpisodeDuration(const ABFFileHeader *pFH, double *pdMetaEpisodeDuration) { ABFH_ASSERT(pFH); WPTRASSERT(pdMetaEpisodeDuration); double dTrainDuration=0.0, dPNDuration=0.0, dEpisodeDuration=0.0; double dTrainDur[ABF_WAVEFORMCOUNT]; double dPNDur[ABF_WAVEFORMCOUNT]; for( UINT i=0; inOperationMode!=ABF_WAVEFORMFILE) return; double dMetaEpisodeDuration = 0.0; ABFH_GetMetaEpisodeDuration(pFH, &dMetaEpisodeDuration); *pdEpisodeStartToStart = max(dMetaEpisodeDuration, double(pFH->fEpisodeStartToStart)*1E6); } //=============================================================================================== // METHOD: CheckDACLevel // TYPE: Public Function // PURPOSE: Returns TRUE if the user value is within range. // ARGUMENTS: nChannel - The channel. // fValue - The value. // RETURNS: TRUE if the user value is within range. // BOOL CheckDACLevel( const ABFFileHeader *pFH, int nChannel, float fValue ) { // Clip the DAC value. float fClippedValue = fValue; ABFH_ClipDACUUValue( pFH, nChannel, &fClippedValue ); BOOL bSame = (fValue == fClippedValue); return bSame; } //============================================================================================== // FUNCTION: CheckMetaDuration // PURPOSE: Check that the meta episode duration doesn't exceed the requested episode start to start time. // RETURNS: TRUE if meta episode duration is OK // BOOL CheckMetaDuration( const ABFFileHeader *pFH ) { // If start to start time is minimum, its OK. if( pFH->fEpisodeStartToStart == 0.0F ) return TRUE; double dMetaDuration = 0.0; ABFH_GetMetaEpisodeDuration( pFH, &dMetaDuration); return dMetaDuration <= pFH->fEpisodeStartToStart * 1E6; } //============================================================================================== // FUNCTION: CheckEpochLength // PURPOSE: Check that the epoch length doesn't exceed the allowable maximum. // RETURNS: TRUE if epoch length is OK // BOOL CheckEpochLength( const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nListEpoch ) { ABFH_ASSERT( pFH); ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); // Get the maximum allowable epoch length int nMaxEpochLen = ABFH_UserLenFromSweepLen( FH.lNumSamplesPerEpisode, FH.nADCNumChannels ); nMaxEpochLen /= FH.nADCNumChannels; // Calculate the duration of all epochs combined int nEpochDuration = 0; for( int nEpoch = 0; nEpoch < ABF_EPOCHCOUNT; nEpoch++ ) { if( FH.nEpochType[uDACChannel][nEpoch] != ABF_EPOCHDISABLED ) { int nDuration = FH.lEpochInitDuration[uDACChannel][nEpoch]; //The duration must be > 0 if( nDuration < 0 ) return FALSE; if ((nEpoch != nListEpoch) && (uEpisode > 1)) nDuration += uEpisode * FH.lEpochDurationInc[uDACChannel][nEpoch]; if (nDuration > 0) nEpochDuration += nDuration; } } return nEpochDuration <= nMaxEpochLen; } //============================================================================================== // FUNCTION: IsBinaryList // PURPOSE: Check that the User List is valid for binary items. // BOOL IsBinaryList( const ABFFileHeader *pFH, UINT uListNum ) { ABFH_ASSERT( pFH ); ASSERT( uListNum < ABF_USERLISTCOUNT ); char szUserList[ABF_USERLISTLEN+1]; ABF_GET_STRING(szUserList, pFH->sULParamValueList[uListNum], sizeof(szUserList)); return ( strspn( szUserList, "01*, " ) == strlen(szUserList) ); } //============================================================================================== // FUNCTION: AreListCharsOK // PURPOSE: Check that the User List only contains valid characters. // BOOL AreListCharsOK( const ABFFileHeader *pFH, UINT uListNum ) { ABFH_ASSERT( pFH ); ASSERT( uListNum < ABF_USERLISTCOUNT ); char szUserList[ABF_USERLISTLEN+1]; ABF_GET_STRING(szUserList, pFH->sULParamValueList[uListNum], sizeof(szUserList)); // a '*' is allowed for digital bit patterns. BOOL bStarInUserList = strspn( szUserList, "*0123456789, Ee.+-" ) == strlen( szUserList ); BOOL bUserListParamIsDigitalPattern = pFH->nULParamToVary[uListNum] >= ABF_PARALLELVALUE && pFH->nULParamToVary[uListNum] < ABF_EPOCHINITLEVEL; if( bStarInUserList && bUserListParamIsDigitalPattern ) return TRUE; // Check the first character. BOOL bFirstCharInvalid = ( szUserList[ 0 ] < '0' || szUserList[ 0 ] > '9' ); if ( ( bFirstCharInvalid ) && szUserList[ 0 ] != '.' && szUserList[ 0 ] != '+' && szUserList[ 0 ] != '-' ) return FALSE; // Check all the other characters. return ( strspn( szUserList, "0123456789, Ee.+-" ) == strlen(szUserList) ); } //============================================================================================== // FUNCTION: ABFH_CheckUserList // PURPOSE: Checks that the user list contains valid entries for the protocol. // BOOL WINAPI ABFH_CheckUserList(const ABFFileHeader *pFH, int *pnError) { ABFH_ASSERT(pFH); return ABFH_CheckUserListEx(pFH, pFH->nActiveDACChannel, pnError); } BOOL WINAPI ABFH_CheckUserListEx(const ABFFileHeader *pFH, UINT uListNum, int *pnError) { ABFH_ASSERT(pFH); ASSERT( uListNum < ABF_USERLISTCOUNT ); // Take a copy of the ABF Header for testing User List values. ABFFileHeader FH; ABFH_PromoteHeader( &FH, pFH ); // The user list is only defined for Stimulus Waveform acquisitions. if (FH.nOperationMode!=ABF_WAVEFORMFILE) return TRUE; // Only check if user list is enabled. if( FH.nULEnable[uListNum] == 0) return TRUE; // Check the characters in the user list. if (!AreListCharsOK( &FH, uListNum )) ERRORRETURN( pnError, ABFH_EINVALIDCHARS ); // Create the User List CUserList UserList; // Make sure we are initialised. UserList.Initialize( &FH, uListNum ); UINT uListEntries = UserList.GetNumEntries(); ASSERT( uListEntries > 0 ); // Prevent compiler warnings. uListEntries = uListEntries; short nParamToVary = FH.nULParamToVary[uListNum]; // loop thru each episode for( int nEpisode = 1; nEpisode <= FH.lEpisodesPerRun; nEpisode++ ) { UserList.UpdateHeader( &FH, uListNum, nEpisode ); int nValue = 0; float fValue = 0.0F; // Check things applicable to Presweep Trains if( nParamToVary == ABF_CONDITNUMPULSES || nParamToVary == ABF_CONDITBASELINEDURATION || nParamToVary == ABF_CONDITBASELINELEVEL || nParamToVary == ABF_CONDITSTEPDURATION || nParamToVary == ABF_CONDITSTEPLEVEL || nParamToVary == ABF_CONDITPOSTTRAINDURATION || nParamToVary == ABF_CONDITPOSTTRAINLEVEL ) { // Check that Presweep Trains are enabled. if ( FH.nConditEnable[uListNum] == 0 ) ERRORRETURN( pnError, ABFH_ENOCONDITTRAINS ); // Check we don't make the meta episode too long if( !CheckMetaDuration( &FH ) ) ERRORRETURN( pnError, ABFH_EMETADURATION ); } // check each entry in the list for a safe value, return FALSE if not switch (nParamToVary) { case ABF_CONDITNUMPULSES: nValue = FH.lConditNumPulses[uListNum]; if( nValue < 0 || nValue > ABF_CTPULSECOUNT_MAX ) ERRORRETURN( pnError, ABFH_ECONDITNUMPULSES ); break; case ABF_CONDITBASELINEDURATION: fValue = FH.fBaselineDuration[uListNum]; if( fValue < 0.0F || fValue > ABF_CTBASELINEDURATION_MAX ) ERRORRETURN( pnError, ABFH_ECONDITBASEDUR ); break; case ABF_CONDITSTEPLEVEL: fValue = FH.fStepLevel[uListNum]; if( !CheckDACLevel( &FH, uListNum, fValue ) ) ERRORRETURN( pnError, ABFH_ECONDITSTEPLEVEL ); // Fall through to test baseline level as well case ABF_CONDITBASELINELEVEL: fValue = FH.fBaselineLevel[uListNum]; if( !CheckDACLevel( &FH, uListNum, fValue ) ) ERRORRETURN( pnError, ABFH_ECONDITBASELEVEL ); break; case ABF_CONDITSTEPDURATION: fValue = FH.fStepDuration[uListNum]; if( fValue < 0.0F || fValue > ABF_CTSTEPDURATION_MAX ) ERRORRETURN( pnError, ABFH_ECONDITSTEPDUR ); break; case ABF_CONDITPOSTTRAINDURATION: fValue = FH.fPostTrainPeriod[uListNum]; if( fValue < 0.0F || fValue > ABF_CTPOSTTRAINDURATION_MAX ) ERRORRETURN( pnError, ABFH_ECONDITPOSTTRAINDUR ); break; case ABF_CONDITPOSTTRAINLEVEL: fValue = FH.fPostTrainLevel[uListNum]; if( !CheckDACLevel( &FH, uListNum, fValue ) ) ERRORRETURN( pnError, ABFH_ECONDITPOSTTRAINLEVEL ); break; case ABF_EPISODESTARTTOSTART: if( !CheckMetaDuration( &FH ) ) ERRORRETURN( pnError, ABFH_EMETADURATION ); break; case ABF_INACTIVEHOLDING: fValue = FH.fDACHoldingLevel[1-FH.nActiveDACChannel] ; if( !CheckDACLevel( &FH, 1-FH.nActiveDACChannel, fValue ) ) ERRORRETURN( pnError, ABFH_EINACTIVEHOLDING ); break; case ABF_DIGITALHOLDING: if (!IsBinaryList( &FH, uListNum )) ERRORRETURN( pnError, ABFH_EINVALIDBINARYCHARS ); if( FH.nDigitalEnable == 0 ) ERRORRETURN( pnError, ABFH_ENODIG ); nValue = FH.nDigitalHolding; if( nValue < 0 || nValue > ABF_DIGITALVALUE_MAX ) ERRORRETURN( pnError, ABFH_EDIGHOLDLEVEL ); break; case ABF_PNNUMPULSES: if( FH.nPNEnable == 0 ) ERRORRETURN( pnError, ABFH_ENOPNPULSES ); nValue = FH.nPNNumPulses; if( nValue < 1 || nValue > ABF_PNPULSECOUNT_MAX ) ERRORRETURN( pnError, ABFH_EPNNUMPULSES ); if( !CheckMetaDuration( &FH ) ) ERRORRETURN( pnError, ABFH_EMETADURATION ); break; default: // Epoch related parameter to vary int nListEpoch = UserList.GetActiveEpoch(); ASSERT(nListEpoch >= 0); ASSERT(nListEpoch < ABF_EPOCHCOUNT); // Check that the waveform is enabled. if( (!FH.nWaveformEnable[uListNum] || FH.nWaveformSource[uListNum] == ABF_WAVEFORMDISABLED) && FH.nDigitalEnable == 0 ) ERRORRETURN( pnError, ABFH_ENOWAVEFORM ); // Make sure that the epoch chosen is enabled. if ( FH.nEpochType[uListNum][nListEpoch] == ABF_EPOCHDISABLED ) ERRORRETURN( pnError, ABFH_ENOEPOCH); if (nParamToVary >= ABF_EPOCHINITDURATION) { if( !CheckEpochLength( &FH, uListNum, nEpisode, nListEpoch ) ) ERRORRETURN( pnError, ABFH_EEPOCHLEN ); } else if (nParamToVary >= ABF_EPOCHINITLEVEL) { fValue = FH.fEpochInitLevel[uListNum][nListEpoch]; if( !CheckDACLevel( &FH, uListNum, fValue ) ) ERRORRETURN( pnError, ABFH_EEPOCHINITLEVEL ); } else if (nParamToVary >= ABF_PARALLELVALUE) { if (!IsBinaryList( &FH, uListNum )) ERRORRETURN( pnError, ABFH_EINVALIDBINARYCHARS); nValue = FH.nDigitalValue[nListEpoch]; if( nValue < 0 || nValue > ABF_EPOCHDIGITALVALUE_MAX ) ERRORRETURN( pnError, ABFH_EDIGLEVEL ); // Check the digital train value. int nTrainValue = FH.nDigitalTrainValue[nListEpoch]; if( nTrainValue < 0 || nTrainValue > ABF_EPOCHDIGITALVALUE_MAX ) ERRORRETURN( pnError, ABFH_EDIGLEVEL ); } break; } } // if we got here, everything's OK return TRUE; } */ stimfit-0.16.7/src/libstfio/abf/axon/AxAbfFio32/abfheadr.cpp0000775000175000017500000016413414752207205017112 //*********************************************************************************************** // // Copyright (c) 1993-2000 Axon Instruments. // All rights reserved. // Permission is granted to freely to use, modify and copy the code in this file. // //*********************************************************************************************** // This is ABFHEADR.CPP; the routines that cope with reading the data file // parameters block for all AXON pCLAMP binary file formats. // // An ANSI C compiler should be used for compilation. // Compile with the large memory model option. // (e.g. CL -c -AL ABFHEADR.C) #include "../Common/wincpp.hpp" #include "abfheadr.h" // header definition & constants #include "oldheadr.h" // old header conversion prototypes #include "abfutil.h" // Large memory allocation/free /* #include "StringResource.h" // Access to string resources. */ #define A_VERY_SMALL_NUMBER 1E-10 #define DEFAULT_LEVEL_HYSTERESIS 64 // Two LSBits of level hysteresis. #define DEFAULT_TIME_HYSTERESIS 1 // Two sequences of time hysteresis. #if !defined(_WINDOWS) || defined(__MINGW32__) || defined(__STF__) #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif const char c_szValidOperators[] = "+-*/"; const ABFLONG c_lMaxShort = 30000; //----------------------------------------------------------------------------------------------- // Uncomment the following line to display interface structure sizes. //#define SHOW_STRUCT_SIZES 1 //----------------------------------------------------------------------------------------------- // Macros and functions to deal with returning error return codes through a pointer if given. #define ERRORRETURN(p, e) return ErrorReturn(p, e); static BOOL ErrorReturn(int *pnError, int nErrorNum) { if (pnError) *pnError = nErrorNum; return FALSE; } //=============================================================================================== // FUNCTION: ABFH_Initialize // PURPOSE: Initialize an ABFFileHeader structure to a consistent set of parameters // void WINAPI ABFH_Initialize( ABFFileHeader *pFH ) { // ABFH_WASSERT(pFH); int i; ABFFileHeader NewFH; ABFH_PromoteHeader( &NewFH, pFH ); // Zero fill all to start with. memset(&NewFH, '\0', sizeof(NewFH)); // Blank fill all strings. ABF_BLANK_FILL(NewFH._sParamValueList); ABF_BLANK_FILL(NewFH.sADCChannelName); ABF_BLANK_FILL(NewFH.sADCUnits); ABF_BLANK_FILL(NewFH.sDACChannelName); ABF_BLANK_FILL(NewFH.sDACChannelUnits); ABF_BLANK_FILL(NewFH.sDACFilePath[0]); ABF_BLANK_FILL(NewFH.sDACFilePath[1]); ABF_SET_STRING(NewFH.sArithmeticOperator, "+"); ABF_BLANK_FILL(NewFH.sArithmeticUnits); NewFH.lFileSignature = ABF_NATIVESIGNATURE; NewFH.fFileVersionNumber = ABF_CURRENTVERSION; NewFH.fHeaderVersionNumber = ABF_CURRENTVERSION; NewFH.nOperationMode = ABF_GAPFREEFILE; NewFH.nADCNumChannels = 1; NewFH.fADCSampleInterval = 100.0F; NewFH.lNumSamplesPerEpisode = 512; NewFH.lEpisodesPerRun = 1; NewFH.lDataSectionPtr = sizeof(ABFFileHeader) / ABF_BLOCKSIZE; NewFH.nDrawingStrategy = ABF_DRAW_REALTIME; NewFH.nTiledDisplay = ABF_DISPLAY_TILED; NewFH.nEraseStrategy = 1; NewFH.nDataDisplayMode = ABF_DRAW_LINES; NewFH.nMultiColor = TRUE; NewFH.nFileType = ABF_ABFFILE; NewFH.nAutoTriggerStrategy = 1; // Allow auto triggering. NewFH.nChannelStatsStrategy = 0; // Don't calculate channel statistics. NewFH.fStatisticsPeriod = 1.0F; NewFH.lCalculationPeriod = ABFLONG(NewFH.fStatisticsPeriod / NewFH.fADCSampleInterval * 1E3F); NewFH.lStatisticsMeasurements = ABF_STATISTICS_ABOVETHRESHOLD | ABF_STATISTICS_MEANOPENTIME; NewFH.lSamplesPerTrace = 16384; NewFH.lPreTriggerSamples = 16; // default to 16 NewFH.fADCRange = 10.24F; NewFH.fDACRange = 10.24F; NewFH.lADCResolution = 32768L; NewFH.lDACResolution = 32768L; NewFH.nExperimentType = ABF_SIMPLEACQUISITION; ABF_BLANK_FILL(NewFH.sCreatorInfo); ABF_BLANK_FILL(NewFH.sModifierInfo); ABF_BLANK_FILL(NewFH.sFileComment); // ADC channel data for (i=0; inOperationMode) { case ABF_FIXLENEVENTS: case ABF_VARLENEVENTS: case ABF_GAPFREEFILE: return ABF_CONTINUOUSMODE; case ABF_HIGHSPEEDOSC: case ABF_WAVEFORMFILE: return ABF_EPISODICMODE; default: ERRORMSG1("Unexpected operation mode '%d'.", pFH->nOperationMode); return ABF_EPISODICMODE; } } //=============================================================================================== // FUNCTION: SetupSignal // PURPOSE: Sets up a signal descriptor from display parameters in an old ABF header. // static void _SetupSignal(const ABFFileHeader *pFH, ABFSignal *pS, UINT uMxOffset, UINT uTraces) { memset(pS, 0, sizeof(ABFSignal)); int nChannel = pFH->nADCSamplingSeq[uMxOffset]; ABFU_GetABFString(pS->szName, ABF_ADCNAMELEN+1, pFH->sADCChannelName[nChannel], ABF_ADCNAMELEN); pS->nMxOffset = short(uMxOffset); pS->rgbColor = RGB_BLUE; pS->nPenWidth = 1; pS->bDrawPoints = char(!pFH->nDataDisplayMode); pS->bHidden = FALSE; pS->bFloatData = FALSE; pS->fVertProportion = 1.0F / float(uTraces); pS->fDisplayGain = pFH->fADCDisplayAmplification[nChannel]; pS->fDisplayOffset = pFH->fADCDisplayOffset[nChannel]; } //=============================================================================================== // FUNCTION: SetupMathSignal // PURPOSE: Sets up a signal descriptor for a math channel from parameters in an ABF header. // static void _SetupMathSignal(const ABFFileHeader *pFH, ABFSignal *pS, UINT uTraces) { memset(pS, 0, sizeof(ABFSignal)); LoadString(g_hInstance, IDS_MATHCHANNEL, pS->szName, sizeof(pS->szName)); pS->nMxOffset = 0; pS->rgbColor = RGB_BLUE; pS->nPenWidth = 1; pS->bDrawPoints = char(!pFH->nDataDisplayMode); pS->bHidden = FALSE; pS->bFloatData = TRUE; pS->fVertProportion = 1.0F / float(uTraces); pS->fDisplayGain = 1.0F; pS->fDisplayOffset = 0.0F; } //=============================================================================================== // FUNCTION: MathChannelEnabled // PURPOSE: Returns TRUE if the math channel is enabled. // static BOOL MathChannelEnabled(const ABFFileHeader *pFH) { return (pFH->nArithmeticEnable && (pFH->nADCNumChannels < ABF_ADCCOUNT)); } //=============================================================================================== // FUNCTION: _GetTraceCount // PURPOSE: Gets the number of traces that should be displayed for this acquisition. // static UINT _GetTraceCount(const ABFFileHeader *pFH, BOOL *pbMathChannel=NULL) { UINT uTraces = UINT(pFH->nADCNumChannels); BOOL bMathChannel = MathChannelEnabled(pFH); if (bMathChannel) uTraces++; if (pbMathChannel) *pbMathChannel = bMathChannel; return uTraces; } //=============================================================================================== // FUNCTION: ABFH_InitializeScopeConfig // PURPOSE: Sets up a scope configuration structure from the old header locations for display // parameters. // void WINAPI ABFH_InitializeScopeConfig(const ABFFileHeader *pFH, ABFScopeConfig *pCfg) { // Zapp everything! memset(pCfg, 0, sizeof(*pCfg)); // Enable SC_CLIPPING pCfg->dwFlags = 0x00000008; // Set the scope mode. pCfg->wScopeMode = _GetDefaultScopeMode(pFH); // Set up the first ScopeConfig structure. pCfg->rgbColor[ABF_BACKGROUNDCOLOR] = RGB_WHITE; pCfg->rgbColor[ABF_GRIDCOLOR] = RGB_LTGRAY; pCfg->rgbColor[ABF_THRESHOLDCOLOR] = RGB_DKRED; pCfg->rgbColor[ABF_EVENTMARKERCOLOR]= RGB_RED; pCfg->rgbColor[ABF_SEPARATORCOLOR] = RGB_BLACK; pCfg->rgbColor[ABF_AVERAGECOLOR] = RGB_RED; pCfg->rgbColor[ABF_OLDDATACOLOR] = RGB_LTGRAY; pCfg->rgbColor[ABF_TEXTCOLOR] = RGB_BLACK; pCfg->rgbColor[ABF_AXISCOLOR] = GetSysColor(COLOR_3DFACE); pCfg->rgbColor[ABF_ACTIVEAXISCOLOR] = GetSysColor(COLOR_3DSHADOW); pCfg->fDisplayStart = 0.0F; // If fDisplayStart==fDisplayEnd a default pCfg->fDisplayEnd = 0.0F; // display scaling will be used. pCfg->nYAxisWidth = -1; pCfg->nEraseStrategy = ABF_ERASE_EACHRUN; // Set the Signals in the first scope configuration to match the // old entries in the header. BOOL bMathChannel = FALSE; UINT uTraces = _GetTraceCount(pFH, &bMathChannel); UINT uNormalTraces = uTraces; if (bMathChannel) uNormalTraces--; UINT i; for (i=0; iTraceList+i, i, uTraces); if (bMathChannel) _SetupMathSignal(pFH, pCfg->TraceList+i, uTraces); pCfg->nTraceCount = short(uTraces); // Initialize the extended ABFScopeConfig fields for ABF file version 1.68. pCfg->nAutoZeroState = 0; pCfg->nSizeofOldStructure = pCfg->nSizeofOldStructure; pCfg->rgbColorEx[ ABF_STATISTICS_REGION0 ] = RGB_BLACK; pCfg->rgbColorEx[ ABF_STATISTICS_REGION1 ] = RGB_DKRED; pCfg->rgbColorEx[ ABF_STATISTICS_REGION2 ] = RGB_DKGREEN; pCfg->rgbColorEx[ ABF_STATISTICS_REGION3 ] = RGB_DKYELLOW; pCfg->rgbColorEx[ ABF_STATISTICS_REGION4 ] = RGB_DKBLUE; pCfg->rgbColorEx[ ABF_STATISTICS_REGION5 ] = RGB_MAUVE; pCfg->rgbColorEx[ ABF_STATISTICS_REGION6 ] = RGB_BLUEGRAY; pCfg->rgbColorEx[ ABF_STATISTICS_REGION7 ] = RGB_DKGRAY; pCfg->rgbColorEx[ ABF_BASELINE_REGION ] = RGB_RED; pCfg->rgbColorEx[ ABF_STOREDSWEEPCOLOR ] = RGB_BLUEGRAY; } //=============================================================================================== // FUNCTION: SetMxOffset // PURPOSE: Returns TRUE if the passed signal is still in the sampling sequence. // static BOOL SetMxOffset(const ABFFileHeader *pFH, ABFSignal *pS) { // Initialize to failure case. pS->nMxOffset = -1; if (!pS->bFloatData) { char szName[ABF_ADCNAMELEN+1]; for (int i=0; inADCNumChannels); i++) { int nChannel = pFH->nADCSamplingSeq[i]; ABFU_GetABFString(szName, sizeof(szName), pFH->sADCChannelName[nChannel], ABF_ADCNAMELEN); if (strcmp(pS->szName, szName)==0) { pS->nMxOffset = short(i); break; } } } else if (MathChannelEnabled(pFH)) pS->nMxOffset = 0; return (pS->nMxOffset != -1); } //=============================================================================================== // FUNCTION: ABFH_CheckScopeConfig // PURPOSE: Checks a scope configuration structure against an ABFFileHeader structure, making // sure that both reference the same signals, in the same multiplex sequence. // RETURNS: FALSE if the configuration structure specified an innappropriate Scope mode. // BOOL WINAPI ABFH_CheckScopeConfig(ABFFileHeader *pFH, ABFScopeConfig *pCfg) { ASSERT(pFH->nADCNumChannels > 0); // Search through the ABFScopeConfig trace list to see if all signals are // included in the sampling list. BOOL bMathChannel = FALSE; UINT uNewTraceCount = _GetTraceCount(pFH, &bMathChannel); UINT uOldTraceCount = UINT(pCfg->nTraceCount); UINT uOldVisibleTraceCount = uOldTraceCount; UINT uGaps = 0; ABFSignal *pS = pCfg->TraceList; for (UINT i=0; i
sec_list(16, Section(32768)); Channel ch(sec_list); Recording rec1(ch); EXPECT_EQ( rec1.size(), 1 ); EXPECT_EQ( rec1[0].size(), 16 ); EXPECT_EQ( rec1[0][0].size(), 32768 ); std::deque ch_list(4, Channel(16, 32768)); Recording rec2(ch_list); EXPECT_EQ( rec2.size(), 4 ); EXPECT_EQ( rec2[rec2.size()-1].size(), 16 ); EXPECT_EQ( rec2[rec2.size()-1][rec2[rec2.size()-1].size()-1].size(), 32768 ); Recording rec3(4, 16, 32768); EXPECT_EQ( rec3.size(), 4 ); EXPECT_EQ( rec3[rec3.size()-1].size(), 16 ); EXPECT_EQ( rec3[rec3.size()-1][rec3[rec3.size()-1].size()-1].size(), 32768 ); } TEST(Recording_test, data_access) { std::deque
sec_list(16, Section(32768)); Channel ch(sec_list); Recording rec1(ch); int chsize = rec1[0].size(); int secsize = rec1[0][rec1[0].size()-1].size(); EXPECT_EQ( rec1[0][chsize-1][secsize-1], 0 ); EXPECT_THROW( rec1.at(1), std::out_of_range ); EXPECT_THROW( rec1[0].at(chsize), std::out_of_range ); EXPECT_THROW( rec1[0][chsize-1].at(secsize), std::out_of_range ); std::deque ch_list(4, Channel(16, 32768)); Recording rec2(ch_list); int recsize = rec2.size(); chsize = rec2[recsize-1].size(); secsize = rec2[recsize-1][rec2[recsize-1].size()-1].size(); EXPECT_EQ( rec2[recsize-1][chsize-1][secsize-1], 0 ); EXPECT_THROW( rec2.at(recsize), std::out_of_range ); EXPECT_THROW( rec2[recsize-1].at(chsize), std::out_of_range ); EXPECT_THROW( rec2[recsize-1][chsize-1].at(secsize), std::out_of_range ); Recording rec3(4, 16, 32768); recsize = rec3.size(); chsize = rec3[recsize-1].size(); secsize = rec3[recsize-1][rec3[recsize-1].size()-1].size(); EXPECT_EQ( rec3[recsize-1][chsize-1][secsize-1], 0 ); EXPECT_THROW( rec3.at(recsize), std::out_of_range ); EXPECT_THROW( rec3[recsize-1].at(chsize), std::out_of_range ); EXPECT_THROW( rec3[recsize-1][chsize-1].at(secsize), std::out_of_range ); } stimfit-0.16.7/src/test/channel.cpp0000664000175000017500000000245114750344764012651 #include "../libstfio/stfio.h" #include TEST(Channel_test, constructors) { Channel ch0; EXPECT_EQ( ch0.size(), 0 ); Section sec(32768); Channel ch1(sec); EXPECT_EQ( ch1.size(), 1 ); EXPECT_EQ( ch1[0].size(), 32768 ); std::deque
sec_list(16, Section(32768)); Channel ch2(sec_list); EXPECT_EQ( ch2.size(), 16 ); EXPECT_EQ( ch2[ch2.size()-1].size(), 32768 ); Channel ch3(16, 32768); EXPECT_EQ( ch3.size(), 16 ); EXPECT_EQ( ch3[ch3.size()-1].size(), 32768 ); } TEST(Channel_test, data_access) { Channel ch1(Section(32768)); EXPECT_EQ( ch1[0][ch1[0].size()-1], 0 ); EXPECT_THROW( ch1.at( ch1.size() ), std::out_of_range ); EXPECT_THROW( ch1[0].at(ch1[0].size()), std::out_of_range ); std::deque
sec_list(16, Section(32768)); Channel ch2(sec_list); EXPECT_EQ( ch2[ch2.size()-1][ch2[ch2.size()-1].size()-1], 0 ); EXPECT_THROW( ch2.at( ch2.size() ), std::out_of_range ); EXPECT_THROW( ch2[ch2.size()-1].at(ch2[ch2.size()-1].size()), std::out_of_range ); Channel ch3(16, 32768); EXPECT_EQ( ch3[ch3.size()-1][ch3[ch3.size()-1].size()-1], 0 ); EXPECT_THROW( ch3.at( ch3.size() ), std::out_of_range ); EXPECT_THROW( ch3[ch3.size()-1].at(ch3[ch3.size()-1].size()), std::out_of_range ); } stimfit-0.16.7/src/test/fit.cpp0000664000175000017500000007010614750344764012025 #include "../stimfit/stf.h" #include "../libstfnum/fit.h" #include "../libstfnum/funclib.h" #include #include #include /* global variables to define our data */ const static int tmax = 100; /* length of data in ms */ const static float dt = 1/100.0; /* sampling interval of data in ms */ //const static double tol = 0.001; /* param-relative tolerance value */ const static float tol = dt; /* 1 sampling interval */ /* list of available fitting functions, see /src/stimfit/math/funclib.cpp */ const static std::vector< stfnum::storedFunc > funcLib = stfnum::GetFuncLib(); /* Fitting options for the LM algorithm, see /src/stimfit/math/fit.h */ const Vector_double opts = stfnum::LM_default_opts(); //========================================================================= // Simple monoexponential function // available for fitting to function 0, and 1 of Stimfit // param is an array of parameters, where // param[0] is the amplitude (peak-offset), // param[1] is the time constant, // param[2] is the end (offset) //========================================================================= Vector_double fexp_simple(const Vector_double ¶m){ Vector_double mydata (int (tmax/dt)); double amp = param[0]; double tau = param[1]; double end = param[2]; for (std::vector::size_type n=0; n != mydata.size() ; ++n){ mydata[n] = amp*exp(-(n*dt)/tau) + end; } return mydata; } //========================================================================= // Monoexponential function with delay, start fixed to baseline // available for fitting to function 2 of Stimfit // param is an array of parameters, where // param[0] is the baseline, // param[1] is the delay, // param[2] is the time constant, // param[3] is the amplitude //========================================================================= Vector_double fexpde(const Vector_double ¶m){ Vector_double mydata (int (tmax/dt)); for (std::vector::size_type n=0; n != mydata.size(); ++n){ mydata[n] = stfnum::fexpde(n*dt, param); } return mydata; } //========================================================================= // Monoexponential function with delay, start fixed to baseline // available for fitting to function 3, 4, 6, 7 and 8 of Stimfit // param is an array of parameters, where // event terms (e.g param[0]) are the amplitudes, // odd terms (e.g param[1]) are the time constants, // param[last] is the offset //========================================================================= Vector_double fexp(const Vector_double ¶m){ Vector_double mydata (int (tmax/dt)); for (std::vector::size_type n=0; n != mydata.size(); ++n){ mydata[n] = stfnum::fexp(n*dt, param); } return mydata; } //========================================================================= // Biexponential function with offset to baseline // corresponding to fitting function 5 of Stimfit // param is an array of parameters, where // param[0] is the baseline, // param[1] is the delay, // param[2] is the slow time constant (e.g tau_h, tau_2) // param[3] is the factor, // param[4] is the fast time constant (e.g tau_m, tau_1) //========================================================================= Vector_double fexpbde(const Vector_double ¶m){ Vector_double mydata (int(tmax/dt)); for (std::vector::size_type n=0; n != mydata.size(); ++n){ mydata[n] = stfnum::fexpbde(n*dt, param); } return mydata; } //========================================================================= // Alpha function with offset to baseline // corresponding to fitting function 9 of Stimfit // param is an array of parameters, where // param[0] is the amplitude, // param[1] is the rate, // param[2] is the offset //========================================================================= Vector_double falpha(const Vector_double ¶m){ Vector_double mydata (int(tmax/dt)); for (std::vector::size_type n=0; n != mydata.size(); ++n){ mydata[n] = stfnum::falpha(n*dt, param); } return mydata; } //========================================================================= // Hodkin-Huxley-like sodium conductance function of the form: // f(v;Na_bar, m, h, base) = Na_bar*m(v)^3*h(v) + base // corresponding to fitting function 10 of Stimfit // param is an array of parameters, where // param[0] is the peak sodium conductance // param[1] is the activation time constant (tau_m) // param[2] is the inactivation time constant (tau_h) // param[3] is the offset //========================================================================= Vector_double fHH(const Vector_double ¶m){ Vector_double mydata (int(tmax/dt)); for (std::vector::size_type n=0; n != mydata.size(); ++n){ mydata[n] = stfnum::fHH(n*dt, param); } return mydata; } //========================================================================= // Hodkin-Huxley-like sodium conductance function of the form: // f(v;Na_bar, m, h, base) = Na_bar*m(v)*h(v) + base // corresponding to fitting function 11 of Stimfit // param is an array of parameters, where // param[0] is the peak sodium conductance // param[1] is the activation time constant (tau_m) // param[2] is the inactivation time constant (tau_h) // param[3] is the offset //========================================================================= Vector_double fgnabiexp(const Vector_double ¶m){ Vector_double mydata (int(tmax/dt)); for (std::vector::size_type n=0; n != mydata.size(); ++n){ mydata[n] = stfnum::fgnabiexp(n*dt, param); } return mydata; } //========================================================================= // A gaussian function of the form // f(x, a, b, c) = a*exp((x-b)^2/2*c^2) // corresponding to the fitting function 12 of Stimfit // param in an array of parameters, where // param[0] is the heigth of the Gaussian function (a) // param[1] is the position of the peak (b) // param[2] is the width of the gaussian (c) //========================================================================= Vector_double fgauss(const Vector_double ¶m){ Vector_double mydata (int(tmax/dt)); for (std::vector::size_type n=0; n != mydata.size(); ++n){ mydata[n] = stfnum::fgauss(n*dt, param); } return mydata; } #if 0 void savetxt(const char *fname, Vector_double &mydata){ std::ofstream output_file; output_file.open(fname); Vector_double::iterator it; for (it = mydata.begin(); it != mydata.end(); ++it){ output_file << *it << std::endl; } output_file.close(); } void debug_stdout(double chisqr, const std::string& info, int warning, const Vector_double &pars){ int fd = open("debug.log", O_WRONLY|O_CREAT|O_TRUNC, 0660); assert(fd >= 0); int ret = dup2(fd, 1); assert(ret >= 0); std::cout << "chisqr = " << chisqr << std::endl; std::cout << "info = " << info << std::endl; std::cout << "warning = " << warning << std::endl; for (std::vector::size_type n = 0; n != pars.size(); ++n) { std::cout << "Pars[" << n << "] = " << pars[n] << std::endl; } close(fd); } #endif void par_test(double value, double expected, double tolerance) { EXPECT_NEAR(value, expected, fabs(expected*tolerance) ); } // Tests fiting to a monoexponential function TEST(fitlib_test, monoexponential) { double tau = 3000.0; Vector_double data(32768); for (int n = 0; n < data.size(); ++n) { data[n] = 1.0-exp(-n/tau); } // Respectively the scale factor for initial \mu, // stopping thresholds for ||J^T e||_inf, ||Dp||_2 and ||e||_2, // maxIter, maxPass Vector_double opts = stfnum::LM_default_opts(); /* Initial parameter guesses */ Vector_double pars(3); pars[0] = -0.1; pars[1] = 3050.0; pars[2] = 1.1; std::string info; int warning; double chisqr = stfnum::lmFit(data, 1.0, funcLib[0], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], -1.0, tol); /* Amplitude */ par_test(pars[1], tau, tol); /* Time constant */ par_test(pars[2], 1.0, tol); /* Baseline */ #if 0 int fd = open("debug.log", O_WRONLY|O_CREAT|O_TRUNC, 0660); assert(fd >= 0); int ret = dup2(fd, 1); assert(ret >= 0); std::cout << "chisqr = " << chisqr << std::endl; std::cout << "info = " << info << std::endl; std::cout << "warning = " << warning << std::endl; for (int n = 0; n < pars.size(); ++n) { std::cout << "Pars[" << n << "] = " << pars[n] << std::endl; } close(fd); #endif } //========================================================================= // Tests fitting to a monoexponential function // Stimfit function with ID = 0 //========================================================================= TEST(fitlib_test, id_00_monoexponential){ /* choose function parameters */ Vector_double mypars(3); mypars[0] = 50.0; /* amplitude */ mypars[1] = 17.0; /* time constant */ mypars[2] = -20.0; /* end */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexp_simple(mypars); /* Initial parameters guesses */ Vector_double pars(3); pars[0] = 0.0; /* Offset */ pars[1] = 5.0; /* Tau_0 */ pars[2] = -35.0; /* Amp_0 */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[0], opts, true, /* use_scaling */ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* Amp_0 */ par_test(pars[1], mypars[1], tol); /* Tau_0 */ par_test(pars[2], mypars[2], tol); /* Offset */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a monoexponential function, offset fixed to baseline // Stimfit function with ID = 1 //========================================================================= TEST(fitlib_test, id_01_monoexponential_offsetfixed){ /* choose function parameters */ Vector_double mypars(3); mypars[0] = 80.0; /* amplitude */ mypars[1] = 34.0; /* time constant */ mypars[2] = -5.52; /* offset */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexp_simple(mypars); #if 0 savetxt("/tmp/monoexp1.out", data); #endif /* Initial parameters guesses */ Vector_double pars(3); pars[0] = 35.5232; /* Amp_0 */ pars[1] = 14.6059; /* Tau_0 */ pars[2] = mypars[2]; /* Offset fixed to baseline */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[1], opts, true, /* use_scaling */ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* Amp_0 */ par_test(pars[1], mypars[1], tol); /* Tau_0 */ EXPECT_EQ(pars[2], mypars[2]); /* Offset to baseline */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a monoexponential function with delay, start to base // Stimfit function with ID = 2 //========================================================================= TEST(fitlib_test, id_02_monoexponential_with_delay){ /* choose function parameters */ Vector_double mypars(4); mypars[0] = 10.0; /* baseline */ mypars[1] = 15.0; /* delay */ mypars[2] = 17.0; /* time constant */ mypars[3] = 90.0; /* amplitude */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexpde(mypars); #if 0 savetxt(data); #endif /* Initial parameter guesses */ Vector_double pars(4); pars[0] = mypars[0]; pars[1] = 5.0; pars[2] = 50.0; pars[3] = 21.0; std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[2], opts, false, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* baseline */ par_test(pars[1], mypars[1], tol); /* delay */ par_test(pars[2], mypars[2], tol); /* time constant */ par_test(pars[3], mypars[3], tol); /* amplitude */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a biexponential // Stimfit function with ID = 3 //========================================================================= TEST(fitlib_test, id_03_biexponential){ /* choose function parameters */ Vector_double mypars(5); mypars[0] = 9.0; /* first amplitude */ mypars[1] = 2.0; /* first time constant */ mypars[2] = 1.0; /* second amplitude */ mypars[3] = 15.0; /* second time constant */ mypars[4] = 4.0; /* baseline */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexp(mypars); #if 0 savetxt("/tmp/mybiexp3.out", data); #endif /* Initial parameter guesses */ Vector_double pars(5); pars[0] = 4.86764; /* Amp_0 */ pars[1] = 2.44482; /* Tau_0 */ pars[2] = 4.86764; /* Amp_1 */ pars[3] = 19.5586; /* Tau_1 */ pars[4] = 4.26472; /* Offset */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[3], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* Amp_0 */ par_test(pars[1], mypars[1], tol); /* Tau_0 */ par_test(pars[2], mypars[2], tol); /* Amp_1 */ par_test(pars[3], mypars[3], tol); /* Tau_1 */ par_test(pars[4], mypars[4], tol); /* Offset */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a biexponential offset fixed to baseline // Stimfit function with ID = 4 //========================================================================= TEST(fitlib_test, id_04_biexponential_offsetfixed){ /* choose function parameters */ Vector_double mypars(5); mypars[0] = 16.0; /* first amplitude */ mypars[1] = 2.6; /* first time constant */ mypars[2] = 12.0; /* second amplitude */ mypars[3] = 15.0; /* second time constant */ mypars[4] = 4.0; /* baseline */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexp(mypars); #if 0 savetxt("/tmp/mybiexp3.out", data); #endif /* Initial parameter guesses */ Vector_double pars(5); pars[0] = 4.86764; /* Amp_0 */ pars[1] = 2.44482; /* Tau_0 */ pars[2] = 4.86764; /* Amp_1 */ pars[3] = 19.5586; /* Tau_1 */ pars[4] = 4.0; /* Offset */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[4], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* Amp_0 */ par_test(pars[1], mypars[1], tol); /* Tau_0 */ par_test(pars[2], mypars[2], tol); /* Amp_1 */ par_test(pars[3], mypars[3], tol); /* Tau_1 */ EXPECT_EQ(pars[4], mypars[4]); /* Offset */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a biexponential with delay, offset fixed to baseline // Stimfit function with ID = 5 //========================================================================= TEST(fitlib_test, id_05_biexponential_with_delay_offsetfixed){ /* choose function parameters */ Vector_double mypars(5); mypars[0] = 0.0; /* baseline */ mypars[1] = 25.0; /* Delay */ mypars[2] = 10.0; /* fast time constant */ mypars[3] = 25.0; /* Factor */ mypars[4] = 50.0; /* slow time constant */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexpbde(mypars); /* Initial parameter guesses */ Vector_double pars(5); pars[0] = mypars[0]; /* offset fixed to baseline! */ pars[1] = 0.1; /* Delay */ pars[2] = 19.925; /* tau1 */ pars[3] = 20.0; /* Factor */ pars[4] = 24.9875; /* tau2 */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[5], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); EXPECT_EQ(pars[0], mypars[0]); /* Offset fixed to baseline */ par_test(pars[1], mypars[1], tol); /* delay */ par_test(pars[2], mypars[2], tol); /* short time constant */ par_test(pars[3], mypars[3], tol); /* Factor != amplitude */ par_test(pars[4], mypars[4], tol); /* long time constant */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a triexponential // Stimfit function with ID = 6 //========================================================================= TEST(fitlib_test, id_06_triexponential){ /* choose function parameters */ Vector_double mypars(7); mypars[0] = 5.76; /* first amplitude */ mypars[1] = 3.37; /* first time constant */ mypars[2] = 5.76; /* second amplitude */ mypars[3] = 26.9; /* second time constant */ mypars[4] = 5.76; /* third amplitude */ mypars[5] = 91.0; /* third time constant */ mypars[6] = 5.07; /* baseline */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexp(mypars); #if 0 savetxt("/tmp/mytriexp6.out", data); #endif /* Initial parameter guesses */ Vector_double pars(7); pars[0] = 4.86764; /* Amp_0 */ pars[1] = 6.44482; /* Tau_0 */ pars[2] = 4.86764; /* Amp_1 */ pars[3] = 49.5586; /* Tau_1 */ pars[4] = 4.86764; /* Amp_2 */ pars[5] = 165.5586; /* Tau_2 */ pars[6] = 6.55319; /* Offset */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[6], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* Amp_0 */ par_test(pars[1], mypars[1], tol); /* Tau_0 */ par_test(pars[2], mypars[2], tol); /* Amp_1 */ par_test(pars[3], mypars[3], tol); /* Tau_1 */ par_test(pars[4], mypars[4], tol); /* Amp_2 */ par_test(pars[5], mypars[5], tol); /* Tau_2 */ par_test(pars[6], mypars[6], tol); /* Offset */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a triexponential free // Stimfit function with ID = 7 //========================================================================= TEST(fitlib_test, id_07_triexponential_free){ /* choose function parameters */ Vector_double mypars(7); mypars[0] = 15.76; /* first amplitude */ mypars[1] = 3.7; /* first time constant */ mypars[2] = 19.76; /* second amplitude */ mypars[3] = 21.9; /* second time constant */ mypars[4] = 2.76; /* third amplitude */ mypars[5] = 42.2; /* third time constant */ mypars[6] = -45.22; /* baseline */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexp(mypars); #if 0 savetxt("/tmp/mytriexp7.out", data); #endif /* Initial parameter guesses */ Vector_double pars(7); pars[0] = 4.86764; /* Amp_0 */ pars[1] = 6.44482; /* Tau_0 */ pars[2] = 4.86764; /* Amp_1 */ pars[3] = 49.5586; /* Tau_1 */ pars[4] = 4.86764; /* Amp_2 */ pars[5] = 65.5586; /* Tau_2 */ pars[6] = -34.242; /* Offset fixed to baseline */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[7], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* Amp_0 */ par_test(pars[1], mypars[1], tol); /* Tau_0 */ par_test(pars[2], mypars[2], tol); /* Amp_1 */ par_test(pars[3], mypars[3], tol); /* Tau_1 */ par_test(pars[4], mypars[4], tol); /* Amp_2 */ par_test(pars[5], mypars[5], tol); /* Tau_2 */ par_test(pars[6], mypars[6], tol); /* Offset */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a triexponential with offset fixed to baseline // Stimfit function with ID = 8 //========================================================================= TEST(fitlib_test, id_08_triexponential_offsetfixed){ /* choose function parameters */ Vector_double mypars(7); mypars[0] = 5.76; /* first amplitude */ mypars[1] = 3.37; /* first time constant */ mypars[2] = 9.76; /* second amplitude */ mypars[3] = 21.9; /* second time constant */ mypars[4] = 5.76; /* third amplitude */ mypars[5] = 41.0; /* third time constant */ mypars[6] = -5.12; /* baseline */ /* create a 100 ms trace with mypars */ Vector_double data; data = fexp(mypars); #if 0 savetxt("/tmp/mytriexp8.out", data); #endif /* Initial parameter guesses */ Vector_double pars(7); pars[0] = 4.86764; /* Amp_0 */ pars[1] = 6.44482; /* Tau_0 */ pars[2] = 4.86764; /* Amp_1 */ pars[3] = 49.5586; /* Tau_1 */ pars[4] = 4.86764; /* Amp_2 */ pars[5] = 165.5586; /* Tau_2 */ pars[6] = mypars[6]; /* Offset fixed to baseline */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[8], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* Amp_0 */ par_test(pars[1], mypars[1], tol); /* Tau_0 */ par_test(pars[2], mypars[2], tol); /* Amp_1 */ par_test(pars[3], mypars[3], tol); /* Tau_1 */ par_test(pars[4], mypars[4], tol); /* Amp_2 */ par_test(pars[5], mypars[5], tol); /* Tau_2 */ EXPECT_EQ(pars[6], mypars[6]); /* Offset */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to an alpha function, // Stimfit function with ID = 9 //========================================================================= TEST(fitlib_test, id_09_alpha){ /* choose function parameters */ Vector_double mypars(3); mypars[0] = 300.0; /* amplitude */ mypars[1] = 5.7; /* rate */ mypars[2] = 50.0; /* offset */ /* create a 100 ms trace with mypars */ Vector_double data; data = falpha(mypars); #if 0 savetxt(data); #endif /* Initial parameter guesses */ Vector_double pars(3); pars[0] = 350.0; /* amplitude */ pars[1] = 3.7; /* rate */ pars[2] = 0.0; /* Offset */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[9], opts, false, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* amplitude */ par_test(pars[1], mypars[1], tol); /* rate */ par_test(pars[2], mypars[2], tol); /* offset */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a HH-type sodium conductance, offset fixed to baseline // Stimfit function with ID =10 //========================================================================= TEST(fitlib_test, id_10_HH_gNa_offsetfixed){ /* choose function parameters */ Vector_double mypars(4); mypars[0] = 120.0; /* maximal sodium conductance */ mypars[1] = 130e-3; /* activation time constat (tau_m_) in us */ mypars[2] = 728e-3; /* inactivation time constant in us */ mypars[3] = 0.0; /* offset */ /* create a 100 ms trace with mypars */ /* here the x-units and x-axis values are not relevant */ Vector_double data; data = fHH(mypars); #if 0 savetxt("/tmp/gnabar.out", data); #endif /* Initial parameter guesses */ Vector_double pars(4); pars[0] = 1000.72; /* gprime_na */ pars[1] = 0.2001; /* tau_m */ pars[2] = 8.0; /* tau_h */ pars[3] = mypars[3]; /* offset fixed to baseline */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[10], opts, false, /* use_scaling */ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* gprime_na */ par_test(pars[1], mypars[1], tol); /* tau_m */ par_test(pars[2], mypars[2], tol); /* tau_h */ EXPECT_EQ(pars[3], mypars[3]); /* offset fixed to baseline */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a HH-type SINGLE sodium conductance, offset fixed to // baseline, Stimfit function with ID =11 //========================================================================= TEST(fitlib_test, id_11_HH_gNa_biexpoffsetfixed){ /* choose function parameters */ Vector_double mypars(4); mypars[0] = 120.0; /* maximal sodium conductance */ mypars[1] = 1.3; /* activation time constat (tau_m_) in us */ mypars[2] = 5.2; /* inactivation time constant in us */ mypars[3] = 10.0; /* offset */ /* create a 100 ms trace with mypars */ Vector_double data; data = fgnabiexp(mypars); #if 0 savetxt("/tmp/gnabar_single.out", data); #endif /* Initial parameter guesses */ Vector_double pars(4); pars[0] = 123.284; /* gprime_na */ pars[1] = 2.625; /* tau_m */ pars[2] = 15.75; /* tau_h */ pars[3] = mypars[3]; /* offset fixed to baseline */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[11], opts, false, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* gprime_na */ par_test(pars[1], mypars[1], tol); /* tau_m */ par_test(pars[2], mypars[2], tol); /* tau_h */ EXPECT_EQ(pars[3], mypars[3]); /* offset fixed to baseline */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif data.clear(); } //========================================================================= // Tests fitting to a gaussian distribution // Stimfit function with ID =12 //========================================================================= TEST(fitlib_test, id_12_fgaussian){ /* choose function parameters */ Vector_double mypars(3); mypars[0] = 1.5; /* height */ mypars[1] = 5.0; /* peak */ mypars[2] = 4.5; /* width */ /* create a trace with mypars */ Vector_double data; data = fgauss(mypars); #if 0 savetxt("/tmp/mygaussian.out", data); #endif /* Initial parameter guesses */ Vector_double pars(3); pars[0] = 1.72; /* amplitude */ pars[1] = 5.5; /* mean */ pars[2] = 2.0; /* width */ std::string info; int warning; double chisqr = stfnum::lmFit(data, dt, funcLib[12], opts, true, /*use_scaling*/ pars, info, warning ); EXPECT_EQ(warning, 0); par_test(pars[0], mypars[0], tol); /* amplitude */ par_test(pars[1], mypars[1], tol); /* peak */ par_test(pars[2], mypars[2], tol); /* witdth */ #if 0 debug_stdout(chisqr, info, warning, pars); #endif //data.clear(); } stimfit-0.16.7/src/test/section.cpp0000664000175000017500000000123414750344764012703 #include "../libstfio/stfio.h" #include TEST(Section_test, constructors) { Section sec0; EXPECT_EQ( sec0.size(), 0 ); Section sec1(Vector_double(32768, 0), "Test section"); EXPECT_EQ( sec1.size(), 32768 ); Section sec2(32768, "Test section"); EXPECT_EQ( sec2.size(), 32768 ); } TEST(Section_test, data_access) { Section sec1(Vector_double(32768, 0), "Test section"); EXPECT_EQ( sec1[sec1.size()-1], 0 ); EXPECT_THROW( sec1.at( sec1.size() ), std::out_of_range ); Section sec2(32768, "Test section"); EXPECT_EQ( sec2[sec2.size()-1], 0 ); EXPECT_THROW( sec2.at( sec2.size() ), std::out_of_range ); } stimfit-0.16.7/src/test/gtest/0000775000175000017500000000000014764352500011731 5stimfit-0.16.7/src/test/gtest/README0000664000175000017500000003733214750344764012551 Google C++ Testing Framework ============================ http://code.google.com/p/googletest/ Overview -------- Google's framework for writing C++ tests on a variety of platforms (Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the xUnit architecture. Supports automatic test discovery, a rich set of assertions, user-defined assertions, death tests, fatal and non-fatal failures, various options for running the tests, and XML test report generation. Please see the project page above for more information as well as the mailing list for questions, discussions, and development. There is also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please join us! Requirements for End Users -------------------------- Google Test is designed to have fairly minimal requirements to build and use with your projects, but there are some. Currently, we support Linux, Windows, Mac OS X, and Cygwin. We will also make our best effort to support other platforms (e.g. Solaris, AIX, and z/OS). However, since core members of the Google Test project have no access to these platforms, Google Test may have outstanding issues there. If you notice any problems on your platform, please notify googletestframework@googlegroups.com. Patches for fixing them are even more welcome! ### Linux Requirements ### These are the base requirements to build and use Google Test from a source package (as described below): * GNU-compatible Make or gmake * POSIX-standard shell * POSIX(-2) Regular Expressions (regex.h) * A C++98-standard-compliant compiler ### Windows Requirements ### * Microsoft Visual C++ 7.1 or newer ### Cygwin Requirements ### * Cygwin 1.5.25-14 or newer ### Mac OS X Requirements ### * Mac OS X 10.4 Tiger or newer * Developer Tools Installed Also, you'll need CMake 2.6.4 or higher if you want to build the samples using the provided CMake script, regardless of the platform. Requirements for Contributors ----------------------------- We welcome patches. If you plan to contribute a patch, you need to build Google Test and its own tests from an SVN checkout (described below), which has further requirements: * Python version 2.3 or newer (for running some of the tests and re-generating certain source files from templates) * CMake 2.6.4 or newer Getting the Source ------------------ There are two primary ways of getting Google Test's source code: you can download a stable source release in your preferred archive format, or directly check out the source from our Subversion (SVN) repositary. The SVN checkout requires a few extra steps and some extra software packages on your system, but lets you track the latest development and make patches much more easily, so we highly encourage it. ### Source Package ### Google Test is released in versioned source packages which can be downloaded from the download page [1]. Several different archive formats are provided, but the only difference is the tools used to manipulate them, and the size of the resulting file. Download whichever you are most comfortable with. [1] http://code.google.com/p/googletest/downloads/list Once the package is downloaded, expand it using whichever tools you prefer for that type. This will result in a new directory with the name "gtest-X.Y.Z" which contains all of the source code. Here are some examples on Linux: tar -xvzf gtest-X.Y.Z.tar.gz tar -xvjf gtest-X.Y.Z.tar.bz2 unzip gtest-X.Y.Z.zip ### SVN Checkout ### To check out the main branch (also known as the "trunk") of Google Test, run the following Subversion command: svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn Setting up the Build -------------------- To build Google Test and your tests that use it, you need to tell your build system where to find its headers and source files. The exact way to do it depends on which build system you use, and is usually straightforward. ### Generic Build Instructions ### Suppose you put Google Test in directory ${GTEST_DIR}. To build it, create a library build target (or a project as called by Visual Studio and Xcode) to compile ${GTEST_DIR}/src/gtest-all.cc with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR} in the normal header search path. Assuming a Linux-like system and gcc, something like the following will do: g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ -pthread -c ${GTEST_DIR}/src/gtest-all.cc ar -rv libgtest.a gtest-all.o (We need -pthread as Google Test uses threads.) Next, you should compile your test source file with ${GTEST_DIR}/include in the system header search path, and link it with gtest and any other necessary libraries: g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \ -o your_test As an example, the make/ directory contains a Makefile that you can use to build Google Test on systems where GNU make is available (e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google Test's own tests. Instead, it just builds the Google Test library and a sample test. You can use it as a starting point for your own build script. If the default settings are correct for your environment, the following commands should succeed: cd ${GTEST_DIR}/make make ./sample1_unittest If you see errors, try to tweak the contents of make/Makefile to make them go away. There are instructions in make/Makefile on how to do it. ### Using CMake ### Google Test comes with a CMake build script (CMakeLists.txt) that can be used on a wide range of platforms ("C" stands for cross-platofrm.). If you don't have CMake installed already, you can download it for free from http://www.cmake.org/. CMake works by generating native makefiles or build projects that can be used in the compiler environment of your choice. The typical workflow starts with: mkdir mybuild # Create a directory to hold the build output. cd mybuild cmake ${GTEST_DIR} # Generate native build scripts. If you want to build Google Test's samples, you should replace the last command with cmake -Dgtest_build_samples=ON ${GTEST_DIR} If you are on a *nix system, you should now see a Makefile in the current directory. Just type 'make' to build gtest. If you use Windows and have Vistual Studio installed, a gtest.sln file and several .vcproj files will be created. You can then build them using Visual Studio. On Mac OS X with Xcode installed, a .xcodeproj file will be generated. ### Legacy Build Scripts ### Before settling on CMake, we have been providing hand-maintained build projects/scripts for Visual Studio, Xcode, and Autotools. While we continue to provide them for convenience, they are not actively maintained any more. We highly recommend that you follow the instructions in the previous two sections to integrate Google Test with your existing build system. If you still need to use the legacy build scripts, here's how: The msvc\ folder contains two solutions with Visual C++ projects. Open the gtest.sln or gtest-md.sln file using Visual Studio, and you are ready to build Google Test the same way you build any Visual Studio project. Files that have names ending with -md use DLL versions of Microsoft runtime libraries (the /MD or the /MDd compiler option). Files without that suffix use static versions of the runtime libraries (the /MT or the /MTd option). Please note that one must use the same option to compile both gtest and the test code. If you use Visual Studio 2005 or above, we recommend the -md version as /MD is the default for new projects in these versions of Visual Studio. On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using Xcode. Build the "gtest" target. The universal binary framework will end up in your selected build directory (selected in the Xcode "Preferences..." -> "Building" pane and defaults to xcode/build). Alternatively, at the command line, enter: xcodebuild This will build the "Release" configuration of gtest.framework in your default build location. See the "xcodebuild" man page for more information about building different configurations and building in different locations. If you wish to use the Google Test Xcode project with Xcode 4.x and above, you need to either: * update the SDK configuration options in xcode/Config/General.xconfig. Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If you choose this route you lose the ability to target earlier versions of MacOS X. * Install an SDK for an earlier version. This doesn't appear to be supported by Apple, but has been reported to work (http://stackoverflow.com/questions/5378518). Tweaking Google Test -------------------- Google Test can be used in diverse environments. The default configuration may not work (or may not work well) out of the box in some environments. However, you can easily tweak Google Test by defining control macros on the compiler command line. Generally, these macros are named like GTEST_XYZ and you define them to either 1 or 0 to enable or disable a certain feature. We list the most frequently used macros below. For a complete list, see file include/gtest/internal/gtest-port.h. ### Choosing a TR1 Tuple Library ### Some Google Test features require the C++ Technical Report 1 (TR1) tuple library, which is not yet available with all compilers. The good news is that Google Test implements a subset of TR1 tuple that's enough for its own need, and will automatically use this when the compiler doesn't provide TR1 tuple. Usually you don't need to care about which tuple library Google Test uses. However, if your project already uses TR1 tuple, you need to tell Google Test to use the same TR1 tuple library the rest of your project uses, or the two tuple implementations will clash. To do that, add -DGTEST_USE_OWN_TR1_TUPLE=0 to the compiler flags while compiling Google Test and your tests. If you want to force Google Test to use its own tuple library, just add -DGTEST_USE_OWN_TR1_TUPLE=1 to the compiler flags instead. If you don't want Google Test to use tuple at all, add -DGTEST_HAS_TR1_TUPLE=0 and all features using tuple will be disabled. ### Multi-threaded Tests ### Google Test is thread-safe where the pthread library is available. After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE macro to see whether this is the case (yes if the macro is #defined to 1, no if it's undefined.). If Google Test doesn't correctly detect whether pthread is available in your environment, you can force it with -DGTEST_HAS_PTHREAD=1 or -DGTEST_HAS_PTHREAD=0 When Google Test uses pthread, you may need to add flags to your compiler and/or linker to select the pthread library, or you'll get link errors. If you use the CMake script or the deprecated Autotools script, this is taken care of for you. If you use your own build script, you'll need to read your compiler and linker's manual to figure out what flags to add. ### As a Shared Library (DLL) ### Google Test is compact, so most users can build and link it as a static library for the simplicity. You can choose to use Google Test as a shared library (known as a DLL on Windows) if you prefer. To compile *gtest* as a shared library, add -DGTEST_CREATE_SHARED_LIBRARY=1 to the compiler flags. You'll also need to tell the linker to produce a shared library instead - consult your linker's manual for how to do it. To compile your *tests* that use the gtest shared library, add -DGTEST_LINKED_AS_SHARED_LIBRARY=1 to the compiler flags. Note: while the above steps aren't technically necessary today when using some compilers (e.g. GCC), they may become necessary in the future, if we decide to improve the speed of loading the library (see http://gcc.gnu.org/wiki/Visibility for details). Therefore you are recommended to always add the above flags when using Google Test as a shared library. Otherwise a future release of Google Test may break your build script. ### Avoiding Macro Name Clashes ### In C++, macros don't obey namespaces. Therefore two libraries that both define a macro of the same name will clash if you #include both definitions. In case a Google Test macro clashes with another library, you can force Google Test to rename its macro to avoid the conflict. Specifically, if both Google Test and some other code define macro FOO, you can add -DGTEST_DONT_DEFINE_FOO=1 to the compiler flags to tell Google Test to change the macro's name from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST. For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write GTEST_TEST(SomeTest, DoesThis) { ... } instead of TEST(SomeTest, DoesThis) { ... } in order to define a test. Upgrating from an Earlier Version --------------------------------- We strive to keep Google Test releases backward compatible. Sometimes, though, we have to make some breaking changes for the users' long-term benefits. This section describes what you'll need to do if you are upgrading from an earlier version of Google Test. ### Upgrading from 1.3.0 or Earlier ### You may need to explicitly enable or disable Google Test's own TR1 tuple library. See the instructions in section "Choosing a TR1 Tuple Library". ### Upgrading from 1.4.0 or Earlier ### The Autotools build script (configure + make) is no longer officially supportted. You are encouraged to migrate to your own build system or use CMake. If you still need to use Autotools, you can find instructions in the README file from Google Test 1.4.0. On platforms where the pthread library is available, Google Test uses it in order to be thread-safe. See the "Multi-threaded Tests" section for what this means to your build script. If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google Test will no longer compile. This should affect very few people, as a large portion of STL (including ) doesn't compile in this mode anyway. We decided to stop supporting it in order to greatly simplify Google Test's implementation. Developing Google Test ---------------------- This section discusses how to make your own changes to Google Test. ### Testing Google Test Itself ### To make sure your changes work as intended and don't break existing functionality, you'll want to compile and run Google Test's own tests. For that you can use CMake: mkdir mybuild cd mybuild cmake -Dgtest_build_tests=ON ${GTEST_DIR} Make sure you have Python installed, as some of Google Test's tests are written in Python. If the cmake command complains about not being able to find Python ("Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)"), try telling it explicitly where your Python executable can be found: cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR} Next, you can build Google Test and all of its own tests. On *nix, this is usually done by 'make'. To run the tests, do make test All tests should pass. ### Regenerating Source Files ### Some of Google Test's source files are generated from templates (not in the C++ sense) using a script. A template file is named FOO.pump, where FOO is the name of the file it will generate. For example, the file include/gtest/internal/gtest-type-util.h.pump is used to generate gtest-type-util.h in the same directory. Normally you don't need to worry about regenerating the source files, unless you need to modify them. In that case, you should modify the corresponding .pump files instead and run the pump.py Python script to regenerate them. You can find pump.py in the scripts/ directory. Read the Pump manual [2] for how to use it. [2] http://code.google.com/p/googletest/wiki/PumpManual ### Contributing a Patch ### We welcome patches. Please read the Google Test developer's guide [3] for how you can contribute. In particular, make sure you have signed the Contributor License Agreement, or we won't be able to accept the patch. [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide Happy testing! stimfit-0.16.7/src/test/gtest/CHANGES0000664000175000017500000001476514750344764012671 Changes for 1.7.0: * New feature: death tests are supported on OpenBSD and in iOS simulator now. * New feature: Google Test now implements a protocol to allow a test runner to detect that a test program has exited prematurely and report it as a failure (before it would be falsely reported as a success if the exit code is 0). * New feature: Test::RecordProperty() can now be used outside of the lifespan of a test method, in which case it will be attributed to the current test case or the test program in the XML report. * New feature (potentially breaking): --gtest_list_tests now prints the type parameters and value parameters for each test. * Improvement: char pointers and char arrays are now escaped properly in failure messages. * Improvement: failure summary in XML reports now includes file and line information. * Improvement: the XML element now has a timestamp attribute. * Improvement: When --gtest_filter is specified, XML report now doesn't contain information about tests that are filtered out. * Fixed the bug where long --gtest_filter flag values are truncated in death tests. * Potentially breaking change: RUN_ALL_TESTS() is now implemented as a function instead of a macro in order to work better with Clang. * Compatibility fixes with C++ 11 and various platforms. * Bug/warning fixes. Changes for 1.6.0: * New feature: ADD_FAILURE_AT() for reporting a test failure at the given source location -- useful for writing testing utilities. * New feature: the universal value printer is moved from Google Mock to Google Test. * New feature: type parameters and value parameters are reported in the XML report now. * A gtest_disable_pthreads CMake option. * Colored output works in GNU Screen sessions now. * Parameters of value-parameterized tests are now printed in the textual output. * Failures from ad hoc test assertions run before RUN_ALL_TESTS() are now correctly reported. * Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to ostream. * More complete handling of exceptions. * GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter name is already used by another library. * --gtest_catch_exceptions is now true by default, allowing a test program to continue after an exception is thrown. * Value-parameterized test fixtures can now derive from Test and WithParamInterface separately, easing conversion of legacy tests. * Death test messages are clearly marked to make them more distinguishable from other messages. * Compatibility fixes for Android, Google Native Client, MinGW, HP UX, PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear), IBM XL C++ (Visual Age C++), and C++0x. * Bug fixes and implementation clean-ups. * Potentially incompatible changes: disables the harmful 'make install' command in autotools. Changes for 1.5.0: * New feature: assertions can be safely called in multiple threads where the pthreads library is available. * New feature: predicates used inside EXPECT_TRUE() and friends can now generate custom failure messages. * New feature: Google Test can now be compiled as a DLL. * New feature: fused source files are included. * New feature: prints help when encountering unrecognized Google Test flags. * Experimental feature: CMake build script (requires CMake 2.6.4+). * Experimental feature: the Pump script for meta programming. * double values streamed to an assertion are printed with enough precision to differentiate any two different values. * Google Test now works on Solaris and AIX. * Build and test script improvements. * Bug fixes and implementation clean-ups. Potentially breaking changes: * Stopped supporting VC++ 7.1 with exceptions disabled. * Dropped support for 'make install'. Changes for 1.4.0: * New feature: the event listener API * New feature: test shuffling * New feature: the XML report format is closer to junitreport and can be parsed by Hudson now. * New feature: when a test runs under Visual Studio, its failures are integrated in the IDE. * New feature: /MD(d) versions of VC++ projects. * New feature: elapsed time for the tests is printed by default. * New feature: comes with a TR1 tuple implementation such that Boost is no longer needed for Combine(). * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends. * New feature: the Xcode project can now produce static gtest libraries in addition to a framework. * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile, Symbian, gcc, and C++Builder. * Bug fixes and implementation clean-ups. Changes for 1.3.0: * New feature: death tests on Windows, Cygwin, and Mac. * New feature: ability to use Google Test assertions in other testing frameworks. * New feature: ability to run disabled test via --gtest_also_run_disabled_tests. * New feature: the --help flag for printing the usage. * New feature: access to Google Test flag values in user code. * New feature: a script that packs Google Test into one .h and one .cc file for easy deployment. * New feature: support for distributing test functions to multiple machines (requires support from the test runner). * Bug fixes and implementation clean-ups. Changes for 1.2.1: * Compatibility fixes for Linux IA-64 and IBM z/OS. * Added support for using Boost and other TR1 implementations. * Changes to the build scripts to support upcoming release of Google C++ Mocking Framework. * Added Makefile to the distribution package. * Improved build instructions in README. Changes for 1.2.0: * New feature: value-parameterized tests. * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS) macros. * Changed the XML report format to match JUnit/Ant's. * Added tests to the Xcode project. * Added scons/SConscript for building with SCons. * Added src/gtest-all.cc for building Google Test from a single file. * Fixed compatibility with Solaris and z/OS. * Enabled running Python tests on systems with python 2.3 installed, e.g. Mac OS X 10.4. * Bug fixes. Changes for 1.1.0: * New feature: type-parameterized tests. * New feature: exception assertions. * New feature: printing elapsed time of tests. * Improved the robustness of death tests. * Added an Xcode project and samples. * Adjusted the output format on Windows to be understandable by Visual Studio. * Minor bug fixes. Changes for 1.0.1: * Added project files for Visual Studio 7.1. * Fixed issues with compiling on Mac OS X. * Fixed issues with compiling on Cygwin. Changes for 1.0.0: * Initial Open Source release of Google Test stimfit-0.16.7/src/test/gtest/src/0000775000175000017500000000000014764352500012520 5stimfit-0.16.7/src/test/gtest/src/gtest-test-part.cc0000664000175000017500000001007714750344764016033 // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Author: mheule@google.com (Markus Heule) // // The Google C++ Testing Framework (Google Test) #include "gtest/gtest-test-part.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { using internal::GetUnitTestImpl; // Gets the summary of the failure message by omitting the stack trace // in it. std::string TestPartResult::ExtractSummary(const char* message) { const char* const stack_trace = strstr(message, internal::kStackTraceMarker); return stack_trace == NULL ? message : std::string(message, stack_trace); } // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { return os << result.file_name() << ":" << result.line_number() << ": " << (result.type() == TestPartResult::kSuccess ? "Success" : result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : "Non-fatal failure") << ":\n" << result.message() << std::endl; } // Appends a TestPartResult to the array. void TestPartResultArray::Append(const TestPartResult& result) { array_.push_back(result); } // Returns the TestPartResult at the given index (0-based). const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { if (index < 0 || index >= size()) { printf("\nInvalid index (%d) into TestPartResultArray.\n", index); internal::posix::Abort(); } return array_[index]; } // Returns the number of TestPartResult objects in the array. int TestPartResultArray::size() const { return static_cast(array_.size()); } namespace internal { HasNewFatalFailureHelper::HasNewFatalFailureHelper() : has_new_fatal_failure_(false), original_reporter_(GetUnitTestImpl()-> GetTestPartResultReporterForCurrentThread()) { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); } HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( original_reporter_); } void HasNewFatalFailureHelper::ReportTestPartResult( const TestPartResult& result) { if (result.fatally_failed()) has_new_fatal_failure_ = true; original_reporter_->ReportTestPartResult(result); } } // namespace internal } // namespace testing stimfit-0.16.7/src/test/gtest/src/gtest.cc0000664000175000017500000054751614750344764014127 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) #include "gtest/gtest.h" #include "gtest/gtest-spi.h" #include #include #include #include #include #include #include #include #include #include #include #include // NOLINT #include #include #if GTEST_OS_LINUX // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # include // NOLINT # include // NOLINT // Declares vsnprintf(). This header is not available on Windows. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # include #elif GTEST_OS_SYMBIAN # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT #elif GTEST_OS_ZOS # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT // On z/OS we additionally need strings.h for strcasecmp. # include // NOLINT #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. # include // NOLINT #elif GTEST_OS_WINDOWS // We are on Windows proper. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT #else // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT # include // NOLINT #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT #endif // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS # define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS namespace testing { using internal::CountIf; using internal::ForEach; using internal::GetElementOr; using internal::Shuffle; // Constants. // A test whose test case name or test name matches this filter is // disabled and not run. static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; // A test case whose name matches this filter is considered a death // test case and will be run before test cases whose name doesn't // match this filter. static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; // A test filter that matches everything. static const char kUniversalFilter[] = "*"; // The default output file for XML output. static const char kDefaultOutputFile[] = "test_detail.xml"; // The environment variable name for the test shard index. static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; // The environment variable name for the total number of test shards. static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard status file. static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; namespace internal { // The text used in failure messages to indicate the start of the // stack trace. const char kStackTraceMarker[] = "\nStack trace:\n"; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. bool g_help_flag = false; } // namespace internal static const char* GetDefaultFilter() { return kUniversalFilter; } GTEST_DEFINE_bool_( also_run_disabled_tests, internal::BoolFromGTestEnv("also_run_disabled_tests", false), "Run disabled tests too, in addition to the tests normally being run."); GTEST_DEFINE_bool_( break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), "True iff a failed assertion should be a debugger break-point."); GTEST_DEFINE_bool_( catch_exceptions, internal::BoolFromGTestEnv("catch_exceptions", true), "True iff " GTEST_NAME_ " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( color, internal::StringFromGTestEnv("color", "auto"), "Whether to use colors in the output. Valid values: yes, no, " "and auto. 'auto' means to use colors if the output is " "being sent to a terminal and the TERM environment variable " "is set to a terminal type that supports colors."); GTEST_DEFINE_string_( filter, internal::StringFromGTestEnv("filter", GetDefaultFilter()), "A colon-separated list of glob (not regex) patterns " "for filtering the tests to run, optionally followed by a " "'-' and a : separated list of negative patterns (tests to " "exclude). A test is run if it matches one of the positive " "patterns and does not match any of the negative patterns."); GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them."); GTEST_DEFINE_string_( output, internal::StringFromGTestEnv("output", ""), "A format (currently must be \"xml\"), optionally followed " "by a colon and an output file name or directory. A directory " "is indicated by a trailing pathname separator. " "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " "If a directory is specified, output files will be created " "within that directory, with file-names based on the test " "executable's name and, if necessary, made unique by adding " "digits."); GTEST_DEFINE_bool_( print_time, internal::BoolFromGTestEnv("print_time", true), "True iff " GTEST_NAME_ " should display elapsed time in text output."); GTEST_DEFINE_int32_( random_seed, internal::Int32FromGTestEnv("random_seed", 0), "Random number seed to use when shuffling test orders. Must be in range " "[1, 99999], or 0 to use a seed based on the current time."); GTEST_DEFINE_int32_( repeat, internal::Int32FromGTestEnv("repeat", 1), "How many times to repeat each test. Specify a negative number " "for repeating forever. Useful for shaking out flaky tests."); GTEST_DEFINE_bool_( show_internal_stack_frames, false, "True iff " GTEST_NAME_ " should include internal stack frames when " "printing test failure stack traces."); GTEST_DEFINE_bool_( shuffle, internal::BoolFromGTestEnv("shuffle", false), "True iff " GTEST_NAME_ " should randomize tests' order on every run."); GTEST_DEFINE_int32_( stack_trace_depth, internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); GTEST_DEFINE_string_( stream_result_to, internal::StringFromGTestEnv("stream_result_to", ""), "This flag specifies the host name and the port number on which to stream " "test results. Example: \"localhost:555\". The flag is effective only on " "Linux."); GTEST_DEFINE_bool_( throw_on_failure, internal::BoolFromGTestEnv("throw_on_failure", false), "When this flag is specified, a failed assertion will throw an exception " "if exceptions are enabled or exit the program with a non-zero code " "otherwise."); namespace internal { // Generates a random number from [0, range), using a Linear // Congruential Generator (LCG). Crashes if 'range' is 0 or greater // than kMaxRange. UInt32 Random::Generate(UInt32 range) { // These constants are the same as are used in glibc's rand(3). state_ = (1103515245U*state_ + 12345U) % kMaxRange; GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0)."; GTEST_CHECK_(range <= kMaxRange) << "Generation of a number in [0, " << range << ") was requested, " << "but this can only generate numbers in [0, " << kMaxRange << ")."; // Converting via modulus introduces a bit of downward bias, but // it's simple, and a linear congruential generator isn't too good // to begin with. return state_ % range; } // GTestIsInitialized() returns true iff the user has initialized // Google Test. Useful for catching the user mistake of not initializing // Google Test before calling RUN_ALL_TESTS(). // // A user must call testing::InitGoogleTest() to initialize Google // Test. g_init_gtest_count is set to the number of times // InitGoogleTest() has been called. We don't protect this variable // under a mutex as it is only accessed in the main thread. GTEST_API_ int g_init_gtest_count = 0; static bool GTestIsInitialized() { return g_init_gtest_count != 0; } // Iterates over a vector of TestCases, keeping a running sum of the // results of calling a given int-returning method on each. // Returns the sum. static int SumOverTestCaseList(const std::vector& case_list, int (TestCase::*method)() const) { int sum = 0; for (size_t i = 0; i < case_list.size(); i++) { sum += (case_list[i]->*method)(); } return sum; } // Returns true iff the test case passed. static bool TestCasePassed(const TestCase* test_case) { return test_case->should_run() && test_case->Passed(); } // Returns true iff the test case failed. static bool TestCaseFailed(const TestCase* test_case) { return test_case->should_run() && test_case->Failed(); } // Returns true iff test_case contains at least one test that should // run. static bool ShouldRunTestCase(const TestCase* test_case) { return test_case->should_run(); } // AssertHelper constructor. AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message) : data_(new AssertHelperData(type, file, line, message)) { } AssertHelper::~AssertHelper() { delete data_; } // Message assignment, for assertion streaming support. void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()-> AddTestPartResult(data_->type, data_->file, data_->line, AppendUserMessage(data_->message, message), UnitTest::GetInstance()->impl() ->CurrentOsStackTraceExceptTop(1) // Skips the stack frame for this function itself. ); // NOLINT } // Mutex for linked pointers. GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // Application pathname gotten in InitGoogleTest. std::string g_executable_path; // Returns the current application's name, removing directory path if that // is present. FilePath GetCurrentExecutableName() { FilePath result; #if GTEST_OS_WINDOWS result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); #endif // GTEST_OS_WINDOWS return result.RemoveDirectoryName(); } // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. std::string UnitTestOptions::GetOutputFormat() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return std::string(""); const char* const colon = strchr(gtest_output_flag, ':'); return (colon == NULL) ? std::string(gtest_output_flag) : std::string(gtest_output_flag, colon - gtest_output_flag); } // Returns the name of the requested output file, or the default if none // was explicitly specified. std::string UnitTestOptions::GetAbsolutePathToOutputFile() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return ""; const char* const colon = strchr(gtest_output_flag, ':'); if (colon == NULL) return internal::FilePath::ConcatPaths( internal::FilePath( UnitTest::GetInstance()->original_working_dir()), internal::FilePath(kDefaultOutputFile)).string(); internal::FilePath output_name(colon + 1); if (!output_name.IsAbsolutePath()) // TODO(wan@google.com): on Windows \some\path is not an absolute // path (as its meaning depends on the current drive), yet the // following logic for turning it into an absolute path is wrong. // Fix it. output_name = internal::FilePath::ConcatPaths( internal::FilePath(UnitTest::GetInstance()->original_working_dir()), internal::FilePath(colon + 1)); if (!output_name.IsDirectory()) return output_name.string(); internal::FilePath result(internal::FilePath::GenerateUniqueFileName( output_name, internal::GetCurrentExecutableName(), GetOutputFormat().c_str())); return result.string(); } // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. bool UnitTestOptions::PatternMatchesString(const char *pattern, const char *str) { switch (*pattern) { case '\0': case ':': // Either ':' or '\0' marks the end of the pattern. return *str == '\0'; case '?': // Matches any single character. return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); case '*': // Matches any string (possibly empty) of characters. return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || PatternMatchesString(pattern + 1, str); default: // Non-special character. Matches itself. return *pattern == *str && PatternMatchesString(pattern + 1, str + 1); } } bool UnitTestOptions::MatchesFilter( const std::string& name, const char* filter) { const char *cur_pattern = filter; for (;;) { if (PatternMatchesString(cur_pattern, name.c_str())) { return true; } // Finds the next pattern in the filter. cur_pattern = strchr(cur_pattern, ':'); // Returns if no more pattern can be found. if (cur_pattern == NULL) { return false; } // Skips the pattern separater (the ':' character). cur_pattern++; } } // Returns true iff the user-specified filter matches the test case // name and the test name. bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, const std::string &test_name) { const std::string& full_name = test_case_name + "." + test_name.c_str(); // Split --gtest_filter at '-', if there is one, to separate into // positive filter and negative filter portions const char* const p = GTEST_FLAG(filter).c_str(); const char* const dash = strchr(p, '-'); std::string positive; std::string negative; if (dash == NULL) { positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter negative = ""; } else { positive = std::string(p, dash); // Everything up to the dash negative = std::string(dash + 1); // Everything after the dash if (positive.empty()) { // Treat '-test1' as the same as '*-test1' positive = kUniversalFilter; } } // A filter is a colon-separated list of patterns. It matches a // test if any pattern in it matches the test. return (MatchesFilter(full_name, positive.c_str()) && !MatchesFilter(full_name, negative.c_str())); } #if GTEST_HAS_SEH // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { // Google Test should handle a SEH exception if: // 1. the user wants it to, AND // 2. this is not a breakpoint exception, AND // 3. this is not a C++ exception (VC++ implements them via SEH, // apparently). // // SEH exception code for C++ exceptions. // (see http://support.microsoft.com/kb/185294 for more information). const DWORD kCxxExceptionCode = 0xe06d7363; bool should_handle = true; if (!GTEST_FLAG(catch_exceptions)) should_handle = false; else if (exception_code == EXCEPTION_BREAKPOINT) should_handle = false; else if (exception_code == kCxxExceptionCode) should_handle = false; return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } #endif // GTEST_HAS_SEH } // namespace internal // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. Intercepts only failures from the current thread. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( TestPartResultArray* result) : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) { Init(); } // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( InterceptMode intercept_mode, TestPartResultArray* result) : intercept_mode_(intercept_mode), result_(result) { Init(); } void ScopedFakeTestPartResultReporter::Init() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { old_reporter_ = impl->GetGlobalTestPartResultReporter(); impl->SetGlobalTestPartResultReporter(this); } else { old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); impl->SetTestPartResultReporterForCurrentThread(this); } } // The d'tor restores the test part result reporter used by Google Test // before. ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { impl->SetGlobalTestPartResultReporter(old_reporter_); } else { impl->SetTestPartResultReporterForCurrentThread(old_reporter_); } } // Increments the test part result count and remembers the result. // This method is from the TestPartResultReporterInterface interface. void ScopedFakeTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { result_->Append(result); } namespace internal { // Returns the type ID of ::testing::Test. We should always call this // instead of GetTypeId< ::testing::Test>() to get the type ID of // testing::Test. This is to work around a suspected linker bug when // using Google Test as a framework on Mac OS X. The bug causes // GetTypeId< ::testing::Test>() to return different values depending // on whether the call is from the Google Test framework itself or // from user test code. GetTestTypeId() is guaranteed to always // return the same value, as it always calls GetTypeId<>() from the // gtest.cc, which is within the Google Test framework. TypeId GetTestTypeId() { return GetTypeId(); } // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); // This predicate-formatter checks that 'results' contains a test part // failure of the given type and that the failure message contains the // given substring. AssertionResult HasOneFailure(const char* /* results_expr */, const char* /* type_expr */, const char* /* substr_expr */, const TestPartResultArray& results, TestPartResult::Type type, const string& substr) { const std::string expected(type == TestPartResult::kFatalFailure ? "1 fatal failure" : "1 non-fatal failure"); Message msg; if (results.size() != 1) { msg << "Expected: " << expected << "\n" << " Actual: " << results.size() << " failures"; for (int i = 0; i < results.size(); i++) { msg << "\n" << results.GetTestPartResult(i); } return AssertionFailure() << msg; } const TestPartResult& r = results.GetTestPartResult(0); if (r.type() != type) { return AssertionFailure() << "Expected: " << expected << "\n" << " Actual:\n" << r; } if (strstr(r.message(), substr.c_str()) == NULL) { return AssertionFailure() << "Expected: " << expected << " containing \"" << substr << "\"\n" << " Actual:\n" << r; } return AssertionSuccess(); } // The constructor of SingleFailureChecker remembers where to look up // test part results, what type of failure we expect, and what // substring the failure message should contain. SingleFailureChecker:: SingleFailureChecker( const TestPartResultArray* results, TestPartResult::Type type, const string& substr) : results_(results), type_(type), substr_(substr) {} // The destructor of SingleFailureChecker verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. SingleFailureChecker::~SingleFailureChecker() { EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); } DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultGlobalTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->current_test_result()->AddTestPartResult(result); unit_test_->listeners()->repeater()->OnTestPartResult(result); } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); } // Returns the global test part result reporter. TestPartResultReporterInterface* UnitTestImpl::GetGlobalTestPartResultReporter() { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); return global_test_part_result_repoter_; } // Sets the global test part result reporter. void UnitTestImpl::SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter) { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); global_test_part_result_repoter_ = reporter; } // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* UnitTestImpl::GetTestPartResultReporterForCurrentThread() { return per_thread_test_part_result_reporter_.get(); } // Sets the test part result reporter for the current thread. void UnitTestImpl::SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter) { per_thread_test_part_result_reporter_.set(reporter); } // Gets the number of successful test cases. int UnitTestImpl::successful_test_case_count() const { return CountIf(test_cases_, TestCasePassed); } // Gets the number of failed test cases. int UnitTestImpl::failed_test_case_count() const { return CountIf(test_cases_, TestCaseFailed); } // Gets the number of all test cases. int UnitTestImpl::total_test_case_count() const { return static_cast(test_cases_.size()); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTestImpl::test_case_to_run_count() const { return CountIf(test_cases_, ShouldRunTestCase); } // Gets the number of successful tests. int UnitTestImpl::successful_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); } // Gets the number of failed tests. int UnitTestImpl::failed_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTestImpl::reportable_disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_disabled_test_count); } // Gets the number of disabled tests. int UnitTestImpl::disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); } // Gets the number of tests to be printed in the XML report. int UnitTestImpl::reportable_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); } // Gets the number of all tests. int UnitTestImpl::total_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); } // Gets the number of tests that should run. int UnitTestImpl::test_to_run_count() const { return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { (void)skip_count; return ""; } // Returns the current time in milliseconds. TimeInMillis GetTimeInMillis() { #if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) // Difference between 1970-01-01 and 1601-01-01 in milliseconds. // http://analogous.blogspot.com/2005/04/epoch.html const TimeInMillis kJavaEpochToWinFileTimeDelta = static_cast(116444736UL) * 100000UL; const DWORD kTenthMicrosInMilliSecond = 10000; SYSTEMTIME now_systime; FILETIME now_filetime; ULARGE_INTEGER now_int64; // TODO(kenton@google.com): Shouldn't this just use // GetSystemTimeAsFileTime()? GetSystemTime(&now_systime); if (SystemTimeToFileTime(&now_systime, &now_filetime)) { now_int64.LowPart = now_filetime.dwLowDateTime; now_int64.HighPart = now_filetime.dwHighDateTime; now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - kJavaEpochToWinFileTimeDelta; return now_int64.QuadPart; } return 0; #elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ __timeb64 now; # ifdef _MSC_VER // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 // (deprecated function) there. // TODO(kenton@google.com): Use GetTickCount()? Or use // SystemTimeToFileTime() # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4996) // Temporarily disables warning 4996. _ftime64(&now); # pragma warning(pop) // Restores the warning state. # else _ftime64(&now); # endif // _MSC_VER return static_cast(now.time) * 1000 + now.millitm; #elif GTEST_HAS_GETTIMEOFDAY_ struct timeval now; gettimeofday(&now, NULL); return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; #else # error "Don't know how to get the current time on your system." #endif } // Utilities // class String. #if GTEST_OS_WINDOWS_MOBILE // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. LPCWSTR String::AnsiToUtf16(const char* ansi) { if (!ansi) return NULL; const int length = strlen(ansi); const int unicode_length = MultiByteToWideChar(CP_ACP, 0, ansi, length, NULL, 0); WCHAR* unicode = new WCHAR[unicode_length + 1]; MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length); unicode[unicode_length] = 0; return unicode; } // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { if (!utf16_str) return NULL; const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, NULL, 0, NULL, NULL); char* ansi = new char[ansi_length + 1]; WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, NULL, NULL); ansi[ansi_length] = 0; return ansi; } #endif // GTEST_OS_WINDOWS_MOBILE // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::CStringEquals(const char * lhs, const char * rhs) { if ( lhs == NULL ) return rhs == NULL; if ( rhs == NULL ) return false; return strcmp(lhs, rhs) == 0; } #if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING // Converts an array of wide chars to a narrow string using the UTF-8 // encoding, and streams the result to the given Message object. static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, Message* msg) { for (size_t i = 0; i != length; ) { // NOLINT if (wstr[i] != L'\0') { *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); while (i != length && wstr[i] != L'\0') i++; } else { *msg << '\0'; i++; } } } #endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING } // namespace internal // Constructs an empty Message. // We allocate the stringstream separately because otherwise each use of // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's // stack frame leading to huge stack frames in some cases; gcc does not reuse // the stack space. Message::Message() : ss_(new ::std::stringstream) { // By default, we want there to be enough precision when printing // a double to a Message. *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& Message::operator <<(const wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } Message& Message::operator <<(wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::std::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". std::string Message::GetString() const { return internal::StringStreamToString(ss_.get()); } // AssertionResult constructors. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult::AssertionResult(const AssertionResult& other) : success_(other.success_), message_(other.message_.get() != NULL ? new ::std::string(*other.message_) : static_cast< ::std::string*>(NULL)) { } // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult AssertionResult::operator!() const { AssertionResult negation(!success_); if (message_.get() != NULL) negation << *message_; return negation; } // Makes a successful assertion result. AssertionResult AssertionSuccess() { return AssertionResult(true); } // Makes a failed assertion result. AssertionResult AssertionFailure() { return AssertionResult(false); } // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << message. AssertionResult AssertionFailure(const Message& message) { return AssertionFailure() << message; } namespace internal { // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case) { Message msg; msg << "Value of: " << actual_expression; if (actual_value != actual_expression) { msg << "\n Actual: " << actual_value; } msg << "\nExpected: " << expected_expression; if (ignoring_case) { msg << " (ignoring case)"; } if (expected_value != expected_expression) { msg << "\nWhich is: " << expected_value; } return AssertionFailure() << msg; } // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value) { const char* actual_message = assertion_result.message(); Message msg; msg << "Value of: " << expression_text << "\n Actual: " << actual_predicate_value; if (actual_message[0] != '\0') msg << " (" << actual_message << ")"; msg << "\nExpected: " << expected_predicate_value; return msg.GetString(); } // Helper function for implementing ASSERT_NEAR. AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error) { const double diff = fabs(val1 - val2); if (diff <= abs_error) return AssertionSuccess(); // TODO(wan): do not print the value of an expression if it's // already a literal. return AssertionFailure() << "The difference between " << expr1 << " and " << expr2 << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" << expr1 << " evaluates to " << val1 << ",\n" << expr2 << " evaluates to " << val2 << ", and\n" << abs_error_expr << " evaluates to " << abs_error << "."; } // Helper template for implementing FloatLE() and DoubleLE(). template AssertionResult FloatingPointLE(const char* expr1, const char* expr2, RawType val1, RawType val2) { // Returns success if val1 is less than val2, if (val1 < val2) { return AssertionSuccess(); } // or if val1 is almost equal to val2. const FloatingPoint lhs(val1), rhs(val2); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } // Note that the above two checks will both fail if either val1 or // val2 is NaN, as the IEEE floating-point standard requires that // any predicate involving a NaN must return false. ::std::stringstream val1_ss; val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val1; ::std::stringstream val2_ss; val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val2; return AssertionFailure() << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" << " Actual: " << StringStreamToString(&val1_ss) << " vs " << StringStreamToString(&val2_ss); } } // namespace internal // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } namespace internal { // The helper function for {ASSERT|EXPECT}_EQ with int or enum // arguments. AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { if (expected == actual) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here // just to avoid copy-and-paste of similar code. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ BiggestInt val1, BiggestInt val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return AssertionFailure() \ << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ }\ } // Implements the helper function for {ASSERT|EXPECT}_NE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(NE, !=) // Implements the helper function for {ASSERT|EXPECT}_LE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LE, <=) // Implements the helper function for {ASSERT|EXPECT}_LT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LT, < ) // Implements the helper function for {ASSERT|EXPECT}_GE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GE, >=) // Implements the helper function for {ASSERT|EXPECT}_GT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GT, > ) #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // The helper function for {ASSERT|EXPECT}_STRCASEEQ. AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CaseInsensitiveCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), true); } // The helper function for {ASSERT|EXPECT}_STRNE. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } // The helper function for {ASSERT|EXPECT}_STRCASENE. AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CaseInsensitiveCStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } } // namespace internal namespace { // Helper functions for implementing IsSubString() and IsNotSubstring(). // This group of overloaded functions return true iff needle is a // substring of haystack. NULL is considered a substring of itself // only. bool IsSubstringPred(const char* needle, const char* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return strstr(haystack, needle) != NULL; } bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return wcsstr(haystack, needle) != NULL; } // StringType here can be either ::std::string or ::std::wstring. template bool IsSubstringPred(const StringType& needle, const StringType& haystack) { return haystack.find(needle) != StringType::npos; } // This function implements either IsSubstring() or IsNotSubstring(), // depending on the value of the expected_to_be_substring parameter. // StringType here can be const char*, const wchar_t*, ::std::string, // or ::std::wstring. template AssertionResult IsSubstringImpl( bool expected_to_be_substring, const char* needle_expr, const char* haystack_expr, const StringType& needle, const StringType& haystack) { if (IsSubstringPred(needle, haystack) == expected_to_be_substring) return AssertionSuccess(); const bool is_wide_string = sizeof(needle[0]) > 1; const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; return AssertionFailure() << "Value of: " << needle_expr << "\n" << " Actual: " << begin_string_quote << needle << "\"\n" << "Expected: " << (expected_to_be_substring ? "" : "not ") << "a substring of " << haystack_expr << "\n" << "Which is: " << begin_string_quote << haystack << "\""; } } // namespace // IsSubstring() and IsNotSubstring() check whether needle is a // substring of haystack (NULL is considered a substring of itself // only), and return an appropriate error message when they fail. AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #if GTEST_HAS_STD_WSTRING AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #endif // GTEST_HAS_STD_WSTRING namespace internal { #if GTEST_OS_WINDOWS namespace { // Helper function for IsHRESULT{SuccessFailure} predicates AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't support FormatMessage. const char error_text[] = ""; # else // Looks up the human-readable system message for the HRESULT code // and since we're not passing any params to FormatMessage, we don't // want inserts expanded. const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; const DWORD kBufSize = 4096; // Gets the system's human readable message string for this HRESULT. char error_text[kBufSize] = { '\0' }; DWORD message_length = ::FormatMessageA(kFlags, 0, // no source, we're asking system hr, // the error 0, // no line width restrictions error_text, // output buffer kBufSize, // buf size NULL); // no arguments for inserts // Trims tailing white space (FormatMessage leaves a trailing CR-LF) for (; message_length && IsSpace(error_text[message_length - 1]); --message_length) { error_text[message_length - 1] = '\0'; } # endif // GTEST_OS_WINDOWS_MOBILE const std::string error_hex("0x" + String::FormatHexInt(hr)); return ::testing::AssertionFailure() << "Expected: " << expr << " " << expected << ".\n" << " Actual: " << error_hex << " " << error_text << "\n"; } } // namespace AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT if (SUCCEEDED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "succeeds", hr); } AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT if (FAILED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "fails", hr); } #endif // GTEST_OS_WINDOWS // Utility functions for encoding Unicode text (wide strings) in // UTF-8. // A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 // like this: // // Code-point length Encoding // 0 - 7 bits 0xxxxxxx // 8 - 11 bits 110xxxxx 10xxxxxx // 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // The maximum code-point a one-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; // The maximum code-point a two-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; // The maximum code-point a three-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; // The maximum code-point a four-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; // Chops off the n lowest bits from a bit pattern. Returns the n // lowest bits. As a side effect, the original bit pattern will be // shifted to the right by n bits. inline UInt32 ChopLowBits(UInt32* bits, int n) { const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); *bits >>= n; return low_bits; } // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". std::string CodePointToUtf8(UInt32 code_point) { if (code_point > kMaxCodePoint4) { return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; } char str[5]; // Big enough for the largest valid code point. if (code_point <= kMaxCodePoint1) { str[1] = '\0'; str[0] = static_cast(code_point); // 0xxxxxxx } else if (code_point <= kMaxCodePoint2) { str[2] = '\0'; str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xC0 | code_point); // 110xxxxx } else if (code_point <= kMaxCodePoint3) { str[3] = '\0'; str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xE0 | code_point); // 1110xxxx } else { // code_point <= kMaxCodePoint4 str[4] = '\0'; str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xF0 | code_point); // 11110xxx } return str; } // The following two functions only make sense if the the system // uses UTF-16 for wide string encoding. All supported systems // with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. // Determines if the arguments constitute UTF-16 surrogate pair // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, wchar_t second) { const UInt32 mask = (1 << 10) - 1; return (sizeof(wchar_t) == 2) ? (((first & mask) << 10) | (second & mask)) + 0x10000 : // This function should not be called when the condition is // false, but we provide a sensible default in case it is. static_cast(first); } // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. std::string WideStringToUtf8(const wchar_t* str, int num_chars) { if (num_chars == -1) num_chars = static_cast(wcslen(str)); ::std::stringstream stream; for (int i = 0; i < num_chars; ++i) { UInt32 unicode_code_point; if (str[i] == L'\0') { break; } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]); i++; } else { unicode_code_point = static_cast(str[i]); } stream << CodePointToUtf8(unicode_code_point); } return StringStreamToString(&stream); } // Converts a wide C string to an std::string using the UTF-8 encoding. // NULL will be converted to "(null)". std::string String::ShowWideCString(const wchar_t * wide_c_str) { if (wide_c_str == NULL) return "(null)"; return internal::WideStringToUtf8(wide_c_str, -1); } // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return wcscmp(lhs, rhs) == 0; } // Helper function for *_STREQ on wide strings. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual) { if (String::WideCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // Helper function for *_STRNE on wide strings. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2) { if (!String::WideCStringEquals(s1, s2)) { return AssertionSuccess(); } return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); } // Compares two C strings, ignoring case. Returns true iff they have // the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return posix::StrCaseCmp(lhs, rhs) == 0; } // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; #if GTEST_OS_WINDOWS return _wcsicmp(lhs, rhs) == 0; #elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID return wcscasecmp(lhs, rhs) == 0; #else // Android, Mac OS X and Cygwin don't define wcscasecmp. // Other unknown OSes may not define it either. wint_t left, right; do { left = towlower(*lhs++); right = towlower(*rhs++); } while (left && left == right); return left == right; #endif // OS selector } // Returns true iff str ends with the given suffix, ignoring case. // Any string is considered to end with an empty suffix. bool String::EndsWithCaseInsensitive( const std::string& str, const std::string& suffix) { const size_t str_len = str.length(); const size_t suffix_len = suffix.length(); return (str_len >= suffix_len) && CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, suffix.c_str()); } // Formats an int value as "%02d". std::string String::FormatIntWidth2(int value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << value; return ss.str(); } // Formats an int value as "%X". std::string String::FormatHexInt(int value) { std::stringstream ss; ss << std::hex << std::uppercase << value; return ss.str(); } // Formats a byte as "%02X". std::string String::FormatByte(unsigned char value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase << static_cast(value); return ss.str(); } // Converts the buffer in a stringstream to an std::string, converting NUL // bytes to "\\0" along the way. std::string StringStreamToString(::std::stringstream* ss) { const ::std::string& str = ss->str(); const char* const start = str.c_str(); const char* const end = start + str.length(); std::string result; result.reserve(2 * (end - start)); for (const char* ch = start; ch != end; ++ch) { if (*ch == '\0') { result += "\\0"; // Replaces NUL with "\\0"; } else { result += *ch; } } return result; } // Appends the user-supplied message to the Google-Test-generated message. std::string AppendUserMessage(const std::string& gtest_msg, const Message& user_msg) { // Appends the user message if it's non-empty. const std::string user_msg_string = user_msg.GetString(); if (user_msg_string.empty()) { return gtest_msg; } return gtest_msg + "\n" + user_msg_string; } } // namespace internal // class TestResult // Creates an empty TestResult. TestResult::TestResult() : death_test_count_(0), elapsed_time_(0) { } // D'tor. TestResult::~TestResult() { } // Returns the i-th test part result among all the results. i can // range from 0 to total_part_count() - 1. If i is not in that range, // aborts the program. const TestPartResult& TestResult::GetTestPartResult(int i) const { if (i < 0 || i >= total_part_count()) internal::posix::Abort(); return test_part_results_.at(i); } // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& TestResult::GetTestProperty(int i) const { if (i < 0 || i >= test_property_count()) internal::posix::Abort(); return test_properties_.at(i); } // Clears the test part results. void TestResult::ClearTestPartResults() { test_part_results_.clear(); } // Adds a test part result to the list. void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { test_part_results_.push_back(test_part_result); } // Adds a test property to the list. If a property with the same key as the // supplied property is already represented, the value of this test_property // replaces the old value for that key. void TestResult::RecordProperty(const std::string& xml_element, const TestProperty& test_property) { if (!ValidateTestProperty(xml_element, test_property)) { return; } internal::MutexLock lock(&test_properites_mutex_); const std::vector::iterator property_with_matching_key = std::find_if(test_properties_.begin(), test_properties_.end(), internal::TestPropertyKeyIs(test_property.key())); if (property_with_matching_key == test_properties_.end()) { test_properties_.push_back(test_property); return; } property_with_matching_key->SetValue(test_property.value()); } // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuitesAttributes[] = { "disabled", "errors", "failures", "name", "random_seed", "tests", "time", "timestamp" }; // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuiteAttributes[] = { "disabled", "errors", "failures", "name", "tests", "time" }; // The list of reserved attributes used in the element of XML output. static const char* const kReservedTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param" }; template std::vector ArrayAsVector(const char* const (&array)[kSize]) { return std::vector(array, array + kSize); } static std::vector GetReservedAttributesForElement( const std::string& xml_element) { if (xml_element == "testsuites") { return ArrayAsVector(kReservedTestSuitesAttributes); } else if (xml_element == "testsuite") { return ArrayAsVector(kReservedTestSuiteAttributes); } else if (xml_element == "testcase") { return ArrayAsVector(kReservedTestCaseAttributes); } else { GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; } // This code is unreachable but some compilers may not realizes that. return std::vector(); } static std::string FormatWordList(const std::vector& words) { Message word_list; for (size_t i = 0; i < words.size(); ++i) { if (i > 0 && words.size() > 2) { word_list << ", "; } if (i == words.size() - 1) { word_list << "and "; } word_list << "'" << words[i] << "'"; } return word_list.GetString(); } bool ValidateTestPropertyName(const std::string& property_name, const std::vector& reserved_names) { if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != reserved_names.end()) { ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name << " (" << FormatWordList(reserved_names) << " are reserved by " << GTEST_NAME_ << ")"; return false; } return true; } // Adds a failure if the key is a reserved attribute of the element named // xml_element. Returns true if the property is valid. bool TestResult::ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property) { return ValidateTestPropertyName(test_property.key(), GetReservedAttributesForElement(xml_element)); } // Clears the object. void TestResult::Clear() { test_part_results_.clear(); test_properties_.clear(); death_test_count_ = 0; elapsed_time_ = 0; } // Returns true iff the test failed. bool TestResult::Failed() const { for (int i = 0; i < total_part_count(); ++i) { if (GetTestPartResult(i).failed()) return true; } return false; } // Returns true iff the test part fatally failed. static bool TestPartFatallyFailed(const TestPartResult& result) { return result.fatally_failed(); } // Returns true iff the test fatally failed. bool TestResult::HasFatalFailure() const { return CountIf(test_part_results_, TestPartFatallyFailed) > 0; } // Returns true iff the test part non-fatally failed. static bool TestPartNonfatallyFailed(const TestPartResult& result) { return result.nonfatally_failed(); } // Returns true iff the test has a non-fatal failure. bool TestResult::HasNonfatalFailure() const { return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int TestResult::total_part_count() const { return static_cast(test_part_results_.size()); } // Returns the number of the test properties. int TestResult::test_property_count() const { return static_cast(test_properties_.size()); } // class Test // Creates a Test object. // The c'tor saves the values of all Google Test flags. Test::Test() : gtest_flag_saver_(new internal::GTestFlagSaver) { } // The d'tor restores the values of all Google Test flags. Test::~Test() { delete gtest_flag_saver_; } // Sets up the test fixture. // // A sub-class may override this. void Test::SetUp() { } // Tears down the test fixture. // // A sub-class may override this. void Test::TearDown() { } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, const std::string& value) { UnitTest::GetInstance()->RecordProperty(key, value); } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, int value) { Message value_message; value_message << value; RecordProperty(key, value_message.GetString().c_str()); } namespace internal { void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message) { // This function is a friend of UnitTest and as such has access to // AddTestPartResult. UnitTest::GetInstance()->AddTestPartResult( result_type, NULL, // No info about the source file where the exception occurred. -1, // We have no info on which line caused the exception. message, ""); // No stack trace, either. } } // namespace internal // Google Test requires all tests in the same test case to use the same test // fixture class. This function checks if the current test has the // same fixture class as the first test in the current test case. If // yes, it returns true; otherwise it generates a Google Test failure and // returns false. bool Test::HasSameFixtureClass() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); const TestCase* const test_case = impl->current_test_case(); // Info about the first test in the current test case. const TestInfo* const first_test_info = test_case->test_info_list()[0]; const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; const char* const first_test_name = first_test_info->name(); // Info about the current test. const TestInfo* const this_test_info = impl->current_test_info(); const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; const char* const this_test_name = this_test_info->name(); if (this_fixture_id != first_fixture_id) { // Is the first test defined using TEST? const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); // Is this test defined using TEST? const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); if (first_is_TEST || this_is_TEST) { // The user mixed TEST and TEST_F in this test case - we'll tell // him/her how to fix it. // Gets the name of the TEST and the name of the TEST_F. Note // that first_is_TEST and this_is_TEST cannot both be true, as // the fixture IDs are different for the two tests. const char* const TEST_name = first_is_TEST ? first_test_name : this_test_name; const char* const TEST_F_name = first_is_TEST ? this_test_name : first_test_name; ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class, so mixing TEST_F and TEST in the same test case is\n" << "illegal. In test case " << this_test_info->test_case_name() << ",\n" << "test " << TEST_F_name << " is defined using TEST_F but\n" << "test " << TEST_name << " is defined using TEST. You probably\n" << "want to change the TEST to TEST_F or move it to another test\n" << "case."; } else { // The user defined two fixture classes with the same name in // two namespaces - we'll tell him/her how to fix it. ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << this_test_info->test_case_name() << ",\n" << "you defined test " << first_test_name << " and test " << this_test_name << "\n" << "using two different test fixture classes. This can happen if\n" << "the two classes are from different namespaces or translation\n" << "units and have the same name. You should probably rename one\n" << "of the classes to put the tests into different test cases."; } return false; } return true; } #if GTEST_HAS_SEH // Adds an "exception thrown" fatal failure to the current test. This // function returns its result via an output parameter pointer because VC++ // prohibits creation of objects with destructors on stack in functions // using __try (see error C2712). static std::string* FormatSehExceptionMessage(DWORD exception_code, const char* location) { Message message; message << "SEH exception with code 0x" << std::setbase(16) << exception_code << std::setbase(10) << " thrown in " << location << "."; return new std::string(message.GetString()); } #endif // GTEST_HAS_SEH namespace internal { #if GTEST_HAS_EXCEPTIONS // Adds an "exception thrown" fatal failure to the current test. static std::string FormatCxxExceptionMessage(const char* description, const char* location) { Message message; if (description != NULL) { message << "C++ exception with description \"" << description << "\""; } else { message << "Unknown C++ exception"; } message << " thrown in " << location << "."; return message.GetString(); } static std::string PrintTestPartResultToString( const TestPartResult& test_part_result); GoogleTestFailureException::GoogleTestFailureException( const TestPartResult& failure) : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} #endif // GTEST_HAS_EXCEPTIONS // We put these helper functions in the internal namespace as IBM's xlC // compiler rejects the code if they were declared static. // Runs the given method and handles SEH exceptions it throws, when // SEH is supported; returns the 0-value for type Result in case of an // SEH exception. (Microsoft compilers cannot handle SEH and C++ // exceptions in the same function. Therefore, we provide a separate // wrapper function for handling SEH exceptions.) template Result HandleSehExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { #if GTEST_HAS_SEH __try { return (object->*method)(); } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT GetExceptionCode())) { // We create the exception message on the heap because VC++ prohibits // creation of objects with destructors on stack in functions using __try // (see error C2712). std::string* exception_message = FormatSehExceptionMessage( GetExceptionCode(), location); internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, *exception_message); delete exception_message; return static_cast(0); } #else (void)location; return (object->*method)(); #endif // GTEST_HAS_SEH } // Runs the given method and catches and reports C++ and/or SEH-style // exceptions, if they are supported; returns the 0-value for type // Result in case of an SEH exception. template Result HandleExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { // NOTE: The user code can affect the way in which Google Test handles // exceptions by setting GTEST_FLAG(catch_exceptions), but only before // RUN_ALL_TESTS() starts. It is technically possible to check the flag // after the exception is caught and either report or re-throw the // exception based on the flag's value: // // try { // // Perform the test method. // } catch (...) { // if (GTEST_FLAG(catch_exceptions)) // // Report the exception as failure. // else // throw; // Re-throws the original exception. // } // // However, the purpose of this flag is to allow the program to drop into // the debugger when the exception is thrown. On most platforms, once the // control enters the catch block, the exception origin information is // lost and the debugger will stop the program at the point of the // re-throw in this function -- instead of at the point of the original // throw statement in the code under test. For this reason, we perform // the check early, sacrificing the ability to affect Google Test's // exception handling in the method where the exception is thrown. if (internal::GetUnitTestImpl()->catch_exceptions()) { #if GTEST_HAS_EXCEPTIONS try { return HandleSehExceptionsInMethodIfSupported(object, method, location); } catch (const internal::GoogleTestFailureException&) { // NOLINT // This exception type can only be thrown by a failed Google // Test assertion with the intention of letting another testing // framework catch it. Therefore we just re-throw it. throw; } catch (const std::exception& e) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(e.what(), location)); } catch (...) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(NULL, location)); } return static_cast(0); #else return HandleSehExceptionsInMethodIfSupported(object, method, location); #endif // GTEST_HAS_EXCEPTIONS } else { return (object->*method)(); } } } // namespace internal // Runs the test and updates the test result. void Test::Run() { if (!HasSameFixtureClass()) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); // We will run the test only if SetUp() was successful. if (!HasFatalFailure()) { impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TestBody, "the test body"); } // However, we want to clean up as much as possible. Hence we will // always call TearDown(), even if SetUp() or the test body has // failed. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TearDown, "TearDown()"); } // Returns true iff the current test has a fatal failure. bool Test::HasFatalFailure() { return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); } // Returns true iff the current test has a non-fatal failure. bool Test::HasNonfatalFailure() { return internal::GetUnitTestImpl()->current_test_result()-> HasNonfatalFailure(); } // class TestInfo // Constructs a TestInfo object. It assumes ownership of the test factory // object. TestInfo::TestInfo(const std::string& a_test_case_name, const std::string& a_name, const char* a_type_param, const char* a_value_param, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) : test_case_name_(a_test_case_name), name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), value_param_(a_value_param ? new std::string(a_value_param) : NULL), fixture_class_id_(fixture_class_id), should_run_(false), is_disabled_(false), matches_filter_(false), factory_(factory), result_() {} // Destructs a TestInfo object. TestInfo::~TestInfo() { delete factory_; } namespace internal { // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param: text representation of the test's value parameter, // or NULL if this is not a value-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory) { TestInfo* const test_info = new TestInfo(test_case_name, name, type_param, value_param, fixture_class_id, factory); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); return test_info; } #if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line) { Message errors; errors << "Attempted redefinition of test case " << test_case_name << ".\n" << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << test_case_name << ", you tried\n" << "to define a test using a fixture class different from the one\n" << "used earlier. This can happen if the two fixture classes are\n" << "from different namespaces and have the same name. You should\n" << "probably rename one of the classes to put the tests into different\n" << "test cases."; fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors.GetString().c_str()); } #endif // GTEST_HAS_PARAM_TEST } // namespace internal namespace { // A predicate that checks the test name of a TestInfo against a known // value. // // This is used for implementation of the TestCase class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestNameIs is copyable. class TestNameIs { public: // Constructor. // // TestNameIs has NO default constructor. explicit TestNameIs(const char* name) : name_(name) {} // Returns true iff the test name of test_info matches name_. bool operator()(const TestInfo * test_info) const { return test_info && test_info->name() == name_; } private: std::string name_; }; } // namespace namespace internal { // This method expands all parameterized tests registered with macros TEST_P // and INSTANTIATE_TEST_CASE_P into regular tests and registers those. // This will be done just once during the program runtime. void UnitTestImpl::RegisterParameterizedTests() { #if GTEST_HAS_PARAM_TEST if (!parameterized_tests_registered_) { parameterized_test_registry_.RegisterTests(); parameterized_tests_registered_ = true; } #endif } } // namespace internal // Creates the test object, runs it, records its result, and then // deletes it. void TestInfo::Run() { if (!should_run_) return; // Tells UnitTest where to store test result. internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_info(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); // Notifies the unit test event listeners that a test is about to start. repeater->OnTestStart(*this); const TimeInMillis start = internal::GetTimeInMillis(); impl->os_stack_trace_getter()->UponLeavingGTest(); // Creates the test object. Test* const test = internal::HandleExceptionsInMethodIfSupported( factory_, &internal::TestFactoryBase::CreateTest, "the test fixture's constructor"); // Runs the test only if the test object was created and its // constructor didn't generate a fatal failure. if ((test != NULL) && !Test::HasFatalFailure()) { // This doesn't throw as all user code that can throw are wrapped into // exception handling code. test->Run(); } // Deletes the test object. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( test, &Test::DeleteSelf_, "the test fixture's destructor"); result_.set_elapsed_time(internal::GetTimeInMillis() - start); // Notifies the unit test event listener that a test has just finished. repeater->OnTestEnd(*this); // Tells UnitTest to stop associating assertion results to this // test. impl->set_current_test_info(NULL); } // class TestCase // Gets the number of successful tests in this test case. int TestCase::successful_test_count() const { return CountIf(test_info_list_, TestPassed); } // Gets the number of failed tests in this test case. int TestCase::failed_test_count() const { return CountIf(test_info_list_, TestFailed); } // Gets the number of disabled tests that will be reported in the XML report. int TestCase::reportable_disabled_test_count() const { return CountIf(test_info_list_, TestReportableDisabled); } // Gets the number of disabled tests in this test case. int TestCase::disabled_test_count() const { return CountIf(test_info_list_, TestDisabled); } // Gets the number of tests to be printed in the XML report. int TestCase::reportable_test_count() const { return CountIf(test_info_list_, TestReportable); } // Get the number of tests in this test case that should run. int TestCase::test_to_run_count() const { return CountIf(test_info_list_, ShouldRunTest); } // Gets the number of all tests. int TestCase::total_test_count() const { return static_cast(test_info_list_.size()); } // Creates a TestCase with the given name. // // Arguments: // // name: name of the test case // a_type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase::TestCase(const char* a_name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) : name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), elapsed_time_(0) { } // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. ForEach(test_info_list_, internal::Delete); } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* TestCase::GetTestInfo(int i) const { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* TestCase::GetMutableTestInfo(int i) { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. void TestCase::AddTestInfo(TestInfo * test_info) { test_info_list_.push_back(test_info); test_indices_.push_back(static_cast(test_indices_.size())); } // Runs every test in this TestCase. void TestCase::Run() { if (!should_run_) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_case(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); repeater->OnTestCaseStart(*this); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); const internal::TimeInMillis start = internal::GetTimeInMillis(); for (int i = 0; i < total_test_count(); i++) { GetMutableTestInfo(i)->Run(); } elapsed_time_ = internal::GetTimeInMillis() - start; impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); repeater->OnTestCaseEnd(*this); impl->set_current_test_case(NULL); } // Clears the results of all tests in this test case. void TestCase::ClearResult() { ad_hoc_test_result_.Clear(); ForEach(test_info_list_, TestInfo::ClearTestResult); } // Shuffles the tests in this test case. void TestCase::ShuffleTests(internal::Random* random) { Shuffle(random, &test_indices_); } // Restores the test order to before the first shuffle. void TestCase::UnshuffleTests() { for (size_t i = 0; i < test_indices_.size(); i++) { test_indices_[i] = static_cast(i); } } // Formats a countable noun. Depending on its quantity, either the // singular form or the plural form is used. e.g. // // FormatCountableNoun(1, "formula", "formuli") returns "1 formula". // FormatCountableNoun(5, "book", "books") returns "5 books". static std::string FormatCountableNoun(int count, const char * singular_form, const char * plural_form) { return internal::StreamableToString(count) + " " + (count == 1 ? singular_form : plural_form); } // Formats the count of tests. static std::string FormatTestCount(int test_count) { return FormatCountableNoun(test_count, "test", "tests"); } // Formats the count of test cases. static std::string FormatTestCaseCount(int test_case_count) { return FormatCountableNoun(test_case_count, "test case", "test cases"); } // Converts a TestPartResult::Type enum to human-friendly string // representation. Both kNonFatalFailure and kFatalFailure are translated // to "Failure", as the user usually doesn't care about the difference // between the two when viewing the test result. static const char * TestPartResultTypeToString(TestPartResult::Type type) { switch (type) { case TestPartResult::kSuccess: return "Success"; case TestPartResult::kNonFatalFailure: case TestPartResult::kFatalFailure: #ifdef _MSC_VER return "error: "; #else return "Failure\n"; #endif default: return "Unknown result type"; } } namespace internal { // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( const TestPartResult& test_part_result) { return (Message() << internal::FormatFileLocation(test_part_result.file_name(), test_part_result.line_number()) << " " << TestPartResultTypeToString(test_part_result.type()) << test_part_result.message()).GetString(); } // Prints a TestPartResult. static void PrintTestPartResult(const TestPartResult& test_part_result) { const std::string& result = PrintTestPartResultToString(test_part_result); printf("%s\n", result.c_str()); fflush(stdout); // If the test program runs in Visual Studio or a debugger, the // following statements add the test part result message to the Output // window such that the user can double-click on it to jump to the // corresponding source code location; otherwise they do nothing. #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // We don't call OutputDebugString*() on Windows Mobile, as printing // to stdout is done by OutputDebugString() there already - we don't // want the same message printed twice. ::OutputDebugStringA(result.c_str()); ::OutputDebugStringA("\n"); #endif } // class PrettyUnitTestResultPrinter enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { switch (color) { case COLOR_RED: return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN; case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; default: return 0; } } #else // Returns the ANSI color code for the given color. COLOR_DEFAULT is // an invalid input. const char* GetAnsiColorCode(GTestColor color) { switch (color) { case COLOR_RED: return "1"; case COLOR_GREEN: return "2"; case COLOR_YELLOW: return "3"; default: return NULL; }; } #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns true iff Google Test should use colors in the output. bool ShouldUseColor(bool stdout_is_tty) { const char* const gtest_color = GTEST_FLAG(color).c_str(); if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { #if GTEST_OS_WINDOWS // On Windows the TERM variable is usually not set, but the // console there does support colors. return stdout_is_tty; #else // On non-Windows platforms, we rely on the TERM variable. const char* const term = posix::GetEnv("TERM"); const bool term_supports_color = String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-256color") || String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen-256color") || String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; #endif // GTEST_OS_WINDOWS } return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || String::CaseInsensitiveCStringEquals(gtest_color, "true") || String::CaseInsensitiveCStringEquals(gtest_color, "t") || String::CStringEquals(gtest_color, "1"); // We take "yes", "true", "t", and "1" as meaning "yes". If the // value is neither one of these nor "auto", we treat it as "no" to // be conservative. } // Helpers for printing colored strings to stdout. Note that on Windows, we // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS const bool use_color = false; #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); const bool use_color = in_color_mode && (color != COLOR_DEFAULT); #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS // The '!= 0' comparison is necessary to satisfy MSVC 7.1. if (!use_color) { vprintf(fmt, args); va_end(args); return; } #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. CONSOLE_SCREEN_BUFFER_INFO buffer_info; GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); const WORD old_color_attrs = buffer_info.wAttributes; // We need to flush the stream buffers into the console before each // SetConsoleTextAttribute call lest it affect the text that is already // printed but has not yet reached the console. fflush(stdout); SetConsoleTextAttribute(stdout_handle, GetColorAttribute(color) | FOREGROUND_INTENSITY); vprintf(fmt, args); fflush(stdout); // Restores the text color. SetConsoleTextAttribute(stdout_handle, old_color_attrs); #else printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE va_end(args); } // Text printed in Google Test's text output and --gunit_list_tests // output to label the type parameter and value parameter for a test. static const char kTypeParamLabel[] = "TypeParam"; static const char kValueParamLabel[] = "GetParam()"; void PrintFullTestCommentIfPresent(const TestInfo& test_info) { const char* const type_param = test_info.type_param(); const char* const value_param = test_info.value_param(); if (type_param != NULL || value_param != NULL) { printf(", where "); if (type_param != NULL) { printf("%s = %s", kTypeParamLabel, type_param); if (value_param != NULL) printf(" and "); } if (value_param != NULL) { printf("%s = %s", kValueParamLabel, value_param); } } } // This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. class PrettyUnitTestResultPrinter : public TestEventListener { public: PrettyUnitTestResultPrinter() {} static void PrintTestName(const char * test_case, const char * test) { printf("%s.%s", test_case, test); } // The following methods override what's in the TestEventListener class. virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} private: static void PrintFailedTests(const UnitTest& unit_test); }; // Fired before each iteration of tests starts. void PrettyUnitTestResultPrinter::OnTestIterationStart( const UnitTest& unit_test, int iteration) { if (GTEST_FLAG(repeat) != 1) printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); const char* const filter = GTEST_FLAG(filter).c_str(); // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. if (!String::CStringEquals(filter, kUniversalFilter)) { ColoredPrintf(COLOR_YELLOW, "Note: %s filter = %s\n", GTEST_NAME_, filter); } if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); ColoredPrintf(COLOR_YELLOW, "Note: This is test shard %d of %s.\n", static_cast(shard_index) + 1, internal::posix::GetEnv(kTestTotalShards)); } if (GTEST_FLAG(shuffle)) { ColoredPrintf(COLOR_YELLOW, "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); } ColoredPrintf(COLOR_GREEN, "[==========] "); printf("Running %s from %s.\n", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment set-up.\n"); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s", counts.c_str(), test_case.name()); if (test_case.type_param() == NULL) { printf("\n"); } else { printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { ColoredPrintf(COLOR_GREEN, "[ RUN ] "); PrintTestName(test_info.test_case_name(), test_info.name()); printf("\n"); fflush(stdout); } // Called after an assertion failure. void PrettyUnitTestResultPrinter::OnTestPartResult( const TestPartResult& result) { // If the test part succeeded, we don't need to do anything. if (result.type() == TestPartResult::kSuccess) return; // Print failure message from the assertion (e.g. expected this and got that). PrintTestPartResult(result); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { if (test_info.result()->Passed()) { ColoredPrintf(COLOR_GREEN, "[ OK ] "); } else { ColoredPrintf(COLOR_RED, "[ FAILED ] "); } PrintTestName(test_info.test_case_name(), test_info.name()); if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info); if (GTEST_FLAG(print_time)) { printf(" (%s ms)\n", internal::StreamableToString( test_info.result()->elapsed_time()).c_str()); } else { printf("\n"); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { if (!GTEST_FLAG(print_time)) return; const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment tear-down\n"); fflush(stdout); } // Internal helper for printing the list of failed tests. void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { const int failed_test_count = unit_test.failed_test_count(); if (failed_test_count == 0) { return; } for (int i = 0; i < unit_test.total_test_case_count(); ++i) { const TestCase& test_case = *unit_test.GetTestCase(i); if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { continue; } for (int j = 0; j < test_case.total_test_count(); ++j) { const TestInfo& test_info = *test_case.GetTestInfo(j); if (!test_info.should_run() || test_info.result()->Passed()) { continue; } ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s.%s", test_case.name(), test_info.name()); PrintFullTestCommentIfPresent(test_info); printf("\n"); } } } void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { ColoredPrintf(COLOR_GREEN, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); if (GTEST_FLAG(print_time)) { printf(" (%s ms total)", internal::StreamableToString(unit_test.elapsed_time()).c_str()); } printf("\n"); ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); int num_failures = unit_test.failed_test_count(); if (!unit_test.Passed()) { const int failed_test_count = unit_test.failed_test_count(); ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); PrintFailedTests(unit_test); printf("\n%2d FAILED %s\n", num_failures, num_failures == 1 ? "TEST" : "TESTS"); } int num_disabled = unit_test.reportable_disabled_test_count(); if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { if (!num_failures) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } ColoredPrintf(COLOR_YELLOW, " YOU HAVE %d DISABLED %s\n\n", num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); } // Ensure that Google Test output is printed before, e.g., heapchecker output. fflush(stdout); } // End PrettyUnitTestResultPrinter // class TestEventRepeater // // This class forwards events to other event listeners. class TestEventRepeater : public TestEventListener { public: TestEventRepeater() : forwarding_enabled_(true) {} virtual ~TestEventRepeater(); void Append(TestEventListener *listener); TestEventListener* Release(TestEventListener* listener); // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled() const { return forwarding_enabled_; } void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } virtual void OnTestProgramStart(const UnitTest& unit_test); virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& unit_test); private: // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled_; // The list of listeners that receive events. std::vector listeners_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; TestEventRepeater::~TestEventRepeater() { ForEach(listeners_, Delete); } void TestEventRepeater::Append(TestEventListener *listener) { listeners_.push_back(listener); } // TODO(vladl@google.com): Factor the search functionality into Vector::Find. TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { for (size_t i = 0; i < listeners_.size(); ++i) { if (listeners_[i] == listener) { listeners_.erase(listeners_.begin() + i); return listener; } } return NULL; } // Since most methods are very similar, use macros to reduce boilerplate. // This defines a member that forwards the call to all listeners. #define GTEST_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (size_t i = 0; i < listeners_.size(); i++) { \ listeners_[i]->Name(parameter); \ } \ } \ } // This defines a member that forwards the call to all listeners in reverse // order. #define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ listeners_[i]->Name(parameter); \ } \ } \ } GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) #undef GTEST_REPEATER_METHOD_ #undef GTEST_REVERSE_REPEATER_METHOD_ void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (size_t i = 0; i < listeners_.size(); i++) { listeners_[i]->OnTestIterationStart(unit_test, iteration); } } } void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { listeners_[i]->OnTestIterationEnd(unit_test, iteration); } } } // End TestEventRepeater // This class generates an XML output file. class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: explicit XmlUnitTestResultPrinter(const char* output_file); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); private: // Is c a whitespace character that is normalized to a space character // when it appears in an XML attribute value? static bool IsNormalizableWhitespace(char c) { return c == 0x9 || c == 0xA || c == 0xD; } // May c appear in a well-formed XML document? static bool IsValidXmlCharacter(char c) { return IsNormalizableWhitespace(c) || c >= 0x20; } // Returns an XML-escaped copy of the input string str. If // is_attribute is true, the text is meant to appear as an attribute // value, and normalizable whitespace is preserved by replacing it // with character references. static std::string EscapeXml(const std::string& str, bool is_attribute); // Returns the given string with all characters invalid in XML removed. static std::string RemoveInvalidXmlCharacters(const std::string& str); // Convenience wrapper around EscapeXml when str is an attribute value. static std::string EscapeXmlAttribute(const std::string& str) { return EscapeXml(str, true); } // Convenience wrapper around EscapeXml when str is not an attribute value. static std::string EscapeXmlText(const char* str) { return EscapeXml(str, false); } // Verifies that the given attribute belongs to the given element and // streams the attribute as XML. static void OutputXmlAttribute(std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value); // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. static void OutputXmlCDataSection(::std::ostream* stream, const char* data); // Streams an XML representation of a TestInfo object. static void OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info); // Prints an XML representation of a TestCase object static void PrintXmlTestCase(::std::ostream* stream, const TestCase& test_case); // Prints an XML summary of unit_test to output stream out. static void PrintXmlUnitTest(::std::ostream* stream, const UnitTest& unit_test); // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. // When the std::string is not empty, it includes a space at the beginning, // to delimit this attribute from prior attributes. static std::string TestPropertiesAsXmlAttributes(const TestResult& result); // The output file. const std::string output_file_; GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; // Creates a new XmlUnitTestResultPrinter. XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) : output_file_(output_file) { if (output_file_.c_str() == NULL || output_file_.empty()) { fprintf(stderr, "XML output file may not be null\n"); fflush(stderr); exit(EXIT_FAILURE); } } // Called after the unit test ends. void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { FILE* xmlout = NULL; FilePath output_file(output_file_); FilePath output_dir(output_file.RemoveFileName()); if (output_dir.CreateDirectoriesRecursively()) { xmlout = posix::FOpen(output_file_.c_str(), "w"); } if (xmlout == NULL) { // TODO(wan): report the reason of the failure. // // We don't do it for now as: // // 1. There is no urgent need for it. // 2. It's a bit involved to make the errno variable thread-safe on // all three operating systems (Linux, Windows, and Mac OS). // 3. To interpret the meaning of errno in a thread-safe way, // we need the strerror_r() function, which is not available on // Windows. fprintf(stderr, "Unable to open file \"%s\"\n", output_file_.c_str()); fflush(stderr); exit(EXIT_FAILURE); } std::stringstream stream; PrintXmlUnitTest(&stream, unit_test); fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); fclose(xmlout); } // Returns an XML-escaped copy of the input string str. If is_attribute // is true, the text is meant to appear as an attribute value, and // normalizable whitespace is preserved by replacing it with character // references. // // Invalid XML characters in str, if any, are stripped from the output. // It is expected that most, if not all, of the text processed by this // module will consist of ordinary English text. // If this module is ever modified to produce version 1.1 XML output, // most invalid characters can be retained using character references. // TODO(wan): It might be nice to have a minimally invasive, human-readable // escaping scheme for invalid characters, rather than dropping them. std::string XmlUnitTestResultPrinter::EscapeXml( const std::string& str, bool is_attribute) { Message m; for (size_t i = 0; i < str.size(); ++i) { const char ch = str[i]; switch (ch) { case '<': m << "<"; break; case '>': m << ">"; break; case '&': m << "&"; break; case '\'': if (is_attribute) m << "'"; else m << '\''; break; case '"': if (is_attribute) m << """; else m << '"'; break; default: if (IsValidXmlCharacter(ch)) { if (is_attribute && IsNormalizableWhitespace(ch)) m << "&#x" << String::FormatByte(static_cast(ch)) << ";"; else m << ch; } break; } } return m.GetString(); } // Returns the given string with all characters invalid in XML removed. // Currently invalid characters are dropped from the string. An // alternative is to replace them with certain characters such as . or ?. std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( const std::string& str) { std::string output; output.reserve(str.size()); for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) if (IsValidXmlCharacter(*it)) output.push_back(*it); return output; } // The following routines generate an XML representation of a UnitTest // object. // // This is how Google Test concepts map to the DTD: // // <-- corresponds to a UnitTest object // <-- corresponds to a TestCase object // <-- corresponds to a TestInfo object // ... // ... // ... // <-- individual assertion failures // // // // Formats the given time in milliseconds as seconds. std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { ::std::stringstream ss; ss << ms/1000.0; return ss.str(); } // Converts the given epoch time in milliseconds to a date string in the ISO // 8601 format, without the timezone information. std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { // Using non-reentrant version as localtime_r is not portable. time_t seconds = static_cast(ms / 1000); #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4996) // Temporarily disables warning 4996 // (function or variable may be unsafe). const struct tm* const time_struct = localtime(&seconds); // NOLINT # pragma warning(pop) // Restores the warning state again. #else const struct tm* const time_struct = localtime(&seconds); // NOLINT #endif if (time_struct == NULL) return ""; // Invalid ms value // YYYY-MM-DDThh:mm:ss return StreamableToString(time_struct->tm_year + 1900) + "-" + String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + String::FormatIntWidth2(time_struct->tm_mday) + "T" + String::FormatIntWidth2(time_struct->tm_hour) + ":" + String::FormatIntWidth2(time_struct->tm_min) + ":" + String::FormatIntWidth2(time_struct->tm_sec); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, const char* data) { const char* segment = data; *stream << ""); if (next_segment != NULL) { stream->write( segment, static_cast(next_segment - segment)); *stream << "]]>]]>"); } else { *stream << segment; break; } } *stream << "]]>"; } void XmlUnitTestResultPrinter::OutputXmlAttribute( std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value) { const std::vector& allowed_names = GetReservedAttributesForElement(element_name); GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end()) << "Attribute " << name << " is not allowed for element <" << element_name << ">."; *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; } // Prints an XML representation of a TestInfo object. // TODO(wan): There is also value in printing properties with the plain printer. void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info) { const TestResult& result = *test_info.result(); const std::string kTestcase = "testcase"; *stream << " \n"; } const string location = internal::FormatCompilerIndependentFileLocation( part.file_name(), part.line_number()); const string summary = location + "\n" + part.summary(); *stream << " "; const string detail = location + "\n" + part.message(); OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); *stream << "\n"; } } if (failures == 0) *stream << " />\n"; else *stream << " \n"; } // Prints an XML representation of a TestCase object void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, const TestCase& test_case) { const std::string kTestsuite = "testsuite"; *stream << " <" << kTestsuite; OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); OutputXmlAttribute(stream, kTestsuite, "tests", StreamableToString(test_case.reportable_test_count())); OutputXmlAttribute(stream, kTestsuite, "failures", StreamableToString(test_case.failed_test_count())); OutputXmlAttribute( stream, kTestsuite, "disabled", StreamableToString(test_case.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuite, "errors", "0"); OutputXmlAttribute(stream, kTestsuite, "time", FormatTimeInMillisAsSeconds(test_case.elapsed_time())); *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) << ">\n"; for (int i = 0; i < test_case.total_test_count(); ++i) { if (test_case.GetTestInfo(i)->is_reportable()) OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); } *stream << " \n"; } // Prints an XML summary of unit_test to output stream out. void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, const UnitTest& unit_test) { const std::string kTestsuites = "testsuites"; *stream << "\n"; *stream << "<" << kTestsuites; OutputXmlAttribute(stream, kTestsuites, "tests", StreamableToString(unit_test.reportable_test_count())); OutputXmlAttribute(stream, kTestsuites, "failures", StreamableToString(unit_test.failed_test_count())); OutputXmlAttribute( stream, kTestsuites, "disabled", StreamableToString(unit_test.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuites, "errors", "0"); OutputXmlAttribute( stream, kTestsuites, "timestamp", FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); OutputXmlAttribute(stream, kTestsuites, "time", FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); if (GTEST_FLAG(shuffle)) { OutputXmlAttribute(stream, kTestsuites, "random_seed", StreamableToString(unit_test.random_seed())); } *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); *stream << ">\n"; for (int i = 0; i < unit_test.total_test_case_count(); ++i) { if (unit_test.GetTestCase(i)->reportable_test_count() > 0) PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); } *stream << "\n"; } // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( const TestResult& result) { Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); attributes << " " << property.key() << "=" << "\"" << EscapeXmlAttribute(property.value()) << "\""; } return attributes.GetString(); } // End XmlUnitTestResultPrinter #if GTEST_CAN_STREAM_RESULTS_ // Checks if str contains '=', '&', '%' or '\n' characters. If yes, // replaces them by "%xx" where xx is their hexadecimal value. For // example, replaces "=" with "%3D". This algorithm is O(strlen(str)) // in both time and space -- important as the input str may contain an // arbitrarily long test failure message and stack trace. string StreamingListener::UrlEncode(const char* str) { string result; result.reserve(strlen(str) + 1); for (char ch = *str; ch != '\0'; ch = *++str) { switch (ch) { case '%': case '=': case '&': case '\n': result.append("%" + String::FormatByte(static_cast(ch))); break; default: result.push_back(ch); break; } } return result; } void StreamingListener::SocketWriter::MakeConnection() { GTEST_CHECK_(sockfd_ == -1) << "MakeConnection() can't be called when there is already a connection."; addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. hints.ai_socktype = SOCK_STREAM; addrinfo* servinfo = NULL; // Use the getaddrinfo() to get a linked list of IP addresses for // the given host name. const int error_num = getaddrinfo( host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); if (error_num != 0) { GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " << gai_strerror(error_num); } // Loop through all the results and connect to the first we can. for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; cur_addr = cur_addr->ai_next) { sockfd_ = socket( cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); if (sockfd_ != -1) { // Connect the client socket to the server socket. if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { close(sockfd_); sockfd_ = -1; } } } freeaddrinfo(servinfo); // all done with this structure if (sockfd_ == -1) { GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " << host_name_ << ":" << port_num_; } } // End of class Streaming Listener #endif // GTEST_CAN_STREAM_RESULTS__ // Class ScopedTrace // Pushes the given source file location and message onto a per-thread // trace stack maintained by Google Test. ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { TraceInfo trace; trace.file = file; trace.line = line; trace.message = message.GetString(); UnitTest::GetInstance()->PushGTestTrace(trace); } // Pops the info pushed by the c'tor. ScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { UnitTest::GetInstance()->PopGTestTrace(); } // class OsStackTraceGetter // Returns the current OS stack trace as an std::string. Parameters: // // max_depth - the maximum number of stack frames to be included // in the trace. // skip_count - the number of top frames to be skipped; doesn't count // against max_depth. // string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, int /* skip_count */) GTEST_LOCK_EXCLUDED_(mutex_) { return ""; } void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { } const char* const OsStackTraceGetter::kElidedFramesMarker = "... " GTEST_NAME_ " internal frames ..."; // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. class ScopedPrematureExitFile { public: explicit ScopedPrematureExitFile(const char* premature_exit_filepath) : premature_exit_filepath_(premature_exit_filepath) { // If a path to the premature-exit file is specified... if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { // create the file with a single "0" character in it. I/O // errors are ignored as there's nothing better we can do and we // don't want to fail the test because of this. FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); fwrite("0", 1, 1, pfile); fclose(pfile); } } ~ScopedPrematureExitFile() { if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { remove(premature_exit_filepath_); } } private: const char* const premature_exit_filepath_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); }; } // namespace internal // class TestEventListeners TestEventListeners::TestEventListeners() : repeater_(new internal::TestEventRepeater()), default_result_printer_(NULL), default_xml_generator_(NULL) { } TestEventListeners::~TestEventListeners() { delete repeater_; } // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the user. void TestEventListeners::Append(TestEventListener* listener) { repeater_->Append(listener); } // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* TestEventListeners::Release(TestEventListener* listener) { if (listener == default_result_printer_) default_result_printer_ = NULL; else if (listener == default_xml_generator_) default_xml_generator_ = NULL; return repeater_->Release(listener); } // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* TestEventListeners::repeater() { return repeater_; } // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { if (default_result_printer_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_result_printer_); default_result_printer_ = listener; if (listener != NULL) Append(listener); } } // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { if (default_xml_generator_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_xml_generator_); default_xml_generator_ = listener; if (listener != NULL) Append(listener); } } // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool TestEventListeners::EventForwardingEnabled() const { return repeater_->forwarding_enabled(); } void TestEventListeners::SuppressEventForwarding() { repeater_->set_forwarding_enabled(false); } // class UnitTest // Gets the singleton UnitTest object. The first time this method is // called, a UnitTest object is constructed and returned. Consecutive // calls will return the same object. // // We don't protect this under mutex_ as a user is not supposed to // call this before main() starts, from which point on the return // value will never change. UnitTest* UnitTest::GetInstance() { // When compiled with MSVC 7.1 in optimized mode, destroying the // UnitTest object upon exiting the program messes up the exit code, // causing successful tests to appear failed. We have to use a // different implementation in this case to bypass the compiler bug. // This implementation makes the compiler happy, at the cost of // leaking the UnitTest object. // CodeGear C++Builder insists on a public destructor for the // default implementation. Use this implementation to keep good OO // design with private destructor. #if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) static UnitTest* const instance = new UnitTest; return instance; #else static UnitTest instance; return &instance; #endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) } // Gets the number of successful test cases. int UnitTest::successful_test_case_count() const { return impl()->successful_test_case_count(); } // Gets the number of failed test cases. int UnitTest::failed_test_case_count() const { return impl()->failed_test_case_count(); } // Gets the number of all test cases. int UnitTest::total_test_case_count() const { return impl()->total_test_case_count(); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTest::test_case_to_run_count() const { return impl()->test_case_to_run_count(); } // Gets the number of successful tests. int UnitTest::successful_test_count() const { return impl()->successful_test_count(); } // Gets the number of failed tests. int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTest::reportable_disabled_test_count() const { return impl()->reportable_disabled_test_count(); } // Gets the number of disabled tests. int UnitTest::disabled_test_count() const { return impl()->disabled_test_count(); } // Gets the number of tests to be printed in the XML report. int UnitTest::reportable_test_count() const { return impl()->reportable_test_count(); } // Gets the number of all tests. int UnitTest::total_test_count() const { return impl()->total_test_count(); } // Gets the number of tests that should run. int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } // Gets the time of the test program start, in ms from the start of the // UNIX epoch. internal::TimeInMillis UnitTest::start_timestamp() const { return impl()->start_timestamp(); } // Gets the elapsed time, in milliseconds. internal::TimeInMillis UnitTest::elapsed_time() const { return impl()->elapsed_time(); } // Returns true iff the unit test passed (i.e. all test cases passed). bool UnitTest::Passed() const { return impl()->Passed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool UnitTest::Failed() const { return impl()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* UnitTest::GetTestCase(int i) const { return impl()->GetTestCase(i); } // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& UnitTest::ad_hoc_test_result() const { return *impl()->ad_hoc_test_result(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* UnitTest::GetMutableTestCase(int i) { return impl()->GetMutableTestCase(i); } // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); } // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in the // order they were registered. After all tests in the program have // finished, all global test environments will be torn-down in the // *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // We don't protect this under mutex_, as we only support calling it // from the main thread. Environment* UnitTest::AddEnvironment(Environment* env) { if (env == NULL) { return NULL; } impl_->environments().push_back(env); return env; } // Adds a TestPartResult to the current TestResult object. All Google Test // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the // assertion macros instead of calling this directly. void UnitTest::AddTestPartResult( TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { Message msg; msg << message; internal::MutexLock lock(&mutex_); if (impl_->gtest_trace_stack().size() > 0) { msg << "\n" << GTEST_NAME_ << " trace:"; for (int i = static_cast(impl_->gtest_trace_stack().size()); i > 0; --i) { const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) << " " << trace.message; } } if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { msg << internal::kStackTraceMarker << os_stack_trace; } const TestPartResult result = TestPartResult(result_type, file_name, line_number, msg.GetString().c_str()); impl_->GetTestPartResultReporterForCurrentThread()-> ReportTestPartResult(result); if (result_type != TestPartResult::kSuccess) { // gtest_break_on_failure takes precedence over // gtest_throw_on_failure. This allows a user to set the latter // in the code (perhaps in order to use Google Test assertions // with another testing framework) and specify the former on the // command line for debugging. if (GTEST_FLAG(break_on_failure)) { #if GTEST_OS_WINDOWS // Using DebugBreak on Windows allows gtest to still break into a debugger // when a failure happens and both the --gtest_break_on_failure and // the --gtest_catch_exceptions flags are specified. DebugBreak(); #else // Dereference NULL through a volatile pointer to prevent the compiler // from removing. We use this rather than abort() or __builtin_trap() for // portability: Symbian doesn't implement abort() well, and some debuggers // don't correctly trap abort(). *static_cast(NULL) = 1; #endif // GTEST_OS_WINDOWS } else if (GTEST_FLAG(throw_on_failure)) { #if GTEST_HAS_EXCEPTIONS throw internal::GoogleTestFailureException(result); #else // We cannot call abort() as it generates a pop-up in debug mode // that cannot be suppressed in VC 7.1 or below. exit(1); #endif } } } // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void UnitTest::RecordProperty(const std::string& key, const std::string& value) { impl_->RecordProperty(TestProperty(key, value)); } // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { const bool in_death_test_child_process = internal::GTEST_FLAG(internal_run_death_test).length() > 0; // Google Test implements this protocol for catching that a test // program exits before returning control to Google Test: // // 1. Upon start, Google Test creates a file whose absolute path // is specified by the environment variable // TEST_PREMATURE_EXIT_FILE. // 2. When Google Test has finished its work, it deletes the file. // // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before // running a Google-Test-based test program and check the existence // of the file at the end of the test execution to see if it has // exited prematurely. // If we are in the child process of a death test, don't // create/delete the premature exit file, as doing so is unnecessary // and will confuse the parent process. Otherwise, create/delete // the file upon entering/leaving this function. If the program // somehow exits before this function has a chance to return, the // premature-exit file will be left undeleted, causing a test runner // that understands the premature-exit-file protocol to report the // test as having failed. const internal::ScopedPrematureExitFile premature_exit_file( in_death_test_child_process ? NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); // Captures the value of GTEST_FLAG(catch_exceptions). This value will be // used for the duration of the program. impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); #if GTEST_HAS_SEH // Either the user wants Google Test to catch exceptions thrown by the // tests or this is executing in the context of death test child // process. In either case the user does not want to see pop-up dialogs // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { # if !GTEST_OS_WINDOWS_MOBILE // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); # endif // !GTEST_OS_WINDOWS_MOBILE # if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); # endif # if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement // executed. Google Test will notify the user of any unexpected // failure via stderr. // // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. // Users of prior VC versions shall suffer the agony and pain of // clicking through the countless debug dialogs. // TODO(vladl@google.com): find a way to suppress the abort dialog() in the // debug mode when compiled with VC 7.1 or lower. if (!GTEST_FLAG(break_on_failure)) _set_abort_behavior( 0x0, // Clear the following flags: _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. # endif } #endif // GTEST_HAS_SEH return internal::HandleExceptionsInMethodIfSupported( impl(), &internal::UnitTestImpl::RunAllTests, "auxiliary test code (environments or event listeners)") ? 0 : 1; } // Returns the working directory when the first TEST() or TEST_F() was // executed. const char* UnitTest::original_working_dir() const { return impl_->original_working_dir_.c_str(); } // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* UnitTest::current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_case(); } // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* UnitTest::current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_info(); } // Returns the random seed used at the start of the current test run. int UnitTest::random_seed() const { return impl_->random_seed(); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { return impl_->parameterized_test_registry(); } #endif // GTEST_HAS_PARAM_TEST // Creates an empty UnitTest. UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); } // Destructor of UnitTest. UnitTest::~UnitTest() { delete impl_; } // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().pop_back(); } namespace internal { UnitTestImpl::UnitTestImpl(UnitTest* parent) : parent_(parent), #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4355) // Temporarily disables warning 4355 // (using this in initializer). default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), # pragma warning(pop) // Restores the warning state again. #else default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), #endif // _MSC_VER global_test_part_result_repoter_( &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), #if GTEST_HAS_PARAM_TEST parameterized_test_registry_(), parameterized_tests_registered_(false), #endif // GTEST_HAS_PARAM_TEST last_death_test_case_(-1), current_test_case_(NULL), current_test_info_(NULL), ad_hoc_test_result_(), os_stack_trace_getter_(NULL), post_flag_parse_init_performed_(false), random_seed_(0), // Will be overridden by the flag before first use. random_(0), // Will be reseeded before first use. start_timestamp_(0), elapsed_time_(0), #if GTEST_HAS_DEATH_TEST death_test_factory_(new DefaultDeathTestFactory), #endif // Will be overridden by the flag before first use. catch_exceptions_(false) { listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. ForEach(test_cases_, internal::Delete); // Deletes every Environment. ForEach(environments_, internal::Delete); delete os_stack_trace_getter_; } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test, to current test case's ad_hoc_test_result when invoke // from SetUpTestCase/TearDownTestCase, or to the global property set // otherwise. If the result already contains a property with the same key, // the value will be updated. void UnitTestImpl::RecordProperty(const TestProperty& test_property) { std::string xml_element; TestResult* test_result; // TestResult appropriate for property recording. if (current_test_info_ != NULL) { xml_element = "testcase"; test_result = &(current_test_info_->result_); } else if (current_test_case_ != NULL) { xml_element = "testsuite"; test_result = &(current_test_case_->ad_hoc_test_result_); } else { xml_element = "testsuites"; test_result = &ad_hoc_test_result_; } test_result->RecordProperty(xml_element, test_property); } #if GTEST_HAS_DEATH_TEST // Disables event forwarding if the control is currently in a death test // subprocess. Must not be called before InitGoogleTest. void UnitTestImpl::SuppressTestEventsIfInSubprocess() { if (internal_run_death_test_flag_.get() != NULL) listeners()->SuppressEventForwarding(); } #endif // GTEST_HAS_DEATH_TEST // Initializes event listeners performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureXmlOutput() { const std::string& output_format = UnitTestOptions::GetOutputFormat(); if (output_format == "xml") { listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); } else if (output_format != "") { printf("WARNING: unrecognized output format \"%s\" ignored.\n", output_format.c_str()); fflush(stdout); } } #if GTEST_CAN_STREAM_RESULTS_ // Initializes event listeners for streaming test results in string form. // Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureStreamingOutput() { const std::string& target = GTEST_FLAG(stream_result_to); if (!target.empty()) { const size_t pos = target.find(':'); if (pos != std::string::npos) { listeners()->Append(new StreamingListener(target.substr(0, pos), target.substr(pos+1))); } else { printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", target.c_str()); fflush(stdout); } } } #endif // GTEST_CAN_STREAM_RESULTS_ // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void UnitTestImpl::PostFlagParsingInit() { // Ensures that this function does not execute more than once. if (!post_flag_parse_init_performed_) { post_flag_parse_init_performed_ = true; #if GTEST_HAS_DEATH_TEST InitDeathTestSubprocessControlInfo(); SuppressTestEventsIfInSubprocess(); #endif // GTEST_HAS_DEATH_TEST // Registers parameterized tests. This makes parameterized tests // available to the UnitTest reflection API without running // RUN_ALL_TESTS. RegisterParameterizedTests(); // Configures listeners for XML output. This makes it possible for users // to shut down the default XML output before invoking RUN_ALL_TESTS. ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Configures listeners for streaming test results to the specified server. ConfigureStreamingOutput(); #endif // GTEST_CAN_STREAM_RESULTS_ } } // A predicate that checks the name of a TestCase against a known // value. // // This is used for implementation of the UnitTest class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestCaseNameIs is copyable. class TestCaseNameIs { public: // Constructor. explicit TestCaseNameIs(const std::string& name) : name_(name) {} // Returns true iff the name of test_case matches name_. bool operator()(const TestCase* test_case) const { return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; } private: std::string name_; }; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. It's the CALLER'S // RESPONSIBILITY to ensure that this function is only called WHEN THE // TESTS ARE NOT SHUFFLED. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) { // Can we find a TestCase with the given name? const std::vector::const_iterator test_case = std::find_if(test_cases_.begin(), test_cases_.end(), TestCaseNameIs(test_case_name)); if (test_case != test_cases_.end()) return *test_case; // No. Let's create one. TestCase* const new_test_case = new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); // Is this a death test case? if (internal::UnitTestOptions::MatchesFilter(test_case_name, kDeathTestCaseFilter)) { // Yes. Inserts the test case after the last death test case // defined so far. This only works when the test cases haven't // been shuffled. Otherwise we may end up running a death test // after a non-death test. ++last_death_test_case_; test_cases_.insert(test_cases_.begin() + last_death_test_case_, new_test_case); } else { // No. Appends to the end of the list. test_cases_.push_back(new_test_case); } test_case_indices_.push_back(static_cast(test_case_indices_.size())); return new_test_case; } // Helpers for setting up / tearing down the given environment. They // are for use in the ForEach() function. static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, the test is considered to be failed, but the // rest of the tests will still be run. // // When parameterized tests are enabled, it expands and registers // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. bool UnitTestImpl::RunAllTests() { // Makes sure InitGoogleTest() was called. if (!GTestIsInitialized()) { printf("%s", "\nThis test program did NOT call ::testing::InitGoogleTest " "before calling RUN_ALL_TESTS(). Please fix it.\n"); return false; } // Do not run any test if the --help flag was specified. if (g_help_flag) return true; // Repeats the call to the post-flag parsing initialization in case the // user didn't call InitGoogleTest. PostFlagParsingInit(); // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding // protocol. internal::WriteToShardStatusFileIfNeeded(); // True iff we are in a subprocess for running a thread-safe-style // death test. bool in_subprocess_for_death_test = false; #if GTEST_HAS_DEATH_TEST in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, in_subprocess_for_death_test); // Compares the full test names with the filter to decide which // tests to run. const bool has_tests_to_run = FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL : IGNORE_SHARDING_PROTOCOL) > 0; // Lists the tests and exits if the --gtest_list_tests flag was specified. if (GTEST_FLAG(list_tests)) { // This must be called *after* FilterTests() has been called. ListTestsMatchingFilter(); return true; } random_seed_ = GTEST_FLAG(shuffle) ? GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; // True iff at least one test has failed. bool failed = false; TestEventListener* repeater = listeners()->repeater(); start_timestamp_ = GetTimeInMillis(); repeater->OnTestProgramStart(*parent_); // How many times to repeat the tests? We don't want to repeat them // when we are inside the subprocess of a death test. const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); // Repeats forever if the repeat count is negative. const bool forever = repeat < 0; for (int i = 0; forever || i != repeat; i++) { // We want to preserve failures generated by ad-hoc test // assertions executed before RUN_ALL_TESTS(). ClearNonAdHocTestResult(); const TimeInMillis start = GetTimeInMillis(); // Shuffles test cases and tests if requested. if (has_tests_to_run && GTEST_FLAG(shuffle)) { random()->Reseed(random_seed_); // This should be done before calling OnTestIterationStart(), // such that a test event listener can see the actual test order // in the event. ShuffleTests(); } // Tells the unit test event listeners that the tests are about to start. repeater->OnTestIterationStart(*parent_, i); // Runs each test case if there is at least one test to run. if (has_tests_to_run) { // Sets up all environments beforehand. repeater->OnEnvironmentsSetUpStart(*parent_); ForEach(environments_, SetUpEnvironment); repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { for (int test_index = 0; test_index < total_test_case_count(); test_index++) { GetMutableTestCase(test_index)->Run(); } } // Tears down all environments in reverse order afterwards. repeater->OnEnvironmentsTearDownStart(*parent_); std::for_each(environments_.rbegin(), environments_.rend(), TearDownEnvironment); repeater->OnEnvironmentsTearDownEnd(*parent_); } elapsed_time_ = GetTimeInMillis() - start; // Tells the unit test event listener that the tests have just finished. repeater->OnTestIterationEnd(*parent_, i); // Gets the result and clears it. if (!Passed()) { failed = true; } // Restores the original test order after the iteration. This // allows the user to quickly repro a failure that happens in the // N-th iteration without repeating the first (N - 1) iterations. // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in // case the user somehow changes the value of the flag somewhere // (it's always safe to unshuffle the tests). UnshuffleTests(); if (GTEST_FLAG(shuffle)) { // Picks a new random seed for each iteration. random_seed_ = GetNextRandomSeed(random_seed_); } } repeater->OnTestProgramEnd(*parent_); return !failed; } // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded() { const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); if (test_shard_file != NULL) { FILE* const file = posix::FOpen(test_shard_file, "w"); if (file == NULL) { ColoredPrintf(COLOR_RED, "Could not write to the test shard status file \"%s\" " "specified by the %s environment variable.\n", test_shard_file, kTestShardStatusFile); fflush(stdout); exit(EXIT_FAILURE); } fclose(file); } } // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (i.e., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. bool ShouldShard(const char* total_shards_env, const char* shard_index_env, bool in_subprocess_for_death_test) { if (in_subprocess_for_death_test) { return false; } const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); if (total_shards == -1 && shard_index == -1) { return false; } else if (total_shards == -1 && shard_index != -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestShardIndex << " = " << shard_index << ", but have left " << kTestTotalShards << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestTotalShards << " = " << total_shards << ", but have left " << kTestShardIndex << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { const Message msg = Message() << "Invalid environment variables: we require 0 <= " << kTestShardIndex << " < " << kTestTotalShards << ", but you have " << kTestShardIndex << "=" << shard_index << ", " << kTestTotalShards << "=" << total_shards << ".\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } return total_shards > 1; } // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { const char* str_val = posix::GetEnv(var); if (str_val == NULL) { return default_val; } Int32 result; if (!ParseInt32(Message() << "The value of environment variable " << var, str_val, &result)) { exit(EXIT_FAILURE); } return result; } // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { return (test_id % total_shards) == shard_index; } // Compares the name of each test with the user-specified filter to // decide whether the test should be run, then records the result in // each TestCase and TestInfo object. // If shard_tests == true, further filters tests based on sharding // variables in the environment - see // http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. // Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestShardIndex, -1) : -1; // num_runnable_tests are the number of tests that will // run across all shards (i.e., match filter and are not disabled). // num_selected_tests are the number of tests to be run on // this shard. int num_runnable_tests = 0; int num_selected_tests = 0; for (size_t i = 0; i < test_cases_.size(); i++) { TestCase* const test_case = test_cases_[i]; const std::string &test_case_name = test_case->name(); test_case->set_should_run(false); for (size_t j = 0; j < test_case->test_info_list().size(); j++) { TestInfo* const test_info = test_case->test_info_list()[j]; const std::string test_name(test_info->name()); // A test is disabled if test case name or test name matches // kDisableTestFilter. const bool is_disabled = internal::UnitTestOptions::MatchesFilter(test_case_name, kDisableTestFilter) || internal::UnitTestOptions::MatchesFilter(test_name, kDisableTestFilter); test_info->is_disabled_ = is_disabled; const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(test_case_name, test_name); test_info->matches_filter_ = matches_filter; const bool is_runnable = (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && matches_filter; const bool is_selected = is_runnable && (shard_tests == IGNORE_SHARDING_PROTOCOL || ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests)); num_runnable_tests += is_runnable; num_selected_tests += is_selected; test_info->should_run_ = is_selected; test_case->set_should_run(test_case->should_run() || is_selected); } } return num_selected_tests; } // Prints the given C-string on a single line by replacing all '\n' // characters with string "\\n". If the output takes more than // max_length characters, only prints the first max_length characters // and "...". static void PrintOnOneLine(const char* str, int max_length) { if (str != NULL) { for (int i = 0; *str != '\0'; ++str) { if (i >= max_length) { printf("..."); break; } if (*str == '\n') { printf("\\n"); i += 2; } else { printf("%c", *str); ++i; } } } } // Prints the names of the tests matching the user-specified filter flag. void UnitTestImpl::ListTestsMatchingFilter() { // Print at most this many characters for each type/value parameter. const int kMaxParamLength = 250; for (size_t i = 0; i < test_cases_.size(); i++) { const TestCase* const test_case = test_cases_[i]; bool printed_test_case_name = false; for (size_t j = 0; j < test_case->test_info_list().size(); j++) { const TestInfo* const test_info = test_case->test_info_list()[j]; if (test_info->matches_filter_) { if (!printed_test_case_name) { printed_test_case_name = true; printf("%s.", test_case->name()); if (test_case->type_param() != NULL) { printf(" # %s = ", kTypeParamLabel); // We print the type parameter on a single line to make // the output easy to parse by a program. PrintOnOneLine(test_case->type_param(), kMaxParamLength); } printf("\n"); } printf(" %s", test_info->name()); if (test_info->value_param() != NULL) { printf(" # %s = ", kValueParamLabel); // We print the value parameter on a single line to make the // output easy to parse by a program. PrintOnOneLine(test_info->value_param(), kMaxParamLength); } printf("\n"); } } } fflush(stdout); } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter are // the same; otherwise, deletes the old getter and makes the input the // current getter. void UnitTestImpl::set_os_stack_trace_getter( OsStackTraceGetterInterface* getter) { if (os_stack_trace_getter_ != getter) { delete os_stack_trace_getter_; os_stack_trace_getter_ = getter; } } // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { if (os_stack_trace_getter_ == NULL) { os_stack_trace_getter_ = new OsStackTraceGetter; } return os_stack_trace_getter_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* UnitTestImpl::current_test_result() { return current_test_info_ ? &(current_test_info_->result_) : &ad_hoc_test_result_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void UnitTestImpl::ShuffleTests() { // Shuffles the death test cases. ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); // Shuffles the non-death test cases. ShuffleRange(random(), last_death_test_case_ + 1, static_cast(test_cases_.size()), &test_case_indices_); // Shuffles the tests inside each test case. for (size_t i = 0; i < test_cases_.size(); i++) { test_cases_[i]->ShuffleTests(random()); } } // Restores the test cases and tests to their order before the first shuffle. void UnitTestImpl::UnshuffleTests() { for (size_t i = 0; i < test_cases_.size(); i++) { // Unshuffles the tests in each test case. test_cases_[i]->UnshuffleTests(); // Resets the index of each test case. test_case_indices_[i] = static_cast(i); } } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); } // Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to // suppress unreachable code warnings. namespace { class ClassUniqueToAlwaysTrue {}; } bool IsTrue(bool condition) { return condition; } bool AlwaysTrue() { #if GTEST_HAS_EXCEPTIONS // This condition is always false so AlwaysTrue() never actually throws, // but it makes the compiler think that it may throw. if (IsTrue(false)) throw ClassUniqueToAlwaysTrue(); #endif // GTEST_HAS_EXCEPTIONS return true; } // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. bool SkipPrefix(const char* prefix, const char** pstr) { const size_t prefix_len = strlen(prefix); if (strncmp(*pstr, prefix, prefix_len) == 0) { *pstr += prefix_len; return true; } return false; } // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. // // Returns the value of the flag, or NULL if the parsing failed. const char* ParseFlagValue(const char* str, const char* flag, bool def_optional) { // str and flag must not be NULL. if (str == NULL || flag == NULL) return NULL; // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; const size_t flag_len = flag_str.length(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; // Skips the flag name. const char* flag_end = str + flag_len; // When def_optional is true, it's OK to not have a "=value" part. if (def_optional && (flag_end[0] == '\0')) { return flag_end; } // If def_optional is true and there are more characters after the // flag name, or if def_optional is false, there must be a '=' after // the flag name. if (flag_end[0] != '=') return NULL; // Returns the string after "=". return flag_end + 1; } // Parses a string for a bool flag, in the form of either // "--flag=value" or "--flag". // // In the former case, the value is taken as true as long as it does // not start with '0', 'f', or 'F'. // // In the latter case, the value is taken as true. // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, true); // Aborts if the parsing failed. if (value_str == NULL) return false; // Converts the string value to a bool. *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); return true; } // Parses a string for an Int32 flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. return ParseInt32(Message() << "The value of flag --" << flag, value_str, value); } // Parses a string for a string flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseStringFlag(const char* str, const char* flag, std::string* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. *value = value_str; return true; } // Determines whether a string has a prefix that Google Test uses for its // flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. // If Google Test detects that a command line flag has its prefix but is not // recognized, it will print its help message. Flags starting with // GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test // internal flags and do not trigger the help message. static bool HasGoogleTestFlagPrefix(const char* str) { return (SkipPrefix("--", &str) || SkipPrefix("-", &str) || SkipPrefix("/", &str)) && !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); } // Prints a string containing code-encoded text. The following escape // sequences can be used in the string to control the text color: // // @@ prints a single '@' character. // @R changes the color to red. // @G changes the color to green. // @Y changes the color to yellow. // @D changes to the default terminal text color. // // TODO(wan@google.com): Write tests for this once we add stdout // capturing to Google Test. static void PrintColorEncoded(const char* str) { GTestColor color = COLOR_DEFAULT; // The current color. // Conceptually, we split the string into segments divided by escape // sequences. Then we print one segment at a time. At the end of // each iteration, the str pointer advances to the beginning of the // next segment. for (;;) { const char* p = strchr(str, '@'); if (p == NULL) { ColoredPrintf(color, "%s", str); return; } ColoredPrintf(color, "%s", std::string(str, p).c_str()); const char ch = p[1]; str = p + 2; if (ch == '@') { ColoredPrintf(color, "@"); } else if (ch == 'D') { color = COLOR_DEFAULT; } else if (ch == 'R') { color = COLOR_RED; } else if (ch == 'G') { color = COLOR_GREEN; } else if (ch == 'Y') { color = COLOR_YELLOW; } else { --str; } } } static const char kColorEncodedHelpMessage[] = "This program contains tests written using " GTEST_NAME_ ". You can use the\n" "following command line flags to control its behavior:\n" "\n" "Test Selection:\n" " @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" " List the names of all tests instead of running them. The name of\n" " TEST(Foo, Bar) is \"Foo.Bar\".\n" " @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" "[@G-@YNEGATIVE_PATTERNS]@D\n" " Run only the tests whose name matches one of the positive patterns but\n" " none of the negative patterns. '?' matches any single character; '*'\n" " matches any substring; ':' separates two patterns.\n" " @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" " Run all disabled tests too.\n" "\n" "Test Execution:\n" " @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" " Run the tests repeatedly; use a negative count to repeat forever.\n" " @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" " Randomize tests' orders on every iteration.\n" " @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" " Random number seed to use for shuffling test orders (between 1 and\n" " 99999, or 0 to use a seed based on the current time).\n" "\n" "Test Output:\n" " @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" " Enable/disable colored output. The default is @Gauto@D.\n" " -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" " Don't print the elapsed time of each test.\n" " @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" " Generate an XML report in the given directory or with the given file\n" " name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" #if GTEST_CAN_STREAM_RESULTS_ " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " Stream test results to the given server.\n" #endif // GTEST_CAN_STREAM_RESULTS_ "\n" "Assertion Behavior:\n" #if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " Set the default death test style.\n" #endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " Turn assertion failures into debugger break-points.\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" " Turn assertion failures into C++ exceptions.\n" " @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" " Do not report exceptions as test failures. Instead, allow them\n" " to crash the program or throw a pop-up (on Windows).\n" "\n" "Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " "the corresponding\n" "environment variable of a flag (all letters in upper-case). For example, to\n" "disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ "color=no@D or set\n" "the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" "\n" "For more information, please read the " GTEST_NAME_ " documentation at\n" "@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" "(not one in your own code or tests), please report it to\n" "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be // instantiated to either char or wchar_t. template void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { for (int i = 1; i < *argc; i++) { const std::string arg_string = StreamableToString(argv[i]); const char* const arg = arg_string.c_str(); using internal::ParseBoolFlag; using internal::ParseInt32Flag; using internal::ParseStringFlag; // Do we see a Google Test flag? if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, >EST_FLAG(also_run_disabled_tests)) || ParseBoolFlag(arg, kBreakOnFailureFlag, >EST_FLAG(break_on_failure)) || ParseBoolFlag(arg, kCatchExceptionsFlag, >EST_FLAG(catch_exceptions)) || ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || ParseStringFlag(arg, kDeathTestStyleFlag, >EST_FLAG(death_test_style)) || ParseBoolFlag(arg, kDeathTestUseFork, >EST_FLAG(death_test_use_fork)) || ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag, >EST_FLAG(internal_run_death_test)) || ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || ParseInt32Flag(arg, kStackTraceDepthFlag, >EST_FLAG(stack_trace_depth)) || ParseStringFlag(arg, kStreamResultToFlag, >EST_FLAG(stream_result_to)) || ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note // that argv has (*argc + 1) elements, the last one always being // NULL. The following loop moves the trailing NULL element as // well. for (int j = i; j != *argc; j++) { argv[j] = argv[j + 1]; } // Decrements the argument count. (*argc)--; // We also need to decrement the iterator as we just removed // an element. i--; } else if (arg_string == "--help" || arg_string == "-h" || arg_string == "-?" || arg_string == "/?" || HasGoogleTestFlagPrefix(arg)) { // Both help flag and unrecognized Google Test flags (excluding // internal ones) trigger help display. g_help_flag = true; } } if (g_help_flag) { // We print the help here instead of in RUN_ALL_TESTS(), as the // latter may not be called at all if the user is using Google // Test with another testing framework. PrintColorEncoded(kColorEncodedHelpMessage); } } // Parses the command line for Google Test flags, without initializing // other parts of Google Test. void ParseGoogleTestFlagsOnly(int* argc, char** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } // The internal implementation of InitGoogleTest(). // // The type parameter CharType can be instantiated to either char or // wchar_t. template void InitGoogleTestImpl(int* argc, CharType** argv) { g_init_gtest_count++; // We don't want to run the initialization code twice. if (g_init_gtest_count != 1) return; if (*argc <= 0) return; internal::g_executable_path = internal::StreamableToString(argv[0]); #if GTEST_HAS_DEATH_TEST g_argvs.clear(); for (int i = 0; i != *argc; i++) { g_argvs.push_back(StreamableToString(argv[i])); } #endif // GTEST_HAS_DEATH_TEST ParseGoogleTestFlagsOnly(argc, argv); GetUnitTestImpl()->PostFlagParsingInit(); } } // namespace internal // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. void InitGoogleTest(int* argc, char** argv) { internal::InitGoogleTestImpl(argc, argv); } // This overloaded version can be used in Windows programs compiled in // UNICODE mode. void InitGoogleTest(int* argc, wchar_t** argv) { internal::InitGoogleTestImpl(argc, argv); } } // namespace testing stimfit-0.16.7/src/test/gtest/src/gtest-port.cc0000664000175000017500000006551214750344764015100 // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/internal/gtest-port.h" #include #include #include #include #if GTEST_OS_WINDOWS_MOBILE # include // For TerminateProcess() #elif GTEST_OS_WINDOWS # include # include #else # include #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_MAC # include # include # include #endif // GTEST_OS_MAC #if GTEST_OS_QNX # include # include #endif // GTEST_OS_QNX #include "gtest/gtest-spi.h" #include "gtest/gtest-message.h" #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { #if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC and C++Builder do not provide a definition of STDERR_FILENO. const int kStdOutFileno = 1; const int kStdErrFileno = 2; #else const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER #if GTEST_OS_MAC // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const task_t task = mach_task_self(); mach_msg_type_number_t thread_count; thread_act_array_t thread_list; const kern_return_t status = task_threads(task, &thread_list, &thread_count); if (status == KERN_SUCCESS) { // task_threads allocates resources in thread_list and we need to free them // to avoid leaks. vm_deallocate(task, reinterpret_cast(thread_list), sizeof(thread_t) * thread_count); return static_cast(thread_count); } else { return 0; } } #elif GTEST_OS_QNX // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const int fd = open("/proc/self/as", O_RDONLY); if (fd < 0) { return 0; } procfs_info process_info; const int status = devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); close(fd); if (status == EOK) { return static_cast(process_info.num_threads); } else { return 0; } } #else size_t GetThreadCount() { // There's no portable way to detect the number of threads, so we just // return 0 to indicate that we cannot detect it. return 0; } #endif // GTEST_OS_MAC #if GTEST_USES_POSIX_RE // Implements RE. Currently only needed for death tests. RE::~RE() { if (is_valid_) { // regfree'ing an invalid regex might crash because the content // of the regex is undefined. Since the regex's are essentially // the same, one cannot be valid (or invalid) without the other // being so too. regfree(&partial_regex_); regfree(&full_regex_); } free(const_cast(pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.full_regex_, str, 1, &match, 0) == 0; } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = posix::StrDup(regex); // Reserves enough bytes to hold the regular expression used for a // full match. const size_t full_regex_len = strlen(regex) + 10; char* const full_pattern = new char[full_regex_len]; snprintf(full_pattern, full_regex_len, "^(%s)$", regex); is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; // We want to call regcomp(&partial_regex_, ...) even if the // previous expression returns false. Otherwise partial_regex_ may // not be properly initialized can may cause trouble when it's // freed. // // Some implementation of POSIX regex (e.g. on at least some // versions of Cygwin) doesn't accept the empty string as a valid // regex. We change it to an equivalent form "()" to be safe. if (is_valid_) { const char* const partial_regex = (*regex == '\0') ? "()" : regex; is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; } EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; delete[] full_pattern; } #elif GTEST_USES_SIMPLE_RE // Returns true iff ch appears anywhere in str (excluding the // terminating '\0' character). bool IsInSet(char ch, const char* str) { return ch != '\0' && strchr(str, ch) != NULL; } // Returns true iff ch belongs to the given classification. Unlike // similar functions in , these aren't affected by the // current locale. bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } bool IsAsciiPunct(char ch) { return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); } bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } bool IsAsciiWordChar(char ch) { return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9') || ch == '_'; } // Returns true iff "\\c" is a supported escape sequence. bool IsValidEscape(char c) { return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); } // Returns true iff the given atom (specified by escaped and pattern) // matches ch. The result is undefined if the atom is invalid. bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { if (escaped) { // "\\p" where p is pattern_char. switch (pattern_char) { case 'd': return IsAsciiDigit(ch); case 'D': return !IsAsciiDigit(ch); case 'f': return ch == '\f'; case 'n': return ch == '\n'; case 'r': return ch == '\r'; case 's': return IsAsciiWhiteSpace(ch); case 'S': return !IsAsciiWhiteSpace(ch); case 't': return ch == '\t'; case 'v': return ch == '\v'; case 'w': return IsAsciiWordChar(ch); case 'W': return !IsAsciiWordChar(ch); } return IsAsciiPunct(pattern_char) && pattern_char == ch; } return (pattern_char == '.' && ch != '\n') || pattern_char == ch; } // Helper function used by ValidateRegex() to format error messages. std::string FormatRegexSyntaxError(const char* regex, int index) { return (Message() << "Syntax error at index " << index << " in simple regular expression \"" << regex << "\": ").GetString(); } // Generates non-fatal failures and returns false if regex is invalid; // otherwise returns true. bool ValidateRegex(const char* regex) { if (regex == NULL) { // TODO(wan@google.com): fix the source file location in the // assertion failures to match where the regex is used in user // code. ADD_FAILURE() << "NULL is not a valid simple regular expression."; return false; } bool is_valid = true; // True iff ?, *, or + can follow the previous atom. bool prev_repeatable = false; for (int i = 0; regex[i]; i++) { if (regex[i] == '\\') { // An escape sequence i++; if (regex[i] == '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "'\\' cannot appear at the end."; return false; } if (!IsValidEscape(regex[i])) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "invalid escape sequence \"\\" << regex[i] << "\"."; is_valid = false; } prev_repeatable = true; } else { // Not an escape sequence. const char ch = regex[i]; if (ch == '^' && i > 0) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'^' can only appear at the beginning."; is_valid = false; } else if (ch == '$' && regex[i + 1] != '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'$' can only appear at the end."; is_valid = false; } else if (IsInSet(ch, "()[]{}|")) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' is unsupported."; is_valid = false; } else if (IsRepeat(ch) && !prev_repeatable) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' can only follow a repeatable token."; is_valid = false; } prev_repeatable = !IsInSet(ch, "^$?*+"); } } return is_valid; } // Matches a repeated regex atom followed by a valid simple regular // expression. The regex atom is defined as c if escaped is false, // or \c otherwise. repeat is the repetition meta character (?, *, // or +). The behavior is undefined if str contains too many // characters to be indexable by size_t, in which case the test will // probably time out anyway. We are fine with this limitation as // std::string has it too. bool MatchRepetitionAndRegexAtHead( bool escaped, char c, char repeat, const char* regex, const char* str) { const size_t min_count = (repeat == '+') ? 1 : 0; const size_t max_count = (repeat == '?') ? 1 : static_cast(-1) - 1; // We cannot call numeric_limits::max() as it conflicts with the // max() macro on Windows. for (size_t i = 0; i <= max_count; ++i) { // We know that the atom matches each of the first i characters in str. if (i >= min_count && MatchRegexAtHead(regex, str + i)) { // We have enough matches at the head, and the tail matches too. // Since we only care about *whether* the pattern matches str // (as opposed to *how* it matches), there is no need to find a // greedy match. return true; } if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false; } return false; } // Returns true iff regex matches a prefix of str. regex must be a // valid simple regular expression and not start with "^", or the // result is undefined. bool MatchRegexAtHead(const char* regex, const char* str) { if (*regex == '\0') // An empty regex matches a prefix of anything. return true; // "$" only matches the end of a string. Note that regex being // valid guarantees that there's nothing after "$" in it. if (*regex == '$') return *str == '\0'; // Is the first thing in regex an escape sequence? const bool escaped = *regex == '\\'; if (escaped) ++regex; if (IsRepeat(regex[1])) { // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so // here's an indirect recursion. It terminates as the regex gets // shorter in each recursion. return MatchRepetitionAndRegexAtHead( escaped, regex[0], regex[1], regex + 2, str); } else { // regex isn't empty, isn't "$", and doesn't start with a // repetition. We match the first atom of regex with the first // character of str and recurse. return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && MatchRegexAtHead(regex + 1, str + 1); } } // Returns true iff regex matches any substring of str. regex must be // a valid simple regular expression, or the result is undefined. // // The algorithm is recursive, but the recursion depth doesn't exceed // the regex length, so we won't need to worry about running out of // stack space normally. In rare cases the time complexity can be // exponential with respect to the regex length + the string length, // but usually it's must faster (often close to linear). bool MatchRegexAnywhere(const char* regex, const char* str) { if (regex == NULL || str == NULL) return false; if (*regex == '^') return MatchRegexAtHead(regex + 1, str); // A successful match can be anywhere in str. do { if (MatchRegexAtHead(regex, str)) return true; } while (*str++ != '\0'); return false; } // Implements the RE class. RE::~RE() { free(const_cast(pattern_)); free(const_cast(full_pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = full_pattern_ = NULL; if (regex != NULL) { pattern_ = posix::StrDup(regex); } is_valid_ = ValidateRegex(regex); if (!is_valid_) { // No need to calculate the full pattern when the regex is invalid. return; } const size_t len = strlen(regex); // Reserves enough bytes to hold the regular expression used for a // full match: we need space to prepend a '^', append a '$', and // terminate the string with '\0'. char* buffer = static_cast(malloc(len + 3)); full_pattern_ = buffer; if (*regex != '^') *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. // We don't use snprintf or strncpy, as they trigger a warning when // compiled with VC++ 8.0. memcpy(buffer, regex, len); buffer += len; if (len == 0 || regex[len - 1] != '$') *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. *buffer = '\0'; } #endif // GTEST_USES_POSIX_RE const char kUnknownFile[] = "unknown file"; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) { return file_name + ":"; } #ifdef _MSC_VER return file_name + "(" + StreamableToString(line) + "):"; #else return file_name + ":" + StreamableToString(line) + ":"; #endif // _MSC_VER } // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. // Note that FormatCompilerIndependentFileLocation() does NOT append colon // to the file location it produces, unlike FormatFileLocation(). GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) return file_name; else return file_name + ":" + StreamableToString(line); } GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { const char* const marker = severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; GetStream() << ::std::endl << marker << " " << FormatFileLocation(file, line).c_str() << ": "; } // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. GTestLog::~GTestLog() { GetStream() << ::std::endl; if (severity_ == GTEST_FATAL) { fflush(stderr); posix::Abort(); } } // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4996) #endif // _MSC_VER #if GTEST_HAS_STREAM_REDIRECTION // Object that captures an output stream (stdout/stderr). class CapturedStream { public: // The ctor redirects the stream to a temporary file. explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { # if GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, // Generate unique file name. temp_file_path); GTEST_CHECK_(success != 0) << "Unable to create a temporary file in " << temp_dir_path; const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " << temp_file_path; filename_ = temp_file_path; # else // There's no guarantee that a test has write access to the current // directory, so we create the temporary file in the /tmp directory // instead. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. # if GTEST_OS_LINUX_ANDROID // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, // this requires a Context handle, which cannot be retrieved // globally from native code. Doing so also precludes running the // code as part of a regular standalone executable, which doesn't // run in a Dalvik process (e.g. when running it through 'adb shell'). // // The location /sdcard is directly accessible from native code // and is the only location (unofficially) supported by the Android // team. It's generally a symlink to the real SD Card mount point // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or // other OEM-customized locations. Never rely on these, and always // use /sdcard. char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; # else char name_template[] = "/tmp/captured_stream.XXXXXX"; # endif // GTEST_OS_LINUX_ANDROID const int captured_fd = mkstemp(name_template); filename_ = name_template; # endif // GTEST_OS_WINDOWS fflush(NULL); dup2(captured_fd, fd_); close(captured_fd); } ~CapturedStream() { remove(filename_.c_str()); } std::string GetCapturedString() { if (uncaptured_fd_ != -1) { // Restores the original stream. fflush(NULL); dup2(uncaptured_fd_, fd_); close(uncaptured_fd_); uncaptured_fd_ = -1; } FILE* const file = posix::FOpen(filename_.c_str(), "r"); const std::string content = ReadEntireFile(file); posix::FClose(file); return content; } private: // Reads the entire content of a file as an std::string. static std::string ReadEntireFile(FILE* file); // Returns the size (in bytes) of a file. static size_t GetFileSize(FILE* file); const int fd_; // A stream to capture. int uncaptured_fd_; // Name of the temporary file holding the stderr output. ::std::string filename_; GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; // Returns the size (in bytes) of a file. size_t CapturedStream::GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast(ftell(file)); } // Reads the entire content of a file as a string. std::string CapturedStream::ReadEntireFile(FILE* file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; size_t bytes_last_read = 0; // # of bytes read in the last fread() size_t bytes_read = 0; // # of bytes read so far fseek(file, 0, SEEK_SET); // Keeps reading the file until we cannot read further or the // pre-determined file size is reached. do { bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); bytes_read += bytes_last_read; } while (bytes_last_read > 0 && bytes_read < file_size); const std::string content(buffer, bytes_read); delete[] buffer; return content; } # ifdef _MSC_VER # pragma warning(pop) # endif // _MSC_VER static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; // Starts capturing an output stream (stdout/stderr). void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { if (*stream != NULL) { GTEST_LOG_(FATAL) << "Only one " << stream_name << " capturer can exist at a time."; } *stream = new CapturedStream(fd); } // Stops capturing the output stream and returns the captured string. std::string GetCapturedStream(CapturedStream** captured_stream) { const std::string content = (*captured_stream)->GetCapturedString(); delete *captured_stream; *captured_stream = NULL; return content; } // Starts capturing stdout. void CaptureStdout() { CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); } // Starts capturing stderr. void CaptureStderr() { CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); } // Stops capturing stdout and returns the captured string. std::string GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } // Stops capturing stderr and returns the captured string. std::string GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). ::std::vector g_argvs; static const ::std::vector* g_injected_test_argvs = NULL; // Owned. void SetInjectableArgvs(const ::std::vector* argvs) { if (g_injected_test_argvs != argvs) delete g_injected_test_argvs; g_injected_test_argvs = argvs; } const ::std::vector& GetInjectableArgvs() { if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } return g_argvs; } #endif // GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS_MOBILE namespace posix { void Abort() { DebugBreak(); TerminateProcess(GetCurrentProcess(), 1); } } // namespace posix #endif // GTEST_OS_WINDOWS_MOBILE // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. static std::string FlagToEnvVar(const char* flag) { const std::string full_flag = (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; for (size_t i = 0; i != full_flag.length(); i++) { env_var << ToUpper(full_flag.c_str()[i]); } return env_var.GetString(); } // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. bool ParseInt32(const Message& src_text, const char* str, Int32* value) { // Parses the environment variable as a decimal integer. char* end = NULL; const long long_value = strtol(str, &end, 10); // NOLINT // Has strtol() consumed all characters in the string? if (*end != '\0') { // No - an invalid character was encountered. Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value \"" << str << "\".\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } // Is the parsed value in the range of an Int32? const Int32 result = static_cast(long_value); if (long_value == LONG_MAX || long_value == LONG_MIN || // The parsed value overflows as a long. (strtol() returns // LONG_MAX or LONG_MIN when the input overflows.) result != long_value // The parsed value overflows as an Int32. ) { Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value " << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } *value = result; return true; } // Reads and returns the Boolean environment variable corresponding to // the given flag; if it's not set, returns default_value. // // The value is considered true iff it's not "0". bool BoolFromGTestEnv(const char* flag, bool default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); return string_value == NULL ? default_value : strcmp(string_value, "0") != 0; } // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { // The environment variable is not set. return default_value; } Int32 result = default_value; if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, &result)) { printf("The default value %s is used.\n", (Message() << default_value).GetString().c_str()); fflush(stdout); return default_value; } return result; } // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. const char* StringFromGTestEnv(const char* flag, const char* default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const value = posix::GetEnv(env_var.c_str()); return value == NULL ? default_value : value; } } // namespace internal } // namespace testing stimfit-0.16.7/src/test/gtest/src/gtest-printers.cc0000664000175000017500000002776314750344764015770 // Copyright 2007, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // It uses the << operator when possible, and prints the bytes in the // object otherwise. A user can override its behavior for a class // type Foo by defining either operator<<(::std::ostream&, const Foo&) // or void PrintTo(const Foo&, ::std::ostream*) in the namespace that // defines Foo. #include "gtest/gtest-printers.h" #include #include #include // NOLINT #include #include "gtest/internal/gtest-port.h" namespace testing { namespace { using ::std::ostream; // Prints a segment of bytes in the given object. void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, size_t count, ostream* os) { char text[5] = ""; for (size_t i = 0; i != count; i++) { const size_t j = start + i; if (i != 0) { // Organizes the bytes into groups of 2 for easy parsing by // human. if ((j % 2) == 0) *os << ' '; else *os << '-'; } GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); *os << text; } } // Prints the bytes in the given value to the given ostream. void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, ostream* os) { // Tells the user how big the object is. *os << count << "-byte object <"; const size_t kThreshold = 132; const size_t kChunkSize = 64; // If the object size is bigger than kThreshold, we'll have to omit // some details by printing only the first and the last kChunkSize // bytes. // TODO(wan): let the user control the threshold using a flag. if (count < kThreshold) { PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); } else { PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); *os << " ... "; // Rounds up to 2-byte boundary. const size_t resume_pos = (count - kChunkSize + 1)/2*2; PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); } *os << ">"; } } // namespace namespace internal2 { // Delegates to PrintBytesInObjectToImpl() to print the bytes in the // given object. The delegation simplifies the implementation, which // uses the << operator and thus is easier done outside of the // ::testing::internal namespace, which contains a << operator that // sometimes conflicts with the one in STL. void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ostream* os) { PrintBytesInObjectToImpl(obj_bytes, count, os); } } // namespace internal2 namespace internal { // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as a hexidecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). enum CharFormat { kAsIs, kHexEscape, kSpecialEscape }; // Returns true if c is a printable ASCII character. We test the // value of c directly instead of calling isprint(), which is buggy on // Windows Mobile. inline bool IsPrintableAscii(wchar_t c) { return 0x20 <= c && c <= 0x7E; } // Prints a wide or narrow char c as a character literal without the // quotes, escaping it when necessary; returns how c was formatted. // The template argument UnsignedChar is the unsigned version of Char, // which is the type of c. template static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { switch (static_cast(c)) { case L'\0': *os << "\\0"; break; case L'\'': *os << "\\'"; break; case L'\\': *os << "\\\\"; break; case L'\a': *os << "\\a"; break; case L'\b': *os << "\\b"; break; case L'\f': *os << "\\f"; break; case L'\n': *os << "\\n"; break; case L'\r': *os << "\\r"; break; case L'\t': *os << "\\t"; break; case L'\v': *os << "\\v"; break; default: if (IsPrintableAscii(c)) { *os << static_cast(c); return kAsIs; } else { *os << "\\x" + String::FormatHexInt(static_cast(c)); return kHexEscape; } } return kSpecialEscape; } // Prints a wchar_t c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { switch (c) { case L'\'': *os << "'"; return kAsIs; case L'"': *os << "\\\""; return kSpecialEscape; default: return PrintAsCharLiteralTo(c, os); } } // Prints a char c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { return PrintAsStringLiteralTo( static_cast(static_cast(c)), os); } // Prints a wide or narrow character c and its code. '\0' is printed // as "'\\0'", other unprintable characters are also properly escaped // using the standard C++ escape sequence. The template argument // UnsignedChar is the unsigned version of Char, which is the type of c. template void PrintCharAndCodeTo(Char c, ostream* os) { // First, print c as a literal in the most readable form we can find. *os << ((sizeof(c) > 1) ? "L'" : "'"); const CharFormat format = PrintAsCharLiteralTo(c, os); *os << "'"; // To aid user debugging, we also print c's code in decimal, unless // it's 0 (in which case c was printed as '\\0', making the code // obvious). if (c == 0) return; *os << " (" << static_cast(c); // For more convenience, we print c's code again in hexidecimal, // unless c was already printed in the form '\x##' or the code is in // [1, 9]. if (format == kHexEscape || (1 <= c && c <= 9)) { // Do nothing. } else { *os << ", 0x" << String::FormatHexInt(static_cast(c)); } *os << ")"; } void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its code. L'\0' is printed as "L'\\0'". void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); } // Prints the given array of characters to the ostream. CharType must be either // char or wchar_t. // The array starts at begin, the length is len, it may include '\0' characters // and may not be NUL-terminated. template static void PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; *os << kQuoteBegin; bool is_previous_hex = false; for (size_t index = 0; index < len; ++index) { const CharType cur = begin[index]; if (is_previous_hex && IsXDigit(cur)) { // Previous character is of '\x..' form and this character can be // interpreted as another hexadecimal digit in its number. Break string to // disambiguate. *os << "\" " << kQuoteBegin; } is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; } *os << "\""; } // Prints a (const) char/wchar_t array of 'len' elements, starting at address // 'begin'. CharType must be either char or wchar_t. template static void UniversalPrintCharArray( const CharType* begin, size_t len, ostream* os) { // The code // const char kFoo[] = "foo"; // generates an array of 4, not 3, elements, with the last one being '\0'. // // Therefore when printing a char array, we don't print the last element if // it's '\0', such that the output matches the string literal as it's // written in the source code. if (len > 0 && begin[len - 1] == '\0') { PrintCharsAsStringTo(begin, len - 1, os); return; } // If, however, the last element in the array is not '\0', e.g. // const char kFoo[] = { 'f', 'o', 'o' }; // we must print the entire array. We also print a message to indicate // that the array is not NUL-terminated. PrintCharsAsStringTo(begin, len, os); *os << " (no terminating NUL)"; } // Prints a (const) char array of 'len' elements, starting at address 'begin'. void UniversalPrintArray(const char* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints a (const) wchar_t array of 'len' elements, starting at address // 'begin'. void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints the given C string to the ostream. void PrintTo(const char* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, strlen(s), os); } } // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, // possibly accessing more memory than intended and causing invalid // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when // wchar_t is implemented as a native type. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Prints the given wide C string to the ostream. void PrintTo(const wchar_t* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, wcslen(s), os); } } #endif // wchar_t is native // Prints a ::string object. #if GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::std::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } // Prints a ::wstring object. #if GTEST_HAS_GLOBAL_WSTRING void PrintWideStringTo(const ::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING void PrintWideStringTo(const ::std::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_STD_WSTRING } // namespace internal } // namespace testing stimfit-0.16.7/src/test/gtest/src/gtest-typed-test.cc0000664000175000017500000000726214750344764016214 // Copyright 2008 Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest-typed-test.h" #include "gtest/gtest.h" namespace testing { namespace internal { #if GTEST_HAS_TYPED_TEST_P // Skips to the first non-space char in str. Returns an empty string if str // contains only whitespace characters. static const char* SkipSpaces(const char* str) { while (IsSpace(*str)) str++; return str; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* TypedTestCasePState::VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests) { typedef ::std::set::const_iterator DefinedTestIter; registered_ = true; // Skip initial whitespace in registered_tests since some // preprocessors prefix stringizied literals with whitespace. registered_tests = SkipSpaces(registered_tests); Message errors; ::std::set tests; for (const char* names = registered_tests; names != NULL; names = SkipComma(names)) { const std::string name = GetPrefixUntilComma(names); if (tests.count(name) != 0) { errors << "Test " << name << " is listed more than once.\n"; continue; } bool found = false; for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (name == *it) { found = true; break; } } if (found) { tests.insert(name); } else { errors << "No test named " << name << " can be found in this test case.\n"; } } for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (tests.count(*it) == 0) { errors << "You forgot to list test " << *it << ".\n"; } } const std::string& errors_str = errors.GetString(); if (errors_str != "") { fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors_str.c_str()); fflush(stderr); posix::Abort(); } return registered_tests; } #endif // GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing stimfit-0.16.7/src/test/gtest/src/gtest-internal-inl.h0000664000175000017500000013260114750344764016344 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // Utility functions and classes used by the Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) // // This file contains purely Google Test's internal implementation. Please // DO NOT #INCLUDE IT IN A USER PROGRAM. #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ #define GTEST_SRC_GTEST_INTERNAL_INL_H_ // GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is // part of Google Test's implementation; otherwise it's undefined. #if !GTEST_IMPLEMENTATION_ // A user is trying to include this from his code - just say no. # error "gtest-internal-inl.h is part of Google Test's internal implementation." # error "It must not be included except by Google Test itself." #endif // GTEST_IMPLEMENTATION_ #ifndef _WIN32_WCE # include #endif // !_WIN32_WCE #include #include // For strtoll/_strtoul64/malloc/free. #include // For memmove. #include #include #include #include "gtest/internal/gtest-port.h" #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT #endif #if GTEST_OS_WINDOWS # include // NOLINT #endif // GTEST_OS_WINDOWS #include "gtest/gtest.h" // NOLINT #include "gtest/gtest-spi.h" namespace testing { // Declares the flags. // // We don't want the users to modify this flag in the code, but want // Google Test's own unit tests to be able to access it. Therefore we // declare it here as opposed to in gtest.h. GTEST_DECLARE_bool_(death_test_use_fork); namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kStreamResultToFlag[] = "stream_result_to"; const char kThrowOnFailureFlag[] = "throw_on_failure"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. GTEST_API_ extern bool g_help_flag; // Returns the current time in milliseconds. GTEST_API_ TimeInMillis GetTimeInMillis(); // Returns true iff Google Test should use colors in the output. GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); // Formats the given time in milliseconds as seconds. GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); // Converts the given time in milliseconds to a date string in the ISO 8601 // format, without the timezone information. N.B.: due to the use the // non-reentrant localtime() function, this function is not thread safe. Do // not use it in any code that can be called from multiple threads. GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); // Parses a string for an Int32 flag, in the form of "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. GTEST_API_ bool ParseInt32Flag( const char* str, const char* flag, Int32* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { const unsigned int raw_seed = (random_seed_flag == 0) ? static_cast(GetTimeInMillis()) : static_cast(random_seed_flag); // Normalizes the actual seed to range [1, kMaxRandomSeed] such that // it's easy to type. const int normalized_seed = static_cast((raw_seed - 1U) % static_cast(kMaxRandomSeed)) + 1; return normalized_seed; } // Returns the first valid random seed after 'seed'. The behavior is // undefined if 'seed' is invalid. The seed after kMaxRandomSeed is // considered to be 1. inline int GetNextRandomSeed(int seed) { GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) << "Invalid random seed " << seed << " - must be in [1, " << kMaxRandomSeed << "]."; const int next_seed = seed + 1; return (next_seed > kMaxRandomSeed) ? 1 : next_seed; } // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. class GTestFlagSaver { public: // The c'tor. GTestFlagSaver() { also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); break_on_failure_ = GTEST_FLAG(break_on_failure); catch_exceptions_ = GTEST_FLAG(catch_exceptions); color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); shuffle_ = GTEST_FLAG(shuffle); stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); stream_result_to_ = GTEST_FLAG(stream_result_to); throw_on_failure_ = GTEST_FLAG(throw_on_failure); } // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. ~GTestFlagSaver() { GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; GTEST_FLAG(break_on_failure) = break_on_failure_; GTEST_FLAG(catch_exceptions) = catch_exceptions_; GTEST_FLAG(color) = color_; GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: // Fields for saving the original values of flags. bool also_run_disabled_tests_; bool break_on_failure_; bool catch_exceptions_; std::string color_; std::string death_test_style_; bool death_test_use_fork_; std::string filter_; std::string internal_run_death_test_; bool list_tests_; std::string output_; bool print_time_; internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; internal::Int32 stack_trace_depth_; std::string stream_result_to_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded(); // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (e.g., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. GTEST_API_ bool ShouldShard(const char* total_shards_str, const char* shard_index_str, bool in_subprocess_for_death_test); // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error and // and aborts. GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. GTEST_API_ bool ShouldRunTestOnShard( int total_shards, int shard_index, int test_id); // STL container utilities. // Returns the number of elements in the given container that satisfy // the given predicate. template inline int CountIf(const Container& c, Predicate predicate) { // Implemented as an explicit loop since std::count_if() in libCstd on // Solaris has a non-standard signature. int count = 0; for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { if (predicate(*it)) ++count; } return count; } // Applies a function/functor to each element in the container. template void ForEach(const Container& c, Functor functor) { std::for_each(c.begin(), c.end(), functor); } // Returns the i-th element of the vector, or default_value if i is not // in range [0, v.size()). template inline E GetElementOr(const std::vector& v, int i, E default_value) { return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; } // Performs an in-place shuffle of a range of the vector's elements. // 'begin' and 'end' are element indices as an STL-style range; // i.e. [begin, end) are shuffled, where 'end' == size() means to // shuffle to the end of the vector. template void ShuffleRange(internal::Random* random, int begin, int end, std::vector* v) { const int size = static_cast(v->size()); GTEST_CHECK_(0 <= begin && begin <= size) << "Invalid shuffle range start " << begin << ": must be in range [0, " << size << "]."; GTEST_CHECK_(begin <= end && end <= size) << "Invalid shuffle range finish " << end << ": must be in range [" << begin << ", " << size << "]."; // Fisher-Yates shuffle, from // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle for (int range_width = end - begin; range_width >= 2; range_width--) { const int last_in_range = begin + range_width - 1; const int selected = begin + random->Generate(range_width); std::swap((*v)[selected], (*v)[last_in_range]); } } // Performs an in-place shuffle of the vector's elements. template inline void Shuffle(internal::Random* random, std::vector* v) { ShuffleRange(random, 0, static_cast(v->size()), v); } // A function for deleting an object. Handy for being used as a // functor. template static void Delete(T* x) { delete x; } // A predicate that checks the key of a TestProperty against a known key. // // TestPropertyKeyIs is copyable. class TestPropertyKeyIs { public: // Constructor. // // TestPropertyKeyIs has NO default constructor. explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} // Returns true iff the test name of test property matches on key_. bool operator()(const TestProperty& test_property) const { return test_property.key() == key_; } private: std::string key_; }; // Class UnitTestOptions. // // This class contains functions for processing options the user // specifies when running the tests. It has only static members. // // In most cases, the user can specify an option using either an // environment variable or a command line flag. E.g. you can set the // test filter using either GTEST_FILTER or --gtest_filter. If both // the variable and the flag are present, the latter overrides the // former. class GTEST_API_ UnitTestOptions { public: // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. static std::string GetOutputFormat(); // Returns the absolute path of the requested output file, or the // default (test_detail.xml in the original working directory) if // none was explicitly specified. static std::string GetAbsolutePathToOutputFile(); // Functions for processing the gtest_filter flag. // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. static bool PatternMatchesString(const char *pattern, const char *str); // Returns true iff the user-specified filter matches the test case // name and the test name. static bool FilterMatchesTest(const std::string &test_case_name, const std::string &test_name); #if GTEST_OS_WINDOWS // Function for supporting the gtest_catch_exception flag. // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. static int GTestShouldProcessSEH(DWORD exception_code); #endif // GTEST_OS_WINDOWS // Returns true if "name" matches the ':' separated list of glob-style // filters in "filter". static bool MatchesFilter(const std::string& name, const char* filter); }; // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. GTEST_API_ FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { public: OsStackTraceGetterInterface() {} virtual ~OsStackTraceGetterInterface() {} // Returns the current OS stack trace as an std::string. Parameters: // // max_depth - the maximum number of stack frames to be included // in the trace. // skip_count - the number of top frames to be skipped; doesn't count // against max_depth. virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; // UponLeavingGTest() should be called immediately before Google Test calls // user code. It saves some information about the current stack that // CurrentStackTrace() will use to find and hide Google Test stack frames. virtual void UponLeavingGTest() = 0; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: OsStackTraceGetter() : caller_frame_(NULL) {} virtual string CurrentStackTrace(int max_depth, int skip_count) GTEST_LOCK_EXCLUDED_(mutex_); virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); // This string is inserted in place of stack frames that are part of // Google Test's implementation. static const char* const kElidedFramesMarker; private: Mutex mutex_; // protects all internal state // We save the stack frame below the frame that calls user code. // We do this because the address of the frame immediately below // the user code changes between the call to UponLeavingGTest() // and any calls to CurrentStackTrace() from within the user code. void* caller_frame_; GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); }; // Information about a Google Test trace point. struct TraceInfo { const char* file; int line; std::string message; }; // This is the default global test part result reporter used in UnitTestImpl. // This class should only be used by UnitTestImpl. class DefaultGlobalTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. Reports the test part // result in the current test. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); }; // This is the default per thread test part result reporter used in // UnitTestImpl. This class should only be used by UnitTestImpl. class DefaultPerThreadTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. The implementation just // delegates to the current global test part result reporter of *unit_test_. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); }; // The private implementation of the UnitTest class. We don't protect // the methods under a mutex, as this class is not accessible by a // user and the UnitTest class that delegates work to this class does // proper locking. class GTEST_API_ UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); // There are two different ways to register your own TestPartResultReporter. // You can register your own repoter to listen either only for test results // from the current thread or for results from all threads. // By default, each per-thread test result repoter just passes a new // TestPartResult to the global test result reporter, which registers the // test part result for the currently running test. // Returns the global test part result reporter. TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); // Sets the global test part result reporter. void SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter); // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); // Sets the test part result reporter for the current thread. void SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter); // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const { return start_timestamp_; } // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const { return !Failed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const { return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[i]; } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i) { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[index]; } // Provides access to the event listener list. TestEventListeners* listeners() { return &listeners_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* current_test_result(); // Returns the TestResult for the ad hoc test. const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter // are the same; otherwise, deletes the old getter and makes the // input the current getter. void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* os_stack_trace_getter(); // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Adds a TestInfo to the unit test. // // Arguments: // // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // test_info: the TestInfo object void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, TestInfo* test_info) { // In order to support thread-safe death tests, we need to // remember the original working directory when the test program // was first invoked. We cannot do this in RUN_ALL_TESTS(), as // the user may have changed the current directory before calling // RUN_ALL_TESTS(). Therefore we capture the current directory in // AddTestInfo(), which is called to register a TEST or TEST_F // before main() is reached. if (original_working_dir_.IsEmpty()) { original_working_dir_.Set(FilePath::GetCurrentDir()); GTEST_CHECK_(!original_working_dir_.IsEmpty()) << "Failed to get the current working directory."; } GetTestCase(test_info->test_case_name(), test_info->type_param(), set_up_tc, tear_down_tc)->AddTestInfo(test_info); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { return parameterized_test_registry_; } #endif // GTEST_HAS_PARAM_TEST // Sets the TestCase object for the test that's currently running. void set_current_test_case(TestCase* a_current_test_case) { current_test_case_ = a_current_test_case; } // Sets the TestInfo object for the test that's currently running. If // current_test_info is NULL, the assertion results will be stored in // ad_hoc_test_result_. void set_current_test_info(TestInfo* a_current_test_info) { current_test_info_ = a_current_test_info; } // Registers all parameterized tests defined using TEST_P and // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter // combination. This method can be called more then once; it has guards // protecting from registering the tests more then once. If // value-parameterized tests are disabled, RegisterParameterizedTests is // present but does nothing. void RegisterParameterizedTests(); // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, this test is considered to be failed, but // the rest of the tests will still be run. bool RunAllTests(); // Clears the results of all tests, except the ad hoc tests. void ClearNonAdHocTestResult() { ForEach(test_cases_, TestCase::ClearTestCaseResult); } // Clears the results of ad-hoc test assertions. void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test or a test case, or to the global property set. If the // result already contains a property with the same key, the value will be // updated. void RecordProperty(const TestProperty& test_property); enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL }; // Matches the full name of each test against the user-specified // filter to decide whether the test should run, then records the // result in each TestCase and TestInfo object. // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests // based on sharding variables in the environment. // Returns the number of tests that should run. int FilterTests(ReactionToSharding shard_tests); // Prints the names of the tests matching the user-specified filter flag. void ListTestsMatchingFilter(); const TestCase* current_test_case() const { return current_test_case_; } TestInfo* current_test_info() { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; } // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector& environments() { return environments_; } // Getters for the per-thread Google Test trace stack. std::vector& gtest_trace_stack() { return *(gtest_trace_stack_.pointer()); } const std::vector& gtest_trace_stack() const { return gtest_trace_stack_.get(); } #if GTEST_HAS_DEATH_TEST void InitDeathTestSubprocessControlInfo() { internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); } // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. // Must not be called before a call to InitGoogleTest. const InternalRunDeathTestFlag* internal_run_death_test_flag() const { return internal_run_death_test_flag_.get(); } // Returns a pointer to the current death test factory. internal::DeathTestFactory* death_test_factory() { return death_test_factory_.get(); } void SuppressTestEventsIfInSubprocess(); friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST // Initializes the event listener performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Initializes the event listener for streaming test results to a socket. // Must not be called before InitGoogleTest. void ConfigureStreamingOutput(); #endif // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void PostFlagParsingInit(); // Gets the random seed used at the start of the current test iteration. int random_seed() const { return random_seed_; } // Gets the random number generator. internal::Random* random() { return &random_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void ShuffleTests(); // Restores the test cases and tests to their order before the first shuffle. void UnshuffleTests(); // Returns the value of GTEST_FLAG(catch_exceptions) at the moment // UnitTest::Run() starts. bool catch_exceptions() const { return catch_exceptions_; } private: friend class ::testing::UnitTest; // Used by UnitTest::Run() to capture the state of // GTEST_FLAG(catch_exceptions) at the moment it starts. void set_catch_exceptions(bool value) { catch_exceptions_ = value; } // The UnitTest object that owns this implementation object. UnitTest* const parent_; // The working directory when the first TEST() or TEST_F() was // executed. internal::FilePath original_working_dir_; // The default test part result reporters. DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; DefaultPerThreadTestPartResultReporter default_per_thread_test_part_result_reporter_; // Points to (but doesn't own) the global test part result reporter. TestPartResultReporterInterface* global_test_part_result_repoter_; // Protects read and write access to global_test_part_result_reporter_. internal::Mutex global_test_part_result_reporter_mutex_; // Points to (but doesn't own) the per-thread test part result reporter. internal::ThreadLocal per_thread_test_part_result_reporter_; // The vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector environments_; // The vector of TestCases in their original order. It owns the // elements in the vector. std::vector test_cases_; // Provides a level of indirection for the test case list to allow // easy shuffling and restoring the test case order. The i-th // element of this vector is the index of the i-th test case in the // shuffled order. std::vector test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized // tests. internal::ParameterizedTestCaseRegistry parameterized_test_registry_; // Indicates whether RegisterParameterizedTests() has been called already. bool parameterized_tests_registered_; #endif // GTEST_HAS_PARAM_TEST // Index of the last death test case registered. Initially -1. int last_death_test_case_; // This points to the TestCase for the currently running test. It // changes as Google Test goes through one test case after another. // When no test is running, this is set to NULL and Google Test // stores assertion results in ad_hoc_test_result_. Initially NULL. TestCase* current_test_case_; // This points to the TestInfo for the currently running test. It // changes as Google Test goes through one test after another. When // no test is running, this is set to NULL and Google Test stores // assertion results in ad_hoc_test_result_. Initially NULL. TestInfo* current_test_info_; // Normally, a user only writes assertions inside a TEST or TEST_F, // or inside a function called by a TEST or TEST_F. Since Google // Test keeps track of which test is current running, it can // associate such an assertion with the test it belongs to. // // If an assertion is encountered when no TEST or TEST_F is running, // Google Test attributes the assertion result to an imaginary "ad hoc" // test, and records the result in ad_hoc_test_result_. TestResult ad_hoc_test_result_; // The list of event listeners that can be used to track events inside // Google Test. TestEventListeners listeners_; // The OS stack trace getter. Will be deleted when the UnitTest // object is destructed. By default, an OsStackTraceGetter is used, // but the user can set this field to use a custom getter if that is // desired. OsStackTraceGetterInterface* os_stack_trace_getter_; // True iff PostFlagParsingInit() has been called. bool post_flag_parse_init_performed_; // The random number seed used at the beginning of the test run. int random_seed_; // Our random number generator. internal::Random random_; // The time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp_; // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; #if GTEST_HAS_DEATH_TEST // The decomposed components of the gtest_internal_run_death_test flag, // parsed when RUN_ALL_TESTS is called. internal::scoped_ptr internal_run_death_test_flag_; internal::scoped_ptr death_test_factory_; #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. internal::ThreadLocal > gtest_trace_stack_; // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() // starts. bool catch_exceptions_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl // Convenience function for accessing the global UnitTest // implementation object. inline UnitTestImpl* GetUnitTestImpl() { return UnitTest::GetInstance()->impl(); } #if GTEST_USES_SIMPLE_RE // Internal helper functions for implementing the simple regular // expression matcher. GTEST_API_ bool IsInSet(char ch, const char* str); GTEST_API_ bool IsAsciiDigit(char ch); GTEST_API_ bool IsAsciiPunct(char ch); GTEST_API_ bool IsRepeat(char ch); GTEST_API_ bool IsAsciiWhiteSpace(char ch); GTEST_API_ bool IsAsciiWordChar(char ch); GTEST_API_ bool IsValidEscape(char ch); GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool ValidateRegex(const char* regex); GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); GTEST_API_ bool MatchRepetitionAndRegexAtHead( bool escaped, char ch, char repeat, const char* regex, const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); #endif // GTEST_USES_SIMPLE_RE // Parses the command line for Google Test flags, without initializing // other parts of Google Test. GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); #if GTEST_HAS_DEATH_TEST // Returns the message describing the last system error, regardless of the // platform. GTEST_API_ std::string GetLastErrnoDescription(); # if GTEST_OS_WINDOWS // Provides leak-safe Windows kernel handle ownership. class AutoHandle { public: AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} explicit AutoHandle(HANDLE handle) : handle_(handle) {} ~AutoHandle() { Reset(); } HANDLE Get() const { return handle_; } void Reset() { Reset(INVALID_HANDLE_VALUE); } void Reset(HANDLE handle) { if (handle != handle_) { if (handle_ != INVALID_HANDLE_VALUE) ::CloseHandle(handle_); handle_ = handle; } } private: HANDLE handle_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); }; # endif // GTEST_OS_WINDOWS // Attempts to parse a string into a positive integer pointed to by the // number parameter. Returns true if that is possible. // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use // it here. template bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // Fail fast if the given string does not begin with a digit; // this bypasses strtoXXX's "optional leading whitespace and plus // or minus sign" semantics, which are undesirable here. if (str.empty() || !IsDigit(str[0])) { return false; } errno = 0; char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. # if GTEST_OS_WINDOWS && !defined(__GNUC__) // MSVC and C++ Builder define __int64 instead of the standard long long. typedef unsigned __int64 BiggestConvertible; const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); # else typedef unsigned long long BiggestConvertible; // NOLINT const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); # endif // GTEST_OS_WINDOWS && !defined(__GNUC__) const bool parse_success = *end == '\0' && errno == 0; // TODO(vladl@google.com): Convert this to compile time assertion when it is // available. GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); const Integer result = static_cast(parsed); if (parse_success && static_cast(result) == parsed) { *number = result; return true; } return false; } #endif // GTEST_HAS_DEATH_TEST // TestResult contains some private methods that should be hidden from // Google Test user but are required for testing. This class allow our tests // to access them. // // This class is supplied only for the purpose of testing Google Test's own // constructs. Do not use it in user tests, either directly or indirectly. class TestResultAccessor { public: static void RecordProperty(TestResult* test_result, const std::string& xml_element, const TestProperty& property) { test_result->RecordProperty(xml_element, property); } static void ClearTestPartResults(TestResult* test_result) { test_result->ClearTestPartResults(); } static const std::vector& test_part_results( const TestResult& test_result) { return test_result.test_part_results(); } }; #if GTEST_CAN_STREAM_RESULTS_ // Streams test results to the given port on the given host machine. class StreamingListener : public EmptyTestEventListener { public: // Abstract base class for writing strings to a socket. class AbstractSocketWriter { public: virtual ~AbstractSocketWriter() {} // Sends a string to the socket. virtual void Send(const string& message) = 0; // Closes the socket. virtual void CloseConnection() {} // Sends a string and a newline to the socket. void SendLn(const string& message) { Send(message + "\n"); } }; // Concrete class for actually writing strings to a socket. class SocketWriter : public AbstractSocketWriter { public: SocketWriter(const string& host, const string& port) : sockfd_(-1), host_name_(host), port_num_(port) { MakeConnection(); } virtual ~SocketWriter() { if (sockfd_ != -1) CloseConnection(); } // Sends a string to the socket. virtual void Send(const string& message) { GTEST_CHECK_(sockfd_ != -1) << "Send() can be called only when there is a connection."; const int len = static_cast(message.length()); if (write(sockfd_, message.c_str(), len) != len) { GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to " << host_name_ << ":" << port_num_; } } private: // Creates a client socket and connects to the server. void MakeConnection(); // Closes the socket. void CloseConnection() { GTEST_CHECK_(sockfd_ != -1) << "CloseConnection() can be called only when there is a connection."; close(sockfd_); sockfd_ = -1; } int sockfd_; // socket file descriptor const string host_name_; const string port_num_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); }; // class SocketWriter // Escapes '=', '&', '%', and '\n' characters in str as "%xx". static string UrlEncode(const char* str); StreamingListener(const string& host, const string& port) : socket_writer_(new SocketWriter(host, port)) { Start(); } explicit StreamingListener(AbstractSocketWriter* socket_writer) : socket_writer_(socket_writer) { Start(); } void OnTestProgramStart(const UnitTest& /* unit_test */) { SendLn("event=TestProgramStart"); } void OnTestProgramEnd(const UnitTest& unit_test) { // Note that Google Test current only report elapsed time for each // test iteration, not for the entire test program. SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); // Notify the streaming server to stop. socket_writer_->CloseConnection(); } void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { SendLn("event=TestIterationStart&iteration=" + StreamableToString(iteration)); } void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) + "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) + "ms"); } void OnTestCaseStart(const TestCase& test_case) { SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); } void OnTestCaseEnd(const TestCase& test_case) { SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + "ms"); } void OnTestStart(const TestInfo& test_info) { SendLn(std::string("event=TestStart&name=") + test_info.name()); } void OnTestEnd(const TestInfo& test_info) { SendLn("event=TestEnd&passed=" + FormatBool((test_info.result())->Passed()) + "&elapsed_time=" + StreamableToString((test_info.result())->elapsed_time()) + "ms"); } void OnTestPartResult(const TestPartResult& test_part_result) { const char* file_name = test_part_result.file_name(); if (file_name == NULL) file_name = ""; SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + "&line=" + StreamableToString(test_part_result.line_number()) + "&message=" + UrlEncode(test_part_result.message())); } private: // Sends the given message and a newline to the socket. void SendLn(const string& message) { socket_writer_->SendLn(message); } // Called at the start of streaming to notify the receiver what // protocol we are using. void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } string FormatBool(bool value) { return value ? "1" : "0"; } const scoped_ptr socket_writer_; GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); }; // class StreamingListener #endif // GTEST_CAN_STREAM_RESULTS_ } // namespace internal } // namespace testing #endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ stimfit-0.16.7/src/test/gtest/src/gtest-filepath.cc0000664000175000017500000003363614750344764015712 // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Authors: keith.ray@gmail.com (Keith Ray) #include "gtest/gtest-message.h" #include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-port.h" #include #if GTEST_OS_WINDOWS_MOBILE # include #elif GTEST_OS_WINDOWS # include # include #elif GTEST_OS_SYMBIAN // Symbian OpenC has PATH_MAX in sys/syslimits.h # include #else # include # include // Some Linux distributions define PATH_MAX here. #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS # define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) # define GTEST_PATH_MAX_ PATH_MAX #elif defined(_XOPEN_PATH_MAX) # define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #else # define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS #include "gtest/internal/gtest-string.h" namespace testing { namespace internal { #if GTEST_OS_WINDOWS // On Windows, '\\' is the standard path separator, but many tools and the // Windows API also accept '/' as an alternate path separator. Unless otherwise // noted, a file path can contain either kind of path separators, or a mixture // of them. const char kPathSeparator = '\\'; const char kAlternatePathSeparator = '/'; const char kPathSeparatorString[] = "\\"; const char kAlternatePathSeparatorString[] = "/"; # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. const char kCurrentDirectoryString[] = "\\"; // Windows CE doesn't define INVALID_FILE_ATTRIBUTES const DWORD kInvalidFileAttributes = 0xffffffff; # else const char kCurrentDirectoryString[] = ".\\"; # endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kPathSeparatorString[] = "/"; const char kCurrentDirectoryString[] = "./"; #endif // GTEST_OS_WINDOWS // Returns whether the given character is a valid path separator. static bool IsPathSeparator(char c) { #if GTEST_HAS_ALT_PATH_SEP_ return (c == kPathSeparator) || (c == kAlternatePathSeparator); #else return c == kPathSeparator; #endif } // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { #if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath FilePath::RemoveExtension(const char* extension) const { const std::string dot_extension = std::string(".") + extension; if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { return FilePath(pathname_.substr( 0, pathname_.length() - dot_extension.length())); } return *this; } // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FilePath::FindLastPathSeparator() const { const char* const last_sep = strrchr(c_str(), kPathSeparator); #if GTEST_HAS_ALT_PATH_SEP_ const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); // Comparing two pointers of which only one is NULL is undefined. if (last_alt_sep != NULL && (last_sep == NULL || last_alt_sep > last_sep)) { return last_alt_sep; } #endif return last_sep; } // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveDirectoryName() const { const char* const last_sep = FindLastPathSeparator(); return last_sep ? FilePath(last_sep + 1) : *this; } // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveFileName() const { const char* const last_sep = FindLastPathSeparator(); std::string dir; if (last_sep) { dir = std::string(c_str(), last_sep + 1 - c_str()); } else { dir = kCurrentDirectoryString; } return FilePath(dir); } // Helper functions for naming files in a directory for xml output. // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { std::string file; if (number == 0) { file = base_name.string() + "." + extension; } else { file = base_name.string() + "_" + StreamableToString(number) + "." + extension; } return ConcatPaths(directory, FilePath(file)); } // Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. FilePath FilePath::ConcatPaths(const FilePath& directory, const FilePath& relative_path) { if (directory.IsEmpty()) return relative_path; const FilePath dir(directory.RemoveTrailingPathSeparator()); return FilePath(dir.string() + kPathSeparator + relative_path.string()); } // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. bool FilePath::FileOrDirectoryExists() const { #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; return attributes != kInvalidFileAttributes; #else posix::StatStruct file_stat; return posix::Stat(pathname_.c_str(), &file_stat) == 0; #endif // GTEST_OS_WINDOWS_MOBILE } // Returns true if pathname describes a directory in the file-system // that exists. bool FilePath::DirectoryExists() const { bool result = false; #if GTEST_OS_WINDOWS // Don't strip off trailing separator if path is a root directory on // Windows (like "C:\\"). const FilePath& path(IsRootDirectory() ? *this : RemoveTrailingPathSeparator()); #else const FilePath& path(*this); #endif #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; if ((attributes != kInvalidFileAttributes) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) { result = true; } #else posix::StatStruct file_stat; result = posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat); #endif // GTEST_OS_WINDOWS_MOBILE return result; } // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool FilePath::IsRootDirectory() const { #if GTEST_OS_WINDOWS // TODO(wan@google.com): on Windows a network share like // \\server\share can be a root directory, although it cannot be the // current directory. Handle this properly. return pathname_.length() == 3 && IsAbsolutePath(); #else return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); #endif } // Returns true if pathname describes an absolute path. bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); #if GTEST_OS_WINDOWS return pathname_.length() >= 3 && ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && IsPathSeparator(name[2]); #else return IsPathSeparator(name[0]); #endif } // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension) { FilePath full_pathname; int number = 0; do { full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); } while (full_pathname.FileOrDirectoryExists()); return full_pathname; } // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool FilePath::IsDirectory() const { return !pathname_.empty() && IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); } // Create directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create directories // for any reason. bool FilePath::CreateDirectoriesRecursively() const { if (!this->IsDirectory()) { return false; } if (pathname_.length() == 0 || this->DirectoryExists()) { return true; } const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); return parent.CreateDirectoriesRecursively() && this->CreateFolder(); } // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool FilePath::CreateFolder() const { #if GTEST_OS_WINDOWS_MOBILE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); int result = CreateDirectory(unicode, NULL) ? 0 : -1; delete [] unicode; #elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); #else int result = mkdir(pathname_.c_str(), 0777); #endif // GTEST_OS_WINDOWS_MOBILE if (result == -1) { return this->DirectoryExists(); // An error is OK if the directory exists. } return true; // No error. } // If input name has a trailing separator character, remove it and return the // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1)) : *this; } // Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). void FilePath::Normalize() { if (pathname_.c_str() == NULL) { pathname_ = ""; return; } const char* src = pathname_.c_str(); char* const dest = new char[pathname_.length() + 1]; char* dest_ptr = dest; memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { *dest_ptr = *src; if (!IsPathSeparator(*src)) { src++; } else { #if GTEST_HAS_ALT_PATH_SEP_ if (*dest_ptr == kAlternatePathSeparator) { *dest_ptr = kPathSeparator; } #endif while (IsPathSeparator(*src)) src++; } dest_ptr++; } *dest_ptr = '\0'; pathname_ = dest; delete[] dest; } } // namespace internal } // namespace testing stimfit-0.16.7/src/test/gtest/src/gtest-all.cc0000664000175000017500000000416114750344764014655 // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Author: mheule@google.com (Markus Heule) // // Google C++ Testing Framework (Google Test) // // Sometimes it's desirable to build Google Test by compiling a single file. // This file serves this purpose. // This line ensures that gtest.h can be compiled on its own, even // when it's fused. #include "gtest/gtest.h" // The following lines pull in the real gtest *.cc files. #include "src/gtest.cc" #include "src/gtest-death-test.cc" #include "src/gtest-filepath.cc" #include "src/gtest-port.cc" #include "src/gtest-printers.cc" #include "src/gtest-test-part.cc" #include "src/gtest-typed-test.cc" stimfit-0.16.7/src/test/gtest/src/gtest-death-test.cc0000664000175000017500000014340514750344764016154 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) // // This file implements death tests. #include "gtest/gtest-death-test.h" #include "gtest/internal/gtest-port.h" #if GTEST_HAS_DEATH_TEST # if GTEST_OS_MAC # include # endif // GTEST_OS_MAC # include # include # include # if GTEST_OS_LINUX # include # endif // GTEST_OS_LINUX # include # if GTEST_OS_WINDOWS # include # else # include # include # endif // GTEST_OS_WINDOWS # if GTEST_OS_QNX # include # endif // GTEST_OS_QNX #endif // GTEST_HAS_DEATH_TEST #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { // Constants. // The default death test style. static const char kDefaultDeathTestStyle[] = "fast"; GTEST_DEFINE_string_( death_test_style, internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), "Indicates how to run a death test in a forked child process: " "\"threadsafe\" (child process re-executes the test binary " "from the beginning, running only the specific death test) or " "\"fast\" (child process runs the death test immediately " "after forking)."); GTEST_DEFINE_bool_( death_test_use_fork, internal::BoolFromGTestEnv("death_test_use_fork", false), "Instructs to use fork()/_exit() instead of clone() in death tests. " "Ignored and always uses fork() on POSIX systems where clone() is not " "implemented. Useful when running under valgrind or similar tools if " "those do not support clone(). Valgrind 3.3.1 will just fail if " "it sees an unsupported combination of clone() flags. " "It is not recommended to use this flag w/o valgrind though it will " "work in 99% of the cases. Once valgrind is fixed, this flag will " "most likely be removed."); namespace internal { GTEST_DEFINE_string_( internal_run_death_test, "", "Indicates the file, line number, temporal index of " "the single death test to run, and a file descriptor to " "which a success code may be sent, all separated by " "the '|' characters. This flag is specified if and only if the current " "process is a sub-process launched for running a thread-safe " "death test. FOR INTERNAL USE ONLY."); } // namespace internal #if GTEST_HAS_DEATH_TEST namespace internal { // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. static bool g_in_fast_death_test_child = false; // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. bool InDeathTestChild() { # if GTEST_OS_WINDOWS // On Windows, death tests are thread-safe regardless of the value of the // death_test_style flag. return !GTEST_FLAG(internal_run_death_test).empty(); # else if (GTEST_FLAG(death_test_style) == "threadsafe") return !GTEST_FLAG(internal_run_death_test).empty(); else return g_in_fast_death_test_child; #endif } } // namespace internal // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { } // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { # if GTEST_OS_WINDOWS return exit_status == exit_code_; # else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; # endif // GTEST_OS_WINDOWS } # if !GTEST_OS_WINDOWS // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } # endif // !GTEST_OS_WINDOWS namespace internal { // Utilities needed for death tests. // Generates a textual description of a given exit code, in the format // specified by wait(2). static std::string ExitSummary(int exit_code) { Message m; # if GTEST_OS_WINDOWS m << "Exited with exit status " << exit_code; # else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { m << "Terminated by signal " << WTERMSIG(exit_code); } # ifdef WCOREDUMP if (WCOREDUMP(exit_code)) { m << " (core dumped)"; } # endif # endif // GTEST_OS_WINDOWS return m.GetString(); } // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } # if !GTEST_OS_WINDOWS // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the // caller not to pass a thread_count of 1. static std::string DeathTestThreadWarning(size_t thread_count) { Message msg; msg << "Death tests use fork(), which is unsafe particularly" << " in a threaded context. For this test, " << GTEST_NAME_ << " "; if (thread_count == 0) msg << "couldn't detect the number of threads."; else msg << "detected " << thread_count << " threads."; return msg.GetString(); } # endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; static const char kDeathTestReturned = 'R'; static const char kDeathTestThrew = 'T'; static const char kDeathTestInternalError = 'I'; // An enumeration describing all of the possible ways that a death test can // conclude. DIED means that the process died while executing the test // code; LIVED means that process lived beyond the end of the test code; // RETURNED means that the test statement attempted to execute a return // statement, which is not allowed; THREW means that the test statement // returned control by throwing an exception. IN_PROGRESS means the test // has not yet concluded. // TODO(vladl@google.com): Unify names and possibly values for // AbortReason, DeathTestOutcome, and flag characters above. enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; // Routine for aborting the program which is safe to call from an // exec-style death test child process, in which case the error // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. void DeathTestAbort(const std::string& message) { // On a POSIX system, this function may be called from a threadsafe-style // death test child process, which operates on a very small stack. Use // the heap for any additional non-minuscule memory requirements. const InternalRunDeathTestFlag* const flag = GetUnitTestImpl()->internal_run_death_test_flag(); if (flag != NULL) { FILE* parent = posix::FDOpen(flag->write_fd(), "w"); fputc(kDeathTestInternalError, parent); fprintf(parent, "%s", message.c_str()); fflush(parent); _exit(1); } else { fprintf(stderr, "%s", message.c_str()); fflush(stderr); posix::Abort(); } } // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. # define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!::testing::internal::IsTrue(expression)) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression); \ } \ } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return // -1 on failure, and set errno to EINTR when it is interrupted and // should be tried again. The macro expands to a loop that repeatedly // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. # define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ int gtest_retval; \ do { \ gtest_retval = (expression); \ } while (gtest_retval == -1 && errno == EINTR); \ if (gtest_retval == -1) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression + " != -1"); \ } \ } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. std::string GetLastErrnoDescription() { return errno == 0 ? "" : posix::StrError(errno); } // This is called from a death test parent process to read a failure // message from the death test child process and log it with the FATAL // severity. On Windows, the message is read from a pipe handle. On other // platforms, it is read from a file descriptor. static void FailFromInternalError(int fd) { Message error; char buffer[256]; int num_read; do { while ((num_read = posix::Read(fd, buffer, 255)) > 0) { buffer[num_read] = '\0'; error << buffer; } } while (num_read == -1 && errno == EINTR); if (num_read == 0) { GTEST_LOG_(FATAL) << error.GetString(); } else { const int last_error = errno; GTEST_LOG_(FATAL) << "Error while reading death test internal: " << GetLastErrnoDescription() << " [" << last_error << "]"; } } // Death test constructor. Increments the running death test count // for the current test. DeathTest::DeathTest() { TestInfo* const info = GetUnitTestImpl()->current_test_info(); if (info == NULL) { DeathTestAbort("Cannot run a death test outside of a TEST or " "TEST_F construct"); } } // Creates and returns a death test by dispatching to the current // death test factory. bool DeathTest::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { return GetUnitTestImpl()->death_test_factory()->Create( statement, regex, file, line, test); } const char* DeathTest::LastMessage() { return last_death_test_message_.c_str(); } void DeathTest::set_last_death_test_message(const std::string& message) { last_death_test_message_ = message; } std::string DeathTest::last_death_test_message_; // Provides cross platform implementation for some death functionality. class DeathTestImpl : public DeathTest { protected: DeathTestImpl(const char* a_statement, const RE* a_regex) : statement_(a_statement), regex_(a_regex), spawned_(false), status_(-1), outcome_(IN_PROGRESS), read_fd_(-1), write_fd_(-1) {} // read_fd_ is expected to be closed and cleared by a derived class. ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } void Abort(AbortReason reason); virtual bool Passed(bool status_ok); const char* statement() const { return statement_; } const RE* regex() const { return regex_; } bool spawned() const { return spawned_; } void set_spawned(bool is_spawned) { spawned_ = is_spawned; } int status() const { return status_; } void set_status(int a_status) { status_ = a_status; } DeathTestOutcome outcome() const { return outcome_; } void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } int write_fd() const { return write_fd_; } void set_write_fd(int fd) { write_fd_ = fd; } // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void ReadAndInterpretStatusByte(); private: // The textual content of the code this object is testing. This class // doesn't own this string and should not attempt to delete it. const char* const statement_; // The regular expression which test output must match. DeathTestImpl // doesn't own this object and should not attempt to delete it. const RE* const regex_; // True if the death test child process has been successfully spawned. bool spawned_; // The exit status of the child process. int status_; // How the death test concluded. DeathTestOutcome outcome_; // Descriptor to the read end of the pipe to the child process. It is // always -1 in the child process. The child keeps its write end of the // pipe in write_fd_. int read_fd_; // Descriptor to the child's write end of the pipe to the parent process. // It is always -1 in the parent process. The parent keeps its end of the // pipe in read_fd_. int write_fd_; }; // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void DeathTestImpl::ReadAndInterpretStatusByte() { char flag; int bytes_read; // The read() here blocks until data is available (signifying the // failure of the death test) or until the pipe is closed (signifying // its success), so it's okay to call this in the parent before // the child process has exited. do { bytes_read = posix::Read(read_fd(), &flag, 1); } while (bytes_read == -1 && errno == EINTR); if (bytes_read == 0) { set_outcome(DIED); } else if (bytes_read == 1) { switch (flag) { case kDeathTestReturned: set_outcome(RETURNED); break; case kDeathTestThrew: set_outcome(THREW); break; case kDeathTestLived: set_outcome(LIVED); break; case kDeathTestInternalError: FailFromInternalError(read_fd()); // Does not return. break; default: GTEST_LOG_(FATAL) << "Death test child process reported " << "unexpected status byte (" << static_cast(flag) << ")"; } } else { GTEST_LOG_(FATAL) << "Read from death test child process failed: " << GetLastErrnoDescription(); } GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); set_read_fd(-1); } // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. // Writes a status byte to the child's status file descriptor, then // calls _exit(1). void DeathTestImpl::Abort(AbortReason reason) { // The parent process considers the death test to be a failure if // it finds any data in our pipe. So, here we write a single flag byte // to the pipe, then exit. const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); // We are leaking the descriptor here because on some platforms (i.e., // when built as Windows DLL), destructors of global objects will still // run after calling _exit(). On such systems, write_fd_ will be // indirectly closed from the destructor of UnitTestImpl, causing double // close if it is also closed here. On debug configurations, double close // may assert. As there are no in-process buffers to flush here, we are // relying on the OS to close the descriptor after the process terminates // when the destructors are not run. _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Returns an indented copy of stderr output for a death test. // This makes distinguishing death test output lines from regular log lines // much easier. static ::std::string FormatDeathTestOutput(const ::std::string& output) { ::std::string ret; for (size_t at = 0; ; ) { const size_t line_end = output.find('\n', at); ret += "[ DEATH ] "; if (line_end == ::std::string::npos) { ret += output.substr(at); break; } ret += output.substr(at, line_end + 1 - at); at = line_end + 1; } return ret; } // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // // Private data members: // outcome: An enumeration describing how the death test // concluded: DIED, LIVED, THREW, or RETURNED. The death test // fails in the latter three cases. // status: The exit status of the child process. On *nix, it is in the // in the format specified by wait(2). On Windows, this is the // value supplied to the ExitProcess() API or a numeric code // of the exception that terminated the program. // regex: A regular expression object to be applied to // the test's captured standard error output; the death test // fails if it does not match. // // Argument: // status_ok: true if exit_status is acceptable in the context of // this particular death test, which fails if it is false // // Returns true iff all of the above conditions are met. Otherwise, the // first failing condition, in the order given above, is the one that is // reported. Also sets the last death test message string. bool DeathTestImpl::Passed(bool status_ok) { if (!spawned()) return false; const std::string error_message = GetCapturedStderr(); bool success = false; Message buffer; buffer << "Death test: " << statement() << "\n"; switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case THREW: buffer << " Result: threw an exception.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); if (matched) { success = true; } else { buffer << " Result: died but not with expected error.\n" << " Expected: " << regex()->pattern() << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } } else { buffer << " Result: died but not with expected exit code:\n" << " " << ExitSummary(status()) << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: default: GTEST_LOG_(FATAL) << "DeathTest::Passed somehow called before conclusion of test"; } DeathTest::set_last_death_test_message(buffer.GetString()); return success; } # if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are // always threadsafe, and Google Test considers the // --gtest_death_test_style=fast setting to be equivalent to // --gtest_death_test_style=threadsafe there. // // A few implementation notes: Like the Linux version, the Windows // implementation uses pipes for child-to-parent communication. But due to // the specifics of pipes on Windows, some extra steps are required: // // 1. The parent creates a communication pipe and stores handles to both // ends of it. // 2. The parent starts the child and provides it with the information // necessary to acquire the handle to the write end of the pipe. // 3. The child acquires the write end of the pipe and signals the parent // using a Windows event. // 4. Now the parent can release the write end of the pipe on its side. If // this is done before step 3, the object's reference count goes down to // 0 and it is destroyed, preventing the child from acquiring it. The // parent now has to release it, or read operations on the read end of // the pipe will not return when the child terminates. // 5. The parent reads child's output through the pipe (outcome code and // any possible error messages) from the pipe, and its stderr and then // determines whether to fail the test. // // Note: to distinguish Win32 API calls from the local method and function // calls, the former are explicitly resolved in the global namespace. // class WindowsDeathTest : public DeathTestImpl { public: WindowsDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} // All of these virtual functions are inherited from DeathTest. virtual int Wait(); virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; // Handle to the write end of the pipe to the child process. AutoHandle write_handle_; // Child process handle. AutoHandle child_handle_; // Event the child process uses to signal the parent that it has // acquired the handle to the write end of the pipe. After seeing this // event the parent can release its own handles to make sure its // ReadFile() calls return when the child terminates. AutoHandle event_handle_; }; // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int WindowsDeathTest::Wait() { if (!spawned()) return 0; // Wait until the child either signals that it has acquired the write end // of the pipe or it dies. const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; switch (::WaitForMultipleObjects(2, wait_handles, FALSE, // Waits for any of the handles. INFINITE)) { case WAIT_OBJECT_0: case WAIT_OBJECT_0 + 1: break; default: GTEST_DEATH_TEST_CHECK_(false); // Should not get here. } // The child has acquired the write end of the pipe or exited. // We release the handle on our side and continue. write_handle_.Reset(); event_handle_.Reset(); ReadAndInterpretStatusByte(); // Waits for the child process to exit if it haven't already. This // returns immediately if the child has already exited, regardless of // whether previous calls to WaitForMultipleObjects synchronized on this // handle or not. GTEST_DEATH_TEST_CHECK_( WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), INFINITE)); DWORD status_code; GTEST_DEATH_TEST_CHECK_( ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); child_handle_.Reset(); set_status(static_cast(status_code)); return status(); } // The AssumeRole process for a Windows death test. It creates a child // process with the same executable as the current process to run the // death test. The child process is given the --gtest_filter and // --gtest_internal_run_death_test flags such that it knows to run the // current death test only. DeathTest::TestRole WindowsDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { // ParseInternalRunDeathTestFlag() has performed all the necessary // processing. set_write_fd(flag->write_fd()); return EXECUTE_TEST; } // WindowsDeathTest uses an anonymous pipe to communicate results of // a death test. SECURITY_ATTRIBUTES handles_are_inheritable = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; HANDLE read_handle, write_handle; GTEST_DEATH_TEST_CHECK_( ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, 0) // Default buffer size. != FALSE); set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), O_RDONLY)); write_handle_.Reset(write_handle); event_handle_.Reset(::CreateEvent( &handles_are_inheritable, TRUE, // The event will automatically reset to non-signaled state. FALSE, // The initial state is non-signalled. NULL)); // The even is unnamed. GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(static_cast(::GetCurrentProcessId())) + // size_t has the same width as pointers on both 32-bit and 64-bit // Windows platforms. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. "|" + StreamableToString(reinterpret_cast(write_handle)) + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); char executable_path[_MAX_PATH + 1]; // NOLINT GTEST_DEATH_TEST_CHECK_( _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, executable_path, _MAX_PATH)); std::string command_line = std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + internal_flag + "\""; DeathTest::set_last_death_test_message(""); CaptureStderr(); // Flush the log buffers since the log streams are shared with the child. FlushInfoLog(); // The child process will share the standard handles with the parent. STARTUPINFOA startup_info; memset(&startup_info, 0, sizeof(STARTUPINFO)); startup_info.dwFlags = STARTF_USESTDHANDLES; startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); PROCESS_INFORMATION process_info; GTEST_DEATH_TEST_CHECK_(::CreateProcessA( executable_path, const_cast(command_line.c_str()), NULL, // Retuned process handle is not inheritable. NULL, // Retuned thread handle is not inheritable. TRUE, // Child inherits all inheritable handles (for write_handle_). 0x0, // Default creation flags. NULL, // Inherit the parent's environment. UnitTest::GetInstance()->original_working_dir(), &startup_info, &process_info) != FALSE); child_handle_.Reset(process_info.hProcess); ::CloseHandle(process_info.hThread); set_spawned(true); return OVERSEE_TEST; } # else // We are not on Windows. // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is // left undefined. class ForkingDeathTest : public DeathTestImpl { public: ForkingDeathTest(const char* statement, const RE* regex); // All of these virtual functions are inherited from DeathTest. virtual int Wait(); protected: void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } private: // PID of child process during death test; 0 in the child process itself. pid_t child_pid_; }; // Constructs a ForkingDeathTest. ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) : DeathTestImpl(a_statement, a_regex), child_pid_(-1) {} // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int ForkingDeathTest::Wait() { if (!spawned()) return 0; ReadAndInterpretStatusByte(); int status_value; GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); set_status(status_value); return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: NoExecDeathTest(const char* a_statement, const RE* a_regex) : ForkingDeathTest(a_statement, a_regex) { } virtual TestRole AssumeRole(); }; // The AssumeRole process for a fork-and-run death test. It implements a // straightforward fork, with a simple pipe to transmit the status byte. DeathTest::TestRole NoExecDeathTest::AssumeRole() { const size_t thread_count = GetThreadCount(); if (thread_count != 1) { GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); DeathTest::set_last_death_test_message(""); CaptureStderr(); // When we fork the process below, the log file buffers are copied, but the // file descriptors are shared. We flush all log files here so that closing // the file descriptors in the child process doesn't throw off the // synchronization between descriptors and buffers in the parent process. // This is as close to the fork as possible to avoid a race condition in case // there are multiple threads running before the death test, and another // thread writes to the log file. FlushInfoLog(); const pid_t child_pid = fork(); GTEST_DEATH_TEST_CHECK_(child_pid != -1); set_child_pid(child_pid); if (child_pid == 0) { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); set_write_fd(pipe_fd[1]); // Redirects all logging to stderr in the child process to prevent // concurrent writes to the log files. We capture stderr in the parent // process and append the child process' output to a log. LogToStderr(); // Event forwarding to the listeners of event listener API mush be shut // down in death test subprocesses. GetUnitTestImpl()->listeners()->SuppressEventForwarding(); g_in_fast_death_test_child = true; return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } } // A concrete death test class that forks and re-executes the main // program from the beginning, with command-line flags set that cause // only this specific death test to be run. class ExecDeathTest : public ForkingDeathTest { public: ExecDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: static ::std::vector GetArgvsForDeathTestChildProcess() { ::std::vector args = GetInjectableArgvs(); return args; } // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; }; // Utility class for accumulating command-line arguments. class Arguments { public: Arguments() { args_.push_back(NULL); } ~Arguments() { for (std::vector::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } } void AddArgument(const char* argument) { args_.insert(args_.end() - 1, posix::StrDup(argument)); } template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } char* const* Argv() { return &args_[0]; } private: std::vector args_; }; // A struct that encompasses the arguments to the child process of a // threadsafe-style death test process. struct ExecDeathTestArgs { char* const* argv; // Command-line arguments for the child's call to exec int close_fd; // File descriptor to close; the read end of a pipe }; # if GTEST_OS_MAC inline char** GetEnviron() { // When Google Test is built as a framework on MacOS X, the environ variable // is unavailable. Apple's documentation (man environ) recommends using // _NSGetEnviron() instead. return *_NSGetEnviron(); } # else // Some POSIX platforms expect you to declare environ. extern "C" makes // it reside in the global namespace. extern "C" char** environ; inline char** GetEnviron() { return environ; } # endif // GTEST_OS_MAC # if !GTEST_OS_QNX // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. static int ExecDeathTestChildMain(void* child_arg) { ExecDeathTestArgs* const args = static_cast(child_arg); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } // We can safely call execve() as it's a direct system call. We // cannot use execvp() as it's a libc function and thus potentially // unsafe. Since execve() doesn't search the PATH, the user must // invoke the test program via a valid path that contains at least // one path separator. execve(args->argv[0], args->argv, GetEnviron()); DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + original_dir + " failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } # endif // !GTEST_OS_QNX // Two utility routines that together determine the direction the stack // grows. // This could be accomplished more elegantly by a single recursive // function, but we want to guard against the unlikely possibility of // a smart compiler optimizing the recursion away. // // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining // StackLowerThanAddress into StackGrowsDown, which then doesn't give // correct answer. void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; void StackLowerThanAddress(const void* ptr, bool* result) { int dummy; *result = (&dummy < ptr); } bool StackGrowsDown() { int dummy; bool result; StackLowerThanAddress(&dummy, &result); return result; } // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The // implementation uses fork(2) + exec. On systems where clone(2) is // available, it is used instead, being slightly more thread-safe. On QNX, // fork supports only single-threaded environments, so this function uses // spawn(2) there instead. The function dies with an error message if // anything goes wrong. static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { ExecDeathTestArgs args = { argv, close_fd }; pid_t child_pid = -1; # if GTEST_OS_QNX // Obtains the current directory and sets it to be closed in the child // process. const int cwd_fd = open(".", O_RDONLY); GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } int fd_flags; // Set close_fd to be closed after spawn. GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC)); struct inheritance inherit = {0}; // spawn is a system call. child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); // Restores the current working directory. GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); # else // GTEST_OS_QNX # if GTEST_OS_LINUX // When a SIGPROF signal is received while fork() or clone() are executing, // the process may hang. To avoid this, we ignore SIGPROF here and re-enable // it after the call to fork()/clone() is complete. struct sigaction saved_sigprof_action; struct sigaction ignore_sigprof_action; memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); sigemptyset(&ignore_sigprof_action.sa_mask); ignore_sigprof_action.sa_handler = SIG_IGN; GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); # endif // GTEST_OS_LINUX # if GTEST_HAS_CLONE const bool use_fork = GTEST_FLAG(death_test_use_fork); if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); const size_t stack_size = getpagesize(); // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); // Maximum stack alignment in bytes: For a downward-growing stack, this // amount is subtracted from size of the stack space to get an address // that is within the stack space and is aligned on all systems we care // about. As far as I know there is no ABI with stack alignment greater // than 64. We assume stack and stack_size already have alignment of // kMaxStackAlignment. const size_t kMaxStackAlignment = 64; void* const stack_top = static_cast(stack) + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0); child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); } # else const bool use_fork = true; # endif // GTEST_HAS_CLONE if (use_fork && (child_pid = fork()) == 0) { ExecDeathTestChildMain(&args); _exit(0); } # endif // GTEST_OS_QNX # if GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_SYSCALL_( sigaction(SIGPROF, &saved_sigprof_action, NULL)); # endif // GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_(child_pid != -1); return child_pid; } // The AssumeRole process for a fork-and-exec death test. It re-executes the // main program from the beginning, setting the --gtest_filter // and --gtest_internal_run_death_test flags to cause only the current // death test to be re-run. DeathTest::TestRole ExecDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { set_write_fd(flag->write_fd()); return EXECUTE_TEST; } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); // Clear the close-on-exec flag on the write end of the pipe, lest // it be closed when the child process does an exec: GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(pipe_fd[1]); Arguments args; args.AddArguments(GetArgvsForDeathTestChildProcess()); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); DeathTest::set_last_death_test_message(""); CaptureStderr(); // See the comment in NoExecDeathTest::AssumeRole for why the next line // is necessary. FlushInfoLog(); const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } # endif // !GTEST_OS_WINDOWS // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to // by the "test" argument to its address. If the test should be // skipped, sets that pointer to NULL. Returns true, unless the // flag is set to an invalid value. bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const int death_test_index = impl->current_test_info() ->increment_death_test_count(); if (flag != NULL) { if (death_test_index > flag->index()) { DeathTest::set_last_death_test_message( "Death test count (" + StreamableToString(death_test_index) + ") somehow exceeded expected maximum (" + StreamableToString(flag->index()) + ")"); return false; } if (!(flag->file() == file && flag->line() == line && flag->index() == death_test_index)) { *test = NULL; return true; } } # if GTEST_OS_WINDOWS if (GTEST_FLAG(death_test_style) == "threadsafe" || GTEST_FLAG(death_test_style) == "fast") { *test = new WindowsDeathTest(statement, regex, file, line); } # else if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); } # endif // GTEST_OS_WINDOWS else { // NOLINT - this is more readable than unbalanced brackets inside #if. DeathTest::set_last_death_test_message( "Unknown death test style \"" + GTEST_FLAG(death_test_style) + "\" encountered"); return false; } return true; } // Splits a given string on a given delimiter, populating a given // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have // ::std::string, so we can use it here. static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; ::std::string::size_type pos = 0; while (::testing::internal::AlwaysTrue()) { const ::std::string::size_type colon = str.find(delimiter, pos); if (colon == ::std::string::npos) { parsed.push_back(str.substr(pos)); break; } else { parsed.push_back(str.substr(pos, colon - pos)); pos = colon + 1; } } dest->swap(parsed); } # if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. int GetStatusFileDescriptor(unsigned int parent_process_id, size_t write_handle_as_size_t, size_t event_handle_as_size_t) { AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, // Non-inheritable. parent_process_id)); if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { DeathTestAbort("Unable to open parent process " + StreamableToString(parent_process_id)); } // TODO(vladl@google.com): Replace the following check with a // compile-time assertion when available. GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); const HANDLE write_handle = reinterpret_cast(write_handle_as_size_t); HANDLE dup_write_handle; // The newly initialized handle is accessible only in in the parent // process. To obtain one accessible within the child, we need to use // DuplicateHandle. if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, ::GetCurrentProcess(), &dup_write_handle, 0x0, // Requested privileges ignored since // DUPLICATE_SAME_ACCESS is used. FALSE, // Request non-inheritable handler. DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the pipe handle " + StreamableToString(write_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); HANDLE dup_event_handle; if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE, DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the event handle " + StreamableToString(event_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const int write_fd = ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); if (write_fd == -1) { DeathTestAbort("Unable to convert pipe handle " + StreamableToString(write_handle_as_size_t) + " to a file descriptor"); } // Signals the parent that the write end of the pipe has been acquired // so the parent can release its own write end. ::SetEvent(dup_event_handle); return write_fd; } # endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { if (GTEST_FLAG(internal_run_death_test) == "") return NULL; // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // can use it here. int line = -1; int index = -1; ::std::vector< ::std::string> fields; SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); int write_fd = -1; # if GTEST_OS_WINDOWS unsigned int parent_process_id = 0; size_t write_handle_as_size_t = 0; size_t event_handle_as_size_t = 0; if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &parent_process_id) || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, event_handle_as_size_t); # else if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &write_fd)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } # endif // GTEST_OS_WINDOWS return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } } // namespace internal #endif // GTEST_HAS_DEATH_TEST } // namespace testing stimfit-0.16.7/src/test/gtest/src/gtest_main.cc0000664000175000017500000000334514750344764015116 // Copyright 2006, Google Inc. // 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 Google Inc. 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 "gtest/gtest.h" GTEST_API_ int main(int argc, char **argv) { printf("Running main() from gtest_main.cc\n"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } stimfit-0.16.7/src/test/gtest/COPYING0000664000175000017500000000270314750344764012716 Copyright 2008, Google Inc. 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 Google Inc. 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. stimfit-0.16.7/src/test/gtest/include/0000775000175000017500000000000014764352500013354 5stimfit-0.16.7/src/test/gtest/include/gtest/0000775000175000017500000000000014764352500014502 5stimfit-0.16.7/src/test/gtest/include/gtest/gtest-message.h0000664000175000017500000002174214750344764017361 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the Message class. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #include #include "gtest/internal/gtest-port.h" // Ensures that there is at least one operator<< in the global namespace. // See Message& operator<<(...) below for why. void operator<<(const testing::internal::Secret&, int); namespace testing { // The Message class works like an ostream repeater. // // Typical usage: // // 1. You stream a bunch of values to a Message object. // It will remember the text in a stringstream. // 2. Then you stream the Message object to an ostream. // This causes the text in the Message to be streamed // to the ostream. // // For example; // // testing::Message foo; // foo << 1 << " != " << 2; // std::cout << foo; // // will print "1 != 2". // // Message is not intended to be inherited from. In particular, its // destructor is not virtual. // // Note that stringstream behaves differently in gcc and in MSVC. You // can stream a NULL char pointer to it in the former, but not in the // latter (it causes an access violation if you do). The Message // class hides this difference by treating a NULL char pointer as // "(null)". class GTEST_API_ Message { private: // The type of basic IO manipulators (endl, ends, and flush) for // narrow streams. typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); public: // Constructs an empty Message. Message(); // Copy constructor. Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT *ss_ << msg.GetString(); } // Constructs a Message from a C-string. explicit Message(const char* str) : ss_(new ::std::stringstream) { *ss_ << str; } #if GTEST_OS_SYMBIAN // Streams a value (either a pointer or not) to this object. template inline Message& operator <<(const T& value) { StreamHelper(typename internal::is_pointer::type(), value); return *this; } #else // Streams a non-pointer value to this object. template inline Message& operator <<(const T& val) { // Some libraries overload << for STL containers. These // overloads are defined in the global namespace instead of ::std. // // C++'s symbol lookup rule (i.e. Koenig lookup) says that these // overloads are visible in either the std namespace or the global // namespace, but not other namespaces, including the testing // namespace which Google Test's Message class is in. // // To allow STL containers (and other types that has a << operator // defined in the global namespace) to be used in Google Test // assertions, testing::Message must access the custom << operator // from the global namespace. With this using declaration, // overloads of << defined in the global namespace and those // visible via Koenig lookup are both exposed in this function. using ::operator <<; *ss_ << val; return *this; } // Streams a pointer value to this object. // // This function is an overload of the previous one. When you // stream a pointer to a Message, this definition will be used as it // is more specialized. (The C++ Standard, section // [temp.func.order].) If you stream a non-pointer, then the // previous definition will be used. // // The reason for this overload is that streaming a NULL pointer to // ostream is undefined behavior. Depending on the compiler, you // may get "0", "(nil)", "(null)", or an access violation. To // ensure consistent result across compilers, we always treat NULL // as "(null)". template inline Message& operator <<(T* const& pointer) { // NOLINT if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } return *this; } #endif // GTEST_OS_SYMBIAN // Since the basic IO manipulators are overloaded for both narrow // and wide streams, we have to provide this specialized definition // of operator <<, even though its body is the same as the // templatized version above. Without this definition, streaming // endl or other basic IO manipulators to Message will confuse the // compiler. Message& operator <<(BasicNarrowIoManip val) { *ss_ << val; return *this; } // Instead of 1/0, we want to see true/false for bool values. Message& operator <<(bool b) { return *this << (b ? "true" : "false"); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& operator <<(const wchar_t* wide_c_str); Message& operator <<(wchar_t* wide_c_str); #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::std::wstring& wstr); #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::wstring& wstr); #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. std::string GetString() const; private: #if GTEST_OS_SYMBIAN // These are needed as the Nokia Symbian Compiler cannot decide between // const T& and const T* in a function template. The Nokia compiler _can_ // decide between class template specializations for T and T*, so a // tr1::type_traits-like is_pointer works, and we can overload on that. template inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } } template inline void StreamHelper(internal::false_type /*is_pointer*/, const T& value) { // See the comments in Message& operator <<(const T&) above for why // we need this using statement. using ::operator <<; *ss_ << value; } #endif // GTEST_OS_SYMBIAN // We'll hold the text streamed to this object here. const internal::scoped_ptr< ::std::stringstream> ss_; // We declare (but don't implement) this to prevent the compiler // from implementing the assignment operator. void operator=(const Message&); }; // Streams a Message to an ostream. inline std::ostream& operator <<(std::ostream& os, const Message& sb) { return os << sb.GetString(); } namespace internal { // Converts a streamable value to an std::string. A NULL pointer is // converted to "(null)". When the input value is a ::string, // ::std::string, ::wstring, or ::std::wstring object, each NUL // character in it is replaced with "\\0". template std::string StreamableToString(const T& streamable) { return (Message() << streamable).GetString(); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest-param-test.h0000664000175000017500000022413014750344764020006 // This file was GENERATED by command: // pump.py gtest-param-test.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Authors: vladl@google.com (Vlad Losev) // // Macros and functions for implementing parameterized tests // in Google C++ Testing Framework (Google Test) // // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // // Here is how you use value-parameterized tests: #if 0 // To write value-parameterized tests, first you should define a fixture // class. It is usually derived from testing::TestWithParam (see below for // another inheritance scheme that's sometimes useful in more complicated // class hierarchies), where the type of your parameter values. // TestWithParam is itself derived from testing::Test. T can be any // copyable type. If it's a raw pointer, you are responsible for managing the // lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. }; // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" // or "pattern", whichever you prefer to think. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method // of the TestWithParam class: EXPECT_TRUE(foo.Blah(GetParam())); ... } TEST_P(FooTest, HasBlahBlah) { ... } // Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test // case with any set of parameters you want. Google Test defines a number // of functions for generating test parameters. They return what we call // (surprise!) parameter generators. Here is a summary of them, which // are all in the testing namespace: // // // Range(begin, end [, step]) - Yields values {begin, begin+step, // begin+step+step, ...}. The values do not // include end. step defaults to 1. // Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. // ValuesIn(container) - Yields values from a C-style array, an STL // ValuesIn(begin,end) container, or an iterator range [begin, end). // Bool() - Yields sequence {false, true}. // Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product // for the math savvy) of the values generated // by the N generators. // // For more details, see comments at the definitions of these functions below // in this file. // // The following statement will instantiate tests from the FooTest test case // each with parameter values "meeny", "miny", and "moe". INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest, Values("meeny", "miny", "moe")); // To distinguish different instances of the pattern, (yes, you // can instantiate it more then once) the first argument to the // INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the // actual test case name. Remember to pick unique prefixes for different // instantiations. The tests from the instantiation above will have // these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" // * InstantiationName/FooTest.DoesBlah/2 for "moe" // * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" // * InstantiationName/FooTest.HasBlahBlah/1 for "miny" // * InstantiationName/FooTest.HasBlahBlah/2 for "moe" // // You can use these names in --gtest_filter. // // This statement will instantiate all tests from FooTest again, each // with parameter values "cat" and "dog": const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // The tests from the instantiation above will have these names: // // * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" // * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" // * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" // * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" // // Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // // Please also note that generator expressions (including parameters to the // generators) are evaluated in InitGoogleTest(), after main() has started. // This allows the user on one hand, to adjust generator parameters in order // to dynamically determine a set of tests to run and on the other hand, // give the user a chance to inspect the generated tests with Google Test // reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. // // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. // // // A parameterized test fixture must be derived from testing::Test and from // testing::WithParamInterface, where T is the type of the parameter // values. Inheriting from TestWithParam satisfies that requirement because // TestWithParam inherits from both Test and WithParamInterface. In more // complicated hierarchies, however, it is occasionally useful to inherit // separately from Test and WithParamInterface. For example: class BaseTest : public ::testing::Test { // You can inherit all the usual members for a non-parameterized test // fixture here. }; class DerivedTest : public BaseTest, public ::testing::WithParamInterface { // The usual test fixture members go here too. }; TEST_F(BaseTest, HasFoo) { // This is an ordinary non-parameterized test. } TEST_P(DerivedTest, DoesBlah) { // GetParam works just the same here as if you inherit from TestWithParam. EXPECT_TRUE(foo.Blah(GetParam())); } #endif // 0 #include "gtest/internal/gtest-port.h" #if !GTEST_OS_SYMBIAN # include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-param-util-generated.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- // parameterized tests. When a parameterized test case is instantiated // with a particular generator, Google Test creates and runs tests // for each element in the sequence produced by the generator. // // In the following sample, tests from test case FooTest are instantiated // each three times with parameter values 3, 5, and 8: // // class FooTest : public TestWithParam { ... }; // // TEST_P(FooTest, TestThis) { // } // TEST_P(FooTest, TestThat) { // } // INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); // // Range() returns generators providing sequences of values in a range. // // Synopsis: // Range(start, end) // - returns a generator producing a sequence of values {start, start+1, // start+2, ..., }. // Range(start, end, step) // - returns a generator producing a sequence of values {start, start+step, // start+step+step, ..., }. // Notes: // * The generated sequences never include end. For example, Range(1, 5) // returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) // returns a generator producing {1, 3, 5, 7}. // * start and end must have the same type. That type may be any integral or // floating-point type or a user defined type satisfying these conditions: // * It must be assignable (have operator=() defined). // * It must have operator+() (operator+(int-compatible type) for // two-operand version). // * It must have operator<() defined. // Elements in the resulting sequences will also have that type. // * Condition start < end must be satisfied in order for resulting sequences // to contain any elements. // template internal::ParamGenerator Range(T start, T end, IncrementT step) { return internal::ParamGenerator( new internal::RangeGenerator(start, end, step)); } template internal::ParamGenerator Range(T start, T end) { return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from // a container. // // Synopsis: // ValuesIn(const T (&array)[N]) // - returns a generator producing sequences with elements from // a C-style array. // ValuesIn(const Container& container) // - returns a generator producing sequences with elements from // an STL-style container. // ValuesIn(Iterator begin, Iterator end) // - returns a generator producing sequences with elements from // a range [begin, end) defined by a pair of STL-style iterators. These // iterators can also be plain C pointers. // // Please note that ValuesIn copies the values from the containers // passed in and keeps them to generate tests in RUN_ALL_TESTS(). // // Examples: // // This instantiates tests from test case StringTest // each with C-string values of "foo", "bar", and "baz": // // const char* strings[] = {"foo", "bar", "baz"}; // INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); // // This instantiates tests from test case StlStringTest // each with STL strings with values "a" and "b": // // ::std::vector< ::std::string> GetParameterStrings() { // ::std::vector< ::std::string> v; // v.push_back("a"); // v.push_back("b"); // return v; // } // // INSTANTIATE_TEST_CASE_P(CharSequence, // StlStringTest, // ValuesIn(GetParameterStrings())); // // // This will also instantiate tests from CharTest // each with parameter values 'a' and 'b': // // ::std::list GetParameterChars() { // ::std::list list; // list.push_back('a'); // list.push_back('b'); // return list; // } // ::std::list l = GetParameterChars(); // INSTANTIATE_TEST_CASE_P(CharSequence2, // CharTest, // ValuesIn(l.begin(), l.end())); // template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end) { typedef typename ::testing::internal::IteratorTraits ::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } template internal::ParamGenerator ValuesIn(const T (&array)[N]) { return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( const Container& container) { return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of // parameters. // // Synopsis: // Values(T v1, T v2, ..., T vN) // - returns a generator producing sequences with elements v1, v2, ..., vN. // // For example, this instantiates tests from test case BarTest each // with values "one", "two", and "three": // // INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); // // This instantiates tests from test case BazTest each with values 1, 2, 3.5. // The exact type of values will depend on the type of parameter in BazTest. // // INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); // // Currently, Values() supports from 1 to 50 parameters. // template internal::ValueArray1 Values(T1 v1) { return internal::ValueArray1(v1); } template internal::ValueArray2 Values(T1 v1, T2 v2) { return internal::ValueArray2(v1, v2); } template internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { return internal::ValueArray3(v1, v2, v3); } template internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { return internal::ValueArray4(v1, v2, v3, v4); } template internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { return internal::ValueArray5(v1, v2, v3, v4, v5); } template internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) { return internal::ValueArray6(v1, v2, v3, v4, v5, v6); } template internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) { return internal::ValueArray7(v1, v2, v3, v4, v5, v6, v7); } template internal::ValueArray8 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { return internal::ValueArray8(v1, v2, v3, v4, v5, v6, v7, v8); } template internal::ValueArray9 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { return internal::ValueArray9(v1, v2, v3, v4, v5, v6, v7, v8, v9); } template internal::ValueArray10 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { return internal::ValueArray10(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); } template internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) { return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); } template internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) { return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); } template internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) { return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); } template internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14); } template internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); } template internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) { return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16); } template internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) { return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17); } template internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) { return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18); } template internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); } template internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); } template internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { return internal::ValueArray21(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); } template internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) { return internal::ValueArray22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22); } template internal::ValueArray23 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) { return internal::ValueArray23(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23); } template internal::ValueArray24 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) { return internal::ValueArray24(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24); } template internal::ValueArray25 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { return internal::ValueArray25(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25); } template internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) { return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); } template internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) { return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); } template internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) { return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28); } template internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) { return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29); } template internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30); } template internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31); } template internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) { return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32); } template internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) { return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); } template internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) { return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); } template internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { return internal::ValueArray35(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); } template internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { return internal::ValueArray36(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36); } template internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) { return internal::ValueArray37(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37); } template internal::ValueArray38 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) { return internal::ValueArray38(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38); } template internal::ValueArray39 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) { return internal::ValueArray39(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39); } template internal::ValueArray40 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); } template internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); } template internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) { return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42); } template internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) { return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43); } template internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) { return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44); } template internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45); } template internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46); } template internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); } template internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) { return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); } template internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) { return internal::ValueArray49(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); } template internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { return internal::ValueArray50(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50); } // Bool() allows generating tests with parameters in a set of (false, true). // // Synopsis: // Bool() // - returns a generator producing sequences with elements {false, true}. // // It is useful when testing code that depends on Boolean flags. Combinations // of multiple flags can be tested when several Bool()'s are combined using // Combine() function. // // In the following example all tests in the test case FlagDependentTest // will be instantiated twice with parameters false and true. // // class FlagDependentTest : public testing::TestWithParam { // virtual void SetUp() { // external_flag = GetParam(); // } // } // INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); // inline internal::ParamGenerator Bool() { return Values(false, true); } # if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // // Synopsis: // Combine(gen1, gen2, ..., genN) // - returns a generator producing sequences with elements coming from // the Cartesian product of elements from the sequences generated by // gen1, gen2, ..., genN. The sequence elements will have a type of // tuple where T1, T2, ..., TN are the types // of elements from sequences produces by gen1, gen2, ..., genN. // // Combine can have up to 10 arguments. This number is currently limited // by the maximum number of elements in the tuple implementation used by Google // Test. // // Example: // // This will instantiate tests in test case AnimalTest each one with // the parameter values tuple("cat", BLACK), tuple("cat", WHITE), // tuple("dog", BLACK), and tuple("dog", WHITE): // // enum Color { BLACK, GRAY, WHITE }; // class AnimalTest // : public testing::TestWithParam > {...}; // // TEST_P(AnimalTest, AnimalLooksNice) {...} // // INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, // Combine(Values("cat", "dog"), // Values(BLACK, WHITE))); // // This will instantiate tests in FlagDependentTest with all variations of two // Boolean flags: // // class FlagDependentTest // : public testing::TestWithParam > { // virtual void SetUp() { // // Assigns external_flag_1 and external_flag_2 values from the tuple. // tie(external_flag_1, external_flag_2) = GetParam(); // } // }; // // TEST_P(FlagDependentTest, TestFeature1) { // // Test your code using external_flag_1 and external_flag_2 here. // } // INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, // Combine(Bool(), Bool())); // template internal::CartesianProductHolder2 Combine( const Generator1& g1, const Generator2& g2) { return internal::CartesianProductHolder2( g1, g2); } template internal::CartesianProductHolder3 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3) { return internal::CartesianProductHolder3( g1, g2, g3); } template internal::CartesianProductHolder4 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4) { return internal::CartesianProductHolder4( g1, g2, g3, g4); } template internal::CartesianProductHolder5 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) { return internal::CartesianProductHolder5( g1, g2, g3, g4, g5); } template internal::CartesianProductHolder6 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) { return internal::CartesianProductHolder6( g1, g2, g3, g4, g5, g6); } template internal::CartesianProductHolder7 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) { return internal::CartesianProductHolder7( g1, g2, g3, g4, g5, g6, g7); } template internal::CartesianProductHolder8 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) { return internal::CartesianProductHolder8( g1, g2, g3, g4, g5, g6, g7, g8); } template internal::CartesianProductHolder9 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) { return internal::CartesianProductHolder9( g1, g2, g3, g4, g5, g6, g7, g8, g9); } template internal::CartesianProductHolder10 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) { return internal::CartesianProductHolder10( g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); } # endif // GTEST_HAS_COMBINE # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ public: \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ virtual void TestBody(); \ private: \ static int AddToRegistry() { \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \ #test_name, \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ return 0; \ } \ static int gtest_registering_dummy_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ int GTEST_TEST_CLASS_NAME_(test_case_name, \ test_name)::gtest_registering_dummy_ = \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() # define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ ::testing::internal::ParamGenerator \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ int gtest_##prefix##test_case_name##_dummy_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #prefix, \ >est_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__) } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest-test-part.h0000664000175000017500000001455514750344764017664 // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Author: mheule@google.com (Markus Heule) // #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #include #include #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" namespace testing { // A copyable object representing the result of a test part (i.e. an // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // // Don't inherit from TestPartResult as its destructor is not virtual. class GTEST_API_ TestPartResult { public: // The possible outcomes of a test part (i.e. an assertion or an // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). enum Type { kSuccess, // Succeeded. kNonFatalFailure, // Failed but the test can continue. kFatalFailure // Failed and the test should be terminated. }; // C'tor. TestPartResult does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestPartResult object. TestPartResult(Type a_type, const char* a_file_name, int a_line_number, const char* a_message) : type_(a_type), file_name_(a_file_name == NULL ? "" : a_file_name), line_number_(a_line_number), summary_(ExtractSummary(a_message)), message_(a_message) { } // Gets the outcome of the test part. Type type() const { return type_; } // Gets the name of the source file where the test part took place, or // NULL if it's unknown. const char* file_name() const { return file_name_.empty() ? NULL : file_name_.c_str(); } // Gets the line in the source file where the test part took place, // or -1 if it's unknown. int line_number() const { return line_number_; } // Gets the summary of the failure message. const char* summary() const { return summary_.c_str(); } // Gets the message associated with the test part. const char* message() const { return message_.c_str(); } // Returns true iff the test part passed. bool passed() const { return type_ == kSuccess; } // Returns true iff the test part failed. bool failed() const { return type_ != kSuccess; } // Returns true iff the test part non-fatally failed. bool nonfatally_failed() const { return type_ == kNonFatalFailure; } // Returns true iff the test part fatally failed. bool fatally_failed() const { return type_ == kFatalFailure; } private: Type type_; // Gets the summary of the failure message by omitting the stack // trace in it. static std::string ExtractSummary(const char* message); // The name of the source file where the test part took place, or // "" if the source file is unknown. std::string file_name_; // The line in the source file where the test part took place, or -1 // if the line number is unknown. int line_number_; std::string summary_; // The test failure summary. std::string message_; // The test failure message. }; // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result); // An array of TestPartResult objects. // // Don't inherit from TestPartResultArray as its destructor is not // virtual. class GTEST_API_ TestPartResultArray { public: TestPartResultArray() {} // Appends the given TestPartResult to the array. void Append(const TestPartResult& result); // Returns the TestPartResult at the given index (0-based). const TestPartResult& GetTestPartResult(int index) const; // Returns the number of TestPartResult objects in the array. int size() const; private: std::vector array_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); }; // This interface knows how to report a test part result. class TestPartResultReporterInterface { public: virtual ~TestPartResultReporterInterface() {} virtual void ReportTestPartResult(const TestPartResult& result) = 0; }; namespace internal { // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a // statement generates new fatal failures. To do so it registers itself as the // current test part result reporter. Besides checking if fatal failures were // reported, it only delegates the reporting to the former result reporter. // The original result reporter is restored in the destructor. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. class GTEST_API_ HasNewFatalFailureHelper : public TestPartResultReporterInterface { public: HasNewFatalFailureHelper(); virtual ~HasNewFatalFailureHelper(); virtual void ReportTestPartResult(const TestPartResult& result); bool has_new_fatal_failure() const { return has_new_fatal_failure_; } private: bool has_new_fatal_failure_; TestPartResultReporterInterface* original_reporter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); }; } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest_pred_impl.h0000664000175000017500000003545114750344764017774 // Copyright 2006, Google Inc. // 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 Google Inc. 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. // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // // Implements a family of generic predicate assertion macros. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ // Makes sure this header is not included before gtest.h. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ # error Do not include gtest_pred_impl.h directly. Include gtest.h instead. #endif // GTEST_INCLUDE_GTEST_GTEST_H_ // This header implements a family of generic predicate assertion // macros: // // ASSERT_PRED_FORMAT1(pred_format, v1) // ASSERT_PRED_FORMAT2(pred_format, v1, v2) // ... // // where pred_format is a function or functor that takes n (in the // case of ASSERT_PRED_FORMATn) values and their source expression // text, and returns a testing::AssertionResult. See the definition // of ASSERT_EQ in gtest.h for an example. // // If you don't care about formatting, you can use the more // restrictive version: // // ASSERT_PRED1(pred, v1) // ASSERT_PRED2(pred, v1, v2) // ... // // where pred is an n-ary function or functor that returns bool, // and the values v1, v2, ..., must support the << operator for // streaming to std::ostream. // // We also define the EXPECT_* variations. // // For now we only support predicates whose arity is at most 5. // Please email googletestframework@googlegroups.com if you need // support for higher arities. // GTEST_ASSERT_ is the basic statement to which all of the assertions // in this file reduce. Don't use this in your code. #define GTEST_ASSERT_(expression, on_failure) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar = (expression)) \ ; \ else \ on_failure(gtest_ar.failure_message()) // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. template AssertionResult AssertPred1Helper(const char* pred_text, const char* e1, Pred pred, const T1& v1) { if (pred(v1)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Don't use this in your code. #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ GTEST_ASSERT_(pred_format(#v1, v1), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. #define GTEST_PRED1_(pred, v1, on_failure)\ GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ #v1, \ pred, \ v1), on_failure) // Unary predicate assertion macros. #define EXPECT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) #define ASSERT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. template AssertionResult AssertPred2Helper(const char* pred_text, const char* e1, const char* e2, Pred pred, const T1& v1, const T2& v2) { if (pred(v1, v2)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Don't use this in your code. #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. #define GTEST_PRED2_(pred, v1, v2, on_failure)\ GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ #v1, \ #v2, \ pred, \ v1, \ v2), on_failure) // Binary predicate assertion macros. #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) #define ASSERT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. template AssertionResult AssertPred3Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, Pred pred, const T1& v1, const T2& v2, const T3& v3) { if (pred(v1, v2, v3)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Don't use this in your code. #define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. #define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ #v1, \ #v2, \ #v3, \ pred, \ v1, \ v2, \ v3), on_failure) // Ternary predicate assertion macros. #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) #define ASSERT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. template AssertionResult AssertPred4Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4) { if (pred(v1, v2, v3, v4)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Don't use this in your code. #define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. #define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ pred, \ v1, \ v2, \ v3, \ v4), on_failure) // 4-ary predicate assertion macros. #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) #define ASSERT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. template AssertionResult AssertPred5Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, const char* e5, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) { if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ", " << e5 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4 << "\n" << e5 << " evaluates to " << v5; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Don't use this in your code. #define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. #define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ #v5, \ pred, \ v1, \ v2, \ v3, \ v4, \ v5), on_failure) // 5-ary predicate assertion macros. #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest.h0000664000175000017500000025456214750344764015747 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for Google Test. It should be // included by any test program that uses Google Test. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! // // Acknowledgment: Google Test borrowed the idea of automatic test // registration from Barthelemy Dagenais' (barthelemy@prologique.com) // easyUnit framework. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_ #include #include #include #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" #include "gtest/gtest-death-test.h" #include "gtest/gtest-message.h" #include "gtest/gtest-param-test.h" #include "gtest/gtest-printers.h" #include "gtest/gtest_prod.h" #include "gtest/gtest-test-part.h" #include "gtest/gtest-typed-test.h" // Depending on the platform, different string classes are available. // On Linux, in addition to ::std::string, Google also makes use of // class ::string, which has the same interface as ::std::string, but // has a different implementation. // // The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that // ::string is available AND is a distinct type to ::std::string, or // define it to 0 to indicate otherwise. // // If the user's ::std::string and ::string are the same class due to // aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. // // If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined // heuristically. namespace testing { // Declares the flags. // This flag temporary enables the disabled tests. GTEST_DECLARE_bool_(also_run_disabled_tests); // This flag brings the debugger on an assertion failure. GTEST_DECLARE_bool_(break_on_failure); // This flag controls whether Google Test catches all test-thrown exceptions // and logs them as failures. GTEST_DECLARE_bool_(catch_exceptions); // This flag enables using colors in terminal output. Available values are // "yes" to enable colors, "no" (disable colors), or "auto" (the default) // to let Google Test decide. GTEST_DECLARE_string_(color); // This flag sets up the filter to select by name using a glob pattern // the tests to run. If the filter is not given all tests are executed. GTEST_DECLARE_string_(filter); // This flag causes the Google Test to list tests. None of the tests listed // are actually run if the flag is provided. GTEST_DECLARE_bool_(list_tests); // This flag controls whether Google Test emits a detailed XML report to a file // in addition to its normal textual output. GTEST_DECLARE_string_(output); // This flags control whether Google Test prints the elapsed time for each // test. GTEST_DECLARE_bool_(print_time); // This flag specifies the random number seed. GTEST_DECLARE_int32_(random_seed); // This flag sets how many times the tests are repeated. The default value // is 1. If the value is -1 the tests are repeating forever. GTEST_DECLARE_int32_(repeat); // This flag controls whether Google Test includes Google Test internal // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); // When this flag is specified, tests' order is randomized on every iteration. GTEST_DECLARE_bool_(shuffle); // This flag specifies the maximum number of stack frames to be // printed in a failure message. GTEST_DECLARE_int32_(stack_trace_depth); // When this flag is specified, a failed assertion will throw an // exception if exceptions are enabled, or exit the program with a // non-zero code otherwise. GTEST_DECLARE_bool_(throw_on_failure); // When this flag is set with a "host:port" string, on supported // platforms test results are streamed to the specified port on // the specified host machine. GTEST_DECLARE_string_(stream_result_to); // The upper limit for valid stack trace depths. const int kMaxStackTraceDepth = 100; namespace internal { class AssertHelper; class DefaultGlobalTestPartResultReporter; class ExecDeathTest; class NoExecDeathTest; class FinalSuccessChecker; class GTestFlagSaver; class StreamingListenerTest; class TestResultAccessor; class TestEventListenersAccessor; class TestEventRepeater; class UnitTestRecordPropertyTestHelper; class WindowsDeathTest; class UnitTestImpl* GetUnitTestImpl(); void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message); } // namespace internal // The friend relationship of some of these classes is cyclic. // If we don't forward declare them the compiler might confuse the classes // in friendship clauses with same named classes on the scope. class Test; class TestCase; class TestInfo; class UnitTest; // A class for indicating whether an assertion was successful. When // the assertion wasn't successful, the AssertionResult object // remembers a non-empty message that describes how it failed. // // To create an instance of this class, use one of the factory functions // (AssertionSuccess() and AssertionFailure()). // // This class is useful for two purposes: // 1. Defining predicate functions to be used with Boolean test assertions // EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts // 2. Defining predicate-format functions to be // used with predicate assertions (ASSERT_PRED_FORMAT*, etc). // // For example, if you define IsEven predicate: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) // will print the message // // Value of: IsEven(Fib(5)) // Actual: false (5 is odd) // Expected: true // // instead of a more opaque // // Value of: IsEven(Fib(5)) // Actual: false // Expected: true // // in case IsEven is a simple Boolean predicate. // // If you expect your predicate to be reused and want to support informative // messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up // about half as often as positive ones in our tests), supply messages for // both success and failure cases: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess() << n << " is even"; // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print // // Value of: IsEven(Fib(6)) // Actual: true (8 is even) // Expected: false // // NB: Predicates that support negative Boolean assertions have reduced // performance in positive ones so be careful not to use them in tests // that have lots (tens of thousands) of positive Boolean assertions. // // To use this class with EXPECT_PRED_FORMAT assertions such as: // // // Verifies that Foo() returns an even number. // EXPECT_PRED_FORMAT1(IsEven, Foo()); // // you need to define: // // testing::AssertionResult IsEven(const char* expr, int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() // << "Expected: " << expr << " is even\n Actual: it's " << n; // } // // If Foo() returns 5, you will see the following message: // // Expected: Foo() is even // Actual: it's 5 // class GTEST_API_ AssertionResult { public: // Copy constructor. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult(const AssertionResult& other); // Used in the EXPECT_TRUE/FALSE(bool_expression). explicit AssertionResult(bool success) : success_(success) {} // Returns true iff the assertion succeeded. operator bool() const { return success_; } // NOLINT // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult operator!() const; // Returns the text streamed into this AssertionResult. Test assertions // use it when they fail (i.e., the predicate's outcome doesn't match the // assertion's expectation). When nothing has been streamed into the // object, returns an empty string. const char* message() const { return message_.get() != NULL ? message_->c_str() : ""; } // TODO(vladl@google.com): Remove this after making sure no clients use it. // Deprecated; please use message() instead. const char* failure_message() const { return message(); } // Streams a custom failure message into this object. template AssertionResult& operator<<(const T& value) { AppendMessage(Message() << value); return *this; } // Allows streaming basic output manipulators such as endl or flush into // this object. AssertionResult& operator<<( ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { AppendMessage(Message() << basic_manipulator); return *this; } private: // Appends the contents of message to message_. void AppendMessage(const Message& a_message) { if (message_.get() == NULL) message_.reset(new ::std::string); message_->append(a_message.GetString().c_str()); } // Stores result of the assertion predicate. bool success_; // Stores the message describing the condition in case the expectation // construct is not satisfied with the predicate's outcome. // Referenced via a pointer to avoid taking too much stack frame space // with test assertions. internal::scoped_ptr< ::std::string> message_; GTEST_DISALLOW_ASSIGN_(AssertionResult); }; // Makes a successful assertion result. GTEST_API_ AssertionResult AssertionSuccess(); // Makes a failed assertion result. GTEST_API_ AssertionResult AssertionFailure(); // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << msg. GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // The abstract class that all tests inherit from. // // In Google Test, a unit test program contains one or many TestCases, and // each TestCase contains one or many Tests. // // When you define a test using the TEST macro, you don't need to // explicitly derive from Test - the TEST macro automatically does // this for you. // // The only time you derive from Test is when defining a test fixture // to be used a TEST_F. For example: // // class FooTest : public testing::Test { // protected: // virtual void SetUp() { ... } // virtual void TearDown() { ... } // ... // }; // // TEST_F(FooTest, Bar) { ... } // TEST_F(FooTest, Baz) { ... } // // Test is not copyable. class GTEST_API_ Test { public: friend class TestInfo; // Defines types for pointers to functions that set up and tear down // a test case. typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; // The d'tor is virtual as we intend to inherit from Test. virtual ~Test(); // Sets up the stuff shared by all tests in this test case. // // Google Test will call Foo::SetUpTestCase() before running the first // test in test case Foo. Hence a sub-class can define its own // SetUpTestCase() method to shadow the one defined in the super // class. static void SetUpTestCase() {} // Tears down the stuff shared by all tests in this test case. // // Google Test will call Foo::TearDownTestCase() after running the last // test in test case Foo. Hence a sub-class can define its own // TearDownTestCase() method to shadow the one defined in the super // class. static void TearDownTestCase() {} // Returns true iff the current test has a fatal failure. static bool HasFatalFailure(); // Returns true iff the current test has a non-fatal failure. static bool HasNonfatalFailure(); // Returns true iff the current test has a (either fatal or // non-fatal) failure. static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } // Logs a property for the current test, test case, or for the entire // invocation of the test program when used outside of the context of a // test case. Only the last value for a given key is remembered. These // are public static so they can be called from utility functions that are // not members of the test fixture. Calls to RecordProperty made during // lifespan of the test (from the moment its constructor starts to the // moment its destructor finishes) will be output in XML as attributes of // the element. Properties recorded from fixture's // SetUpTestCase or TearDownTestCase are logged as attributes of the // corresponding element. Calls to RecordProperty made in the // global context (before or after invocation of RUN_ALL_TESTS and from // SetUp/TearDown method of Environment objects registered with Google // Test) will be output as attributes of the element. static void RecordProperty(const std::string& key, const std::string& value); static void RecordProperty(const std::string& key, int value); protected: // Creates a Test object. Test(); // Sets up the test fixture. virtual void SetUp(); // Tears down the test fixture. virtual void TearDown(); private: // Returns true iff the current test has the same fixture class as // the first test in the current test case. static bool HasSameFixtureClass(); // Runs the test after the test fixture has been set up. // // A sub-class must implement this to define the test logic. // // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. // Instead, use the TEST or TEST_F macro. virtual void TestBody() = 0; // Sets up, executes, and tears down the test. void Run(); // Deletes self. We deliberately pick an unusual name for this // internal method to avoid clashing with names used in user TESTs. void DeleteSelf_() { delete this; } // Uses a GTestFlagSaver to save and restore all Google Test flags. const internal::GTestFlagSaver* const gtest_flag_saver_; // Often a user mis-spells SetUp() as Setup() and spends a long time // wondering why it is never called by Google Test. The declaration of // the following method is solely for catching such an error at // compile time: // // - The return type is deliberately chosen to be not void, so it // will be a conflict if a user declares void Setup() in his test // fixture. // // - This method is private, so it will be another compiler error // if a user calls it from his test fixture. // // DO NOT OVERRIDE THIS FUNCTION. // // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } // We disallow copying Tests. GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); }; typedef internal::TimeInMillis TimeInMillis; // A copyable object representing a user specified test property which can be // output as a key/value string pair. // // Don't inherit from TestProperty as its destructor is not virtual. class TestProperty { public: // C'tor. TestProperty does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestProperty object. TestProperty(const std::string& a_key, const std::string& a_value) : key_(a_key), value_(a_value) { } // Gets the user supplied key. const char* key() const { return key_.c_str(); } // Gets the user supplied value. const char* value() const { return value_.c_str(); } // Sets a new value, overriding the one supplied in the constructor. void SetValue(const std::string& new_value) { value_ = new_value; } private: // The key supplied by the user. std::string key_; // The value supplied by the user. std::string value_; }; // The result of a single Test. This includes a list of // TestPartResults, a list of TestProperties, a count of how many // death tests there are in the Test, and how much time it took to run // the Test. // // TestResult is not copyable. class GTEST_API_ TestResult { public: // Creates an empty TestResult. TestResult(); // D'tor. Do not inherit from TestResult. ~TestResult(); // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int total_part_count() const; // Returns the number of the test properties. int test_property_count() const; // Returns true iff the test passed (i.e. no test part failed). bool Passed() const { return !Failed(); } // Returns true iff the test failed. bool Failed() const; // Returns true iff the test fatally failed. bool HasFatalFailure() const; // Returns true iff the test has a non-fatal failure. bool HasNonfatalFailure() const; // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test part result among all the results. i can range // from 0 to test_property_count() - 1. If i is not in that range, aborts // the program. const TestPartResult& GetTestPartResult(int i) const; // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& GetTestProperty(int i) const; private: friend class TestInfo; friend class TestCase; friend class UnitTest; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::ExecDeathTest; friend class internal::TestResultAccessor; friend class internal::UnitTestImpl; friend class internal::WindowsDeathTest; // Gets the vector of TestPartResults. const std::vector& test_part_results() const { return test_part_results_; } // Gets the vector of TestProperties. const std::vector& test_properties() const { return test_properties_; } // Sets the elapsed time. void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } // Adds a test property to the list. The property is validated and may add // a non-fatal failure if invalid (e.g., if it conflicts with reserved // key names). If a property is already recorded for the same key, the // value will be updated, rather than storing multiple values for the same // key. xml_element specifies the element for which the property is being // recorded and is used for validation. void RecordProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a failure if the key is a reserved attribute of Google Test // testcase tags. Returns true if the property is valid. // TODO(russr): Validate attribute names are legal and human readable. static bool ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a test part result to the list. void AddTestPartResult(const TestPartResult& test_part_result); // Returns the death test count. int death_test_count() const { return death_test_count_; } // Increments the death test count, returning the new count. int increment_death_test_count() { return ++death_test_count_; } // Clears the test part results. void ClearTestPartResults(); // Clears the object. void Clear(); // Protects mutable state of the property vector and of owned // properties, whose values may be updated. internal::Mutex test_properites_mutex_; // The vector of TestPartResults std::vector test_part_results_; // The vector of TestProperties std::vector test_properties_; // Running count of death tests. int death_test_count_; // The elapsed time, in milliseconds. TimeInMillis elapsed_time_; // We disallow copying TestResult. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); }; // class TestResult // A TestInfo object stores the following information about a test: // // Test case name // Test name // Whether the test should be run // A function pointer that creates the test object when invoked // Test result // // The constructor of TestInfo registers itself with the UnitTest // singleton such that the RUN_ALL_TESTS() macro knows which tests to // run. class GTEST_API_ TestInfo { public: // Destructs a TestInfo object. This function is not virtual, so // don't inherit from TestInfo. ~TestInfo(); // Returns the test case name. const char* test_case_name() const { return test_case_name_.c_str(); } // Returns the test name. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a typed // or a type-parameterized test. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns the text representation of the value parameter, or NULL if this // is not a value-parameterized test. const char* value_param() const { if (value_param_.get() != NULL) return value_param_->c_str(); return NULL; } // Returns true if this test should run, that is if the test is not // disabled (or it is disabled but the also_run_disabled_tests flag has // been specified) and its full name matches the user-specified filter. // // Google Test allows the user to filter the tests by their full names. // The full name of a test Bar in test case Foo is defined as // "Foo.Bar". Only the tests that match the filter will run. // // A filter is a colon-separated list of glob (not regex) patterns, // optionally followed by a '-' and a colon-separated list of // negative patterns (tests to exclude). A test is run if it // matches one of the positive patterns and does not match any of // the negative patterns. // // For example, *A*:Foo.* is a filter that matches any string that // contains the character 'A' or starts with "Foo.". bool should_run() const { return should_run_; } // Returns true iff this test will appear in the XML report. bool is_reportable() const { // For now, the XML report includes all tests matching the filter. // In the future, we may trim tests that are excluded because of // sharding. return matches_filter_; } // Returns the result of the test. const TestResult* result() const { return &result_; } private: #if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST friend class Test; friend class TestCase; friend class internal::UnitTestImpl; friend class internal::StreamingListenerTest; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, internal::TypeId fixture_class_id, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, internal::TestFactoryBase* factory); // Constructs a TestInfo object. The newly constructed instance assumes // ownership of the factory object. TestInfo(const std::string& test_case_name, const std::string& name, const char* a_type_param, // NULL if not a type-parameterized test const char* a_value_param, // NULL if not a value-parameterized test internal::TypeId fixture_class_id, internal::TestFactoryBase* factory); // Increments the number of death tests encountered in this test so // far. int increment_death_test_count() { return result_.increment_death_test_count(); } // Creates the test object, runs it, records its result, and then // deletes it. void Run(); static void ClearTestResult(TestInfo* test_info) { test_info->result_.Clear(); } // These fields are immutable properties of the test. const std::string test_case_name_; // Test case name const std::string name_; // Test name // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // Text representation of the value parameter, or NULL if this is not a // value-parameterized test. const internal::scoped_ptr value_param_; const internal::TypeId fixture_class_id_; // ID of the test fixture class bool should_run_; // True iff this test should run bool is_disabled_; // True iff this test is disabled bool matches_filter_; // True if this test matches the // user-specified filter. internal::TestFactoryBase* const factory_; // The factory that creates // the test object // This field is mutable and needs to be reset before running the // test for the second time. TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; // A test case, which consists of a vector of TestInfos. // // TestCase is not copyable. class GTEST_API_ TestCase { public: // Creates a TestCase with the given name. // // TestCase does NOT have a default constructor. Always use this // constructor to create a TestCase object. // // Arguments: // // name: name of the test case // a_type_param: the name of the test's type parameter, or NULL if // this is not a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase(const char* name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Destructor of TestCase. virtual ~TestCase(); // Gets the name of the TestCase. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a // type-parameterized test case. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns true if any test in this test case should run. bool should_run() const { return should_run_; } // Gets the number of successful tests in this test case. int successful_test_count() const; // Gets the number of failed tests in this test case. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests in this test case. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Get the number of tests in this test case that should run. int test_to_run_count() const; // Gets the number of all tests in this test case. int total_test_count() const; // Returns true iff the test case passed. bool Passed() const { return !Failed(); } // Returns true iff the test case failed. bool Failed() const { return failed_test_count() > 0; } // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* GetTestInfo(int i) const; // Returns the TestResult that holds test properties recorded during // execution of SetUpTestCase and TearDownTestCase. const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } private: friend class Test; friend class internal::UnitTestImpl; // Gets the (mutable) vector of TestInfos in this TestCase. std::vector& test_info_list() { return test_info_list_; } // Gets the (immutable) vector of TestInfos in this TestCase. const std::vector& test_info_list() const { return test_info_list_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* GetMutableTestInfo(int i); // Sets the should_run member. void set_should_run(bool should) { should_run_ = should; } // Adds a TestInfo to this test case. Will delete the TestInfo upon // destruction of the TestCase object. void AddTestInfo(TestInfo * test_info); // Clears the results of all tests in this test case. void ClearResult(); // Clears the results of all tests in the given test case. static void ClearTestCaseResult(TestCase* test_case) { test_case->ClearResult(); } // Runs every test in this TestCase. void Run(); // Runs SetUpTestCase() for this TestCase. This wrapper is needed // for catching exceptions thrown from SetUpTestCase(). void RunSetUpTestCase() { (*set_up_tc_)(); } // Runs TearDownTestCase() for this TestCase. This wrapper is // needed for catching exceptions thrown from TearDownTestCase(). void RunTearDownTestCase() { (*tear_down_tc_)(); } // Returns true iff test passed. static bool TestPassed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Passed(); } // Returns true iff test failed. static bool TestFailed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Failed(); } // Returns true iff the test is disabled and will be reported in the XML // report. static bool TestReportableDisabled(const TestInfo* test_info) { return test_info->is_reportable() && test_info->is_disabled_; } // Returns true iff test is disabled. static bool TestDisabled(const TestInfo* test_info) { return test_info->is_disabled_; } // Returns true iff this test will appear in the XML report. static bool TestReportable(const TestInfo* test_info) { return test_info->is_reportable(); } // Returns true if the given test should run. static bool ShouldRunTest(const TestInfo* test_info) { return test_info->should_run(); } // Shuffles the tests in this test case. void ShuffleTests(internal::Random* random); // Restores the test order to before the first shuffle. void UnshuffleTests(); // Name of the test case. std::string name_; // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // The vector of TestInfos in their original order. It owns the // elements in the vector. std::vector test_info_list_; // Provides a level of indirection for the test list to allow easy // shuffling and restoring the test order. The i-th element in this // vector is the index of the i-th test in the shuffled test list. std::vector test_indices_; // Pointer to the function that sets up the test case. Test::SetUpTestCaseFunc set_up_tc_; // Pointer to the function that tears down the test case. Test::TearDownTestCaseFunc tear_down_tc_; // True iff any test in this test case should run. bool should_run_; // Elapsed time, in milliseconds. TimeInMillis elapsed_time_; // Holds test properties recorded during execution of SetUpTestCase and // TearDownTestCase. TestResult ad_hoc_test_result_; // We disallow copying TestCases. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); }; // An Environment object is capable of setting up and tearing down an // environment. The user should subclass this to define his own // environment(s). // // An Environment object does the set-up and tear-down in virtual // methods SetUp() and TearDown() instead of the constructor and the // destructor, as: // // 1. You cannot safely throw from a destructor. This is a problem // as in some cases Google Test is used where exceptions are enabled, and // we may want to implement ASSERT_* using exceptions where they are // available. // 2. You cannot use ASSERT_* directly in a constructor or // destructor. class Environment { public: // The d'tor is virtual as we need to subclass Environment. virtual ~Environment() {} // Override this to define how to set up the environment. virtual void SetUp() {} // Override this to define how to tear down the environment. virtual void TearDown() {} private: // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; // The interface for tracing execution of tests. The methods are organized in // the order the corresponding events are fired. class TestEventListener { public: virtual ~TestEventListener() {} // Fired before any test activity starts. virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; // Fired before each iteration of tests starts. There may be more than // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration // index, starting from 0. virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration) = 0; // Fired before environment set-up for each iteration of tests starts. virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; // Fired after environment set-up for each iteration of tests ends. virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; // Fired before the test case starts. virtual void OnTestCaseStart(const TestCase& test_case) = 0; // Fired before the test starts. virtual void OnTestStart(const TestInfo& test_info) = 0; // Fired after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; // Fired after the test ends. virtual void OnTestEnd(const TestInfo& test_info) = 0; // Fired after the test case ends. virtual void OnTestCaseEnd(const TestCase& test_case) = 0; // Fired before environment tear-down for each iteration of tests starts. virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; // Fired after environment tear-down for each iteration of tests ends. virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; // Fired after each iteration of tests finishes. virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0; // Fired after all test activities have ended. virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; }; // The convenience class for users who need to override just one or two // methods and are not concerned that a possible change to a signature of // the methods they override will not be caught during the build. For // comments about each method please see the definition of TestEventListener // above. class EmptyTestEventListener : public TestEventListener { public: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} virtual void OnTestStart(const TestInfo& /*test_info*/) {} virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} virtual void OnTestEnd(const TestInfo& /*test_info*/) {} virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} }; // TestEventListeners lets users add listeners to track events in Google Test. class GTEST_API_ TestEventListeners { public: TestEventListeners(); ~TestEventListeners(); // Appends an event listener to the end of the list. Google Test assumes // the ownership of the listener (i.e. it will delete the listener when // the test program finishes). void Append(TestEventListener* listener); // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* Release(TestEventListener* listener); // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the caller and makes this // function return NULL the next time. TestEventListener* default_result_printer() const { return default_result_printer_; } // Returns the standard listener responsible for the default XML output // controlled by the --gtest_output=xml flag. Can be removed from the // listeners list by users who want to shut down the default XML output // controlled by this flag and substitute it with custom one. Note that // removing this object from the listener list with Release transfers its // ownership to the caller and makes this function return NULL the next // time. TestEventListener* default_xml_generator() const { return default_xml_generator_; } private: friend class TestCase; friend class TestInfo; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::NoExecDeathTest; friend class internal::TestEventListenersAccessor; friend class internal::UnitTestImpl; // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* repeater(); // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultResultPrinter(TestEventListener* listener); // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultXmlGenerator(TestEventListener* listener); // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool EventForwardingEnabled() const; void SuppressEventForwarding(); // The actual list of listeners. internal::TestEventRepeater* repeater_; // Listener responsible for the standard result output. TestEventListener* default_result_printer_; // Listener responsible for the creation of the XML output file. TestEventListener* default_xml_generator_; // We disallow copying TestEventListeners. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); }; // A UnitTest consists of a vector of TestCases. // // This is a singleton class. The only instance of UnitTest is // created when UnitTest::GetInstance() is first called. This // instance is never deleted. // // UnitTest is not copyable. // // This class is thread-safe as long as the methods are called // according to their specification. class GTEST_API_ UnitTest { public: // Gets the singleton UnitTest object. The first time this method // is called, a UnitTest object is constructed and returned. // Consecutive calls will return the same object. static UnitTest* GetInstance(); // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // This method can only be called from the main thread. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. int Run() GTEST_MUST_USE_RESULT_; // Returns the working directory when the first TEST() or TEST_F() // was executed. The UnitTest object owns the string. const char* original_working_dir() const; // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the random seed used at the start of the current test run. int random_seed() const; #if GTEST_HAS_PARAM_TEST // Returns the ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_); #endif // GTEST_HAS_PARAM_TEST // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const; // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const; // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const; // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const; // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const; // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& ad_hoc_test_result() const; // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& listeners(); private: // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in // the order they were registered. After all tests in the program // have finished, all global test environments will be torn-down in // the *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // This method can only be called from the main thread. Environment* AddEnvironment(Environment* env); // Adds a TestPartResult to the current TestResult object. All // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) // eventually call this to report their results. The user code // should use the assertion macros instead of calling this directly. void AddTestPartResult(TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_); // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void RecordProperty(const std::string& key, const std::string& value); // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i); // Accessors for the implementation object. internal::UnitTestImpl* impl() { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; } // These classes and funcions are friends as they need to access private // members of UnitTest. friend class Test; friend class internal::AssertHelper; friend class internal::ScopedTrace; friend class internal::StreamingListenerTest; friend class internal::UnitTestRecordPropertyTestHelper; friend Environment* AddGlobalTestEnvironment(Environment* env); friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend void internal::ReportFailureInUnknownLocation( TestPartResult::Type result_type, const std::string& message); // Creates an empty UnitTest. UnitTest(); // D'tor virtual ~UnitTest(); // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_); // Pops a trace from the per-thread Google Test trace stack. void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_); // Protects mutable state in *impl_. This is mutable as some const // methods need to lock it too. mutable internal::Mutex mutex_; // Opaque implementation object. This field is never changed once // the object is constructed. We don't mark it as const here, as // doing so will cause a warning in the constructor of UnitTest. // Mutable state in *impl_ is protected by mutex_. internal::UnitTestImpl* impl_; // We disallow copying UnitTest. GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); }; // A convenient wrapper for adding an environment for the test // program. // // You should call this before RUN_ALL_TESTS() is called, probably in // main(). If you use gtest_main, you need to call this before main() // starts for it to take effect. For example, you can define a global // variable like this: // // testing::Environment* const foo_env = // testing::AddGlobalTestEnvironment(new FooEnvironment); // // However, we strongly recommend you to write your own main() and // call AddGlobalTestEnvironment() there, as relying on initialization // of global variables makes the code harder to read and may cause // problems when you register multiple environments from different // translation units and the environments have dependencies among them // (remember that the compiler doesn't guarantee the order in which // global variables from different translation units are initialized). inline Environment* AddGlobalTestEnvironment(Environment* env) { return UnitTest::GetInstance()->AddEnvironment(env); } // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. GTEST_API_ void InitGoogleTest(int* argc, char** argv); // This overloaded version can be used in Windows programs compiled in // UNICODE mode. GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); namespace internal { // FormatForComparison::Format(value) formats a // value of type ToPrint that is an operand of a comparison assertion // (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in // the comparison, and is used to help determine the best way to // format the value. In particular, when the value is a C string // (char pointer) and the other operand is an STL string object, we // want to format the C string as a string, since we know it is // compared by value with the string object. If the value is a char // pointer but the other operand is not an STL string object, we don't // know whether the pointer is supposed to point to a NUL-terminated // string, and thus want to print it as a pointer to be safe. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // The default case. template class FormatForComparison { public: static ::std::string Format(const ToPrint& value) { return ::testing::PrintToString(value); } }; // Array. template class FormatForComparison { public: static ::std::string Format(const ToPrint* value) { return FormatForComparison::Format(value); } }; // By default, print C string as pointers to be safe, as we don't know // whether they actually point to a NUL-terminated string. #define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ template \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(static_cast(value)); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); #undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ // If a C string is compared with an STL string object, we know it's meant // to point to a NUL-terminated string, and thus can print it as a string. #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ template <> \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(value); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); #if GTEST_HAS_GLOBAL_STRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); #endif #if GTEST_HAS_GLOBAL_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); #endif #if GTEST_HAS_STD_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); #endif #undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) // operand to be used in a failure message. The type (but not value) // of the other operand may affect the format. This allows us to // print a char* as a raw pointer when it is compared against another // char* or void*, and print it as a C string when it is compared // against an std::string object, for example. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template std::string FormatForComparisonFailureMessage( const T1& value, const T2& /* other_operand */) { return FormatForComparison::Format(value); } // The helper function for {ASSERT|EXPECT}_EQ. template AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4389) // Temporarily disables warning on // signed/unsigned mismatch. #endif if (expected == actual) { return AssertionSuccess(); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums // can be implicitly cast to BiggestInt. GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual); // The helper class for {ASSERT|EXPECT}_EQ. The template argument // lhs_is_null_literal is true iff the first argument to ASSERT_EQ() // is a null pointer literal. The following default implementation is // for lhs_is_null_literal being false. template class EqHelper { public: // This templatized version is for the general case. template static AssertionResult Compare(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous // enums can be implicitly cast to BiggestInt. // // Even though its body looks the same as the above version, we // cannot merge the two, as it will make anonymous enums unhappy. static AssertionResult Compare(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } }; // This specialization is used when the first argument to ASSERT_EQ() // is a null pointer literal, like NULL, false, or 0. template <> class EqHelper { public: // We define two overloaded versions of Compare(). The first // version will be picked when the second argument to ASSERT_EQ() is // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or // EXPECT_EQ(false, a_bool). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual, // The following line prevents this overload from being considered if T2 // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) // expands to Compare("", "", NULL, my_ptr), which requires a conversion // to match the Secret* in the other overload, which would otherwise make // this template match better. typename EnableIf::value>::type* = 0) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // This version will be picked when the second argument to ASSERT_EQ() is a // pointer, e.g. ASSERT_EQ(NULL, a_pointer). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, // We used to have a second template parameter instead of Secret*. That // template parameter would deduce to 'long', making this a better match // than the first overload even without the first overload's EnableIf. // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to // non-pointer argument" (even a deduced integral argument), so the old // implementation caused warnings in user code. Secret* /* expected (NULL) */, T* actual) { // We already know that 'expected' is a null pointer. return CmpHelperEQ(expected_expression, actual_expression, static_cast(NULL), actual); } }; // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste // of similar code. // // For each templatized helper function, we also define an overloaded // version for BiggestInt in order to reduce code bloat and allow // anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled // with gcc 4. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ template \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ const T1& val1, const T2& val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return AssertionFailure() \ << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ }\ }\ GTEST_API_ AssertionResult CmpHelper##op_name(\ const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // Implements the helper function for {ASSERT|EXPECT}_NE GTEST_IMPL_CMP_HELPER_(NE, !=); // Implements the helper function for {ASSERT|EXPECT}_LE GTEST_IMPL_CMP_HELPER_(LE, <=); // Implements the helper function for {ASSERT|EXPECT}_LT GTEST_IMPL_CMP_HELPER_(LT, <); // Implements the helper function for {ASSERT|EXPECT}_GE GTEST_IMPL_CMP_HELPER_(GE, >=); // Implements the helper function for {ASSERT|EXPECT}_GT GTEST_IMPL_CMP_HELPER_(GT, >); #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRCASEEQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRNE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASENE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual); // Helper function for *_STRNE on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2); } // namespace internal // IsSubstring() and IsNotSubstring() are intended to be used as the // first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by // themselves. They check whether needle is a substring of haystack // (NULL is considered a substring of itself only), and return an // appropriate error message when they fail. // // The {needle,haystack}_expr arguments are the stringified // expressions that generated the two real arguments. GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); #if GTEST_HAS_STD_WSTRING GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); #endif // GTEST_HAS_STD_WSTRING namespace internal { // Helper template function for comparing floating-points. // // Template parameter: // // RawType: the raw floating-point type (either float or double) // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, const char* actual_expression, RawType expected, RawType actual) { const FloatingPoint lhs(expected), rhs(actual); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } ::std::stringstream expected_ss; expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) << expected; ::std::stringstream actual_ss; actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) << actual; return EqFailure(expected_expression, actual_expression, StringStreamToString(&expected_ss), StringStreamToString(&actual_ss), false); } // Helper function for implementing ASSERT_NEAR. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error); // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // A class that enables one to stream messages to assertion macros class GTEST_API_ AssertHelper { public: // Constructor. AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message); ~AssertHelper(); // Message assignment is a semantic trick to enable assertion // streaming; see the GTEST_MESSAGE_ macro below. void operator=(const Message& message) const; private: // We put our data in a struct so that the size of the AssertHelper class can // be as small as possible. This is important because gcc is incapable of // re-using stack space even for temporary variables, so every EXPECT_EQ // reserves stack space for another AssertHelper. struct AssertHelperData { AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num, const char* msg) : type(t), file(srcfile), line(line_num), message(msg) { } TestPartResult::Type const type; const char* const file; int const line; std::string const message; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); }; AssertHelperData* const data_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; } // namespace internal #if GTEST_HAS_PARAM_TEST // The pure interface class that all value-parameterized tests inherit from. // A value-parameterized class must inherit from both ::testing::Test and // ::testing::WithParamInterface. In most cases that just means inheriting // from ::testing::TestWithParam, but more complicated test hierarchies // may need to inherit from Test and WithParamInterface at different levels. // // This interface has support for accessing the test parameter value via // the GetParam() method. // // Use it with one of the parameter generator defining functions, like Range(), // Values(), ValuesIn(), Bool(), and Combine(). // // class FooTest : public ::testing::TestWithParam { // protected: // FooTest() { // // Can use GetParam() here. // } // virtual ~FooTest() { // // Can use GetParam() here. // } // virtual void SetUp() { // // Can use GetParam() here. // } // virtual void TearDown { // // Can use GetParam() here. // } // }; // TEST_P(FooTest, DoesBar) { // // Can use GetParam() method here. // Foo foo; // ASSERT_TRUE(foo.DoesBar(GetParam())); // } // INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); template class WithParamInterface { public: typedef T ParamType; virtual ~WithParamInterface() {} // The current parameter value. Is also available in the test fixture's // constructor. This member function is non-static, even though it only // references static data, to reduce the opportunity for incorrect uses // like writing 'WithParamInterface::GetParam()' for a test that // uses a fixture whose parameter type is int. const ParamType& GetParam() const { GTEST_CHECK_(parameter_ != NULL) << "GetParam() can only be called inside a value-parameterized test " << "-- did you intend to write TEST_P instead of TEST_F?"; return *parameter_; } private: // Sets parameter value. The caller is responsible for making sure the value // remains alive and unchanged throughout the current test. static void SetParam(const ParamType* parameter) { parameter_ = parameter; } // Static value used for accessing parameter during a test lifetime. static const ParamType* parameter_; // TestClass must be a subclass of WithParamInterface and Test. template friend class internal::ParameterizedTestFactory; }; template const T* WithParamInterface::parameter_ = NULL; // Most value-parameterized classes can ignore the existence of // WithParamInterface, and can just inherit from ::testing::TestWithParam. template class TestWithParam : public Test, public WithParamInterface { }; #endif // GTEST_HAS_PARAM_TEST // Macros for indicating success/failure in test code. // ADD_FAILURE unconditionally adds a failure to the current test. // SUCCEED generates a success - it doesn't automatically make the // current test successful, as a test is only successful when it has // no failure. // // EXPECT_* verifies that a certain condition is satisfied. If not, // it behaves like ADD_FAILURE. In particular: // // EXPECT_TRUE verifies that a Boolean condition is true. // EXPECT_FALSE verifies that a Boolean condition is false. // // FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except // that they will also abort the current function on failure. People // usually want the fail-fast behavior of FAIL and ASSERT_*, but those // writing data-driven tests often find themselves using ADD_FAILURE // and EXPECT_* more. // Generates a nonfatal failure with a generic message. #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") // Generates a nonfatal failure at the given source file location with // a generic message. #define ADD_FAILURE_AT(file, line) \ GTEST_MESSAGE_AT_(file, line, "Failed", \ ::testing::TestPartResult::kNonFatalFailure) // Generates a fatal failure with a generic message. #define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_FAIL # define FAIL() GTEST_FAIL() #endif // Generates a success with a generic message. #define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") // Define this macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_SUCCEED # define SUCCEED() GTEST_SUCCEED() #endif // Macros for testing exceptions. // // * {ASSERT|EXPECT}_THROW(statement, expected_exception): // Tests that the statement throws the expected exception. // * {ASSERT|EXPECT}_NO_THROW(statement): // Tests that the statement doesn't throw any exception. // * {ASSERT|EXPECT}_ANY_THROW(statement): // Tests that the statement throws an exception. #define EXPECT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) #define EXPECT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define EXPECT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define ASSERT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) #define ASSERT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) #define ASSERT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) // Boolean assertions. Condition can be either a Boolean expression or an // AssertionResult. For more information on how to use AssertionResult with // these macros see comments on that class. #define EXPECT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_NONFATAL_FAILURE_) #define EXPECT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_NONFATAL_FAILURE_) #define ASSERT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_FATAL_FAILURE_) #define ASSERT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_FATAL_FAILURE_) // Includes the auto-generated header that implements a family of // generic predicate assertion macros. #include "gtest/gtest_pred_impl.h" // Macros for testing equalities and inequalities. // // * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual // * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 // * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 // * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 // * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 // * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 // // When they are not, Google Test prints both the tested expressions and // their actual values. The values must be compatible built-in types, // or you will get a compiler error. By "compatible" we mean that the // values can be compared by the respective operator. // // Note: // // 1. It is possible to make a user-defined type work with // {ASSERT|EXPECT}_??(), but that requires overloading the // comparison operators and is thus discouraged by the Google C++ // Usage Guide. Therefore, you are advised to use the // {ASSERT|EXPECT}_TRUE() macro to assert that two objects are // equal. // // 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on // pointers (in particular, C strings). Therefore, if you use it // with two C strings, you are testing how their locations in memory // are related, not how their content is related. To compare two C // strings by content, use {ASSERT|EXPECT}_STR*(). // // 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to // {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you // what the actual value is when it fails, and similarly for the // other comparisons. // // 4. Do not depend on the order in which {ASSERT|EXPECT}_??() // evaluate their arguments, which is undefined. // // 5. These macros evaluate their arguments exactly once. // // Examples: // // EXPECT_NE(5, Foo()); // EXPECT_EQ(NULL, a_pointer); // ASSERT_LT(i, array_size); // ASSERT_GT(records.size(), 0) << "There is no record left."; #define EXPECT_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define EXPECT_NE(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) #define EXPECT_LE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define EXPECT_LT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define EXPECT_GE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define EXPECT_GT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) #define GTEST_ASSERT_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define GTEST_ASSERT_NE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) #define GTEST_ASSERT_LE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define GTEST_ASSERT_LT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define GTEST_ASSERT_GE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define GTEST_ASSERT_GT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) // Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of // ASSERT_XY(), which clashes with some users' own code. #if !GTEST_DONT_DEFINE_ASSERT_EQ # define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_NE # define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LE # define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LT # define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GE # define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GT # define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) #endif // C-string Comparisons. All tests treat NULL and any non-NULL string // as different. Two NULLs are equal. // // * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 // * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 // * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case // * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case // // For wide or narrow string objects, you can use the // {ASSERT|EXPECT}_??() macros. // // Don't depend on the order in which the arguments are evaluated, // which is undefined. // // These macros evaluate their arguments exactly once. #define EXPECT_STREQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define EXPECT_STRNE(s1, s2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define EXPECT_STRCASEEQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define EXPECT_STRCASENE(s1, s2)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) #define ASSERT_STREQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define ASSERT_STRNE(s1, s2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define ASSERT_STRCASEEQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define ASSERT_STRCASENE(s1, s2)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) // Macros for comparing floating-point numbers. // // * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): // Tests that two float values are almost equal. // * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): // Tests that two double values are almost equal. // * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): // Tests that v1 and v2 are within the given distance to each other. // // Google Test uses ULP-based comparison to automatically pick a default // error bound that is appropriate for the operands. See the // FloatingPoint template class in gtest-internal.h if you are // interested in the implementation details. #define EXPECT_FLOAT_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_DOUBLE_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_FLOAT_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_DOUBLE_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_NEAR(val1, val2, abs_error)\ EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) #define ASSERT_NEAR(val1, val2, abs_error)\ ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) // These predicate format functions work on floating-point values, and // can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. // // EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2); GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2); #if GTEST_OS_WINDOWS // Macros that test for HRESULT failure and success, these are only useful // on Windows, and rely on Windows SDK macros and APIs to compile. // // * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) // // When expr unexpectedly fails or succeeds, Google Test prints the // expected result and the actual result with both a human-readable // string representation of the error, if available, as well as the // hex result code. # define EXPECT_HRESULT_SUCCEEDED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define ASSERT_HRESULT_SUCCEEDED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define EXPECT_HRESULT_FAILED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) # define ASSERT_HRESULT_FAILED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) #endif // GTEST_OS_WINDOWS // Macros that execute statement and check that it doesn't generate new fatal // failures in the current thread. // // * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); // // Examples: // // EXPECT_NO_FATAL_FAILURE(Process()); // ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; // #define ASSERT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) #define EXPECT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) // Causes a trace (including the source file path, the current line // number, and the given message) to be included in every test failure // message generated by code in the current scope. The effect is // undone when the control leaves the current scope. // // The message argument can be anything streamable to std::ostream. // // In the implementation, we include the current line number as part // of the dummy variable name, thus allowing multiple SCOPED_TRACE()s // to appear in the same block - as long as they are on different // lines. #define SCOPED_TRACE(message) \ ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ __FILE__, __LINE__, ::testing::Message() << (message)) // Compile-time assertion for type equality. // StaticAssertTypeEq() compiles iff type1 and type2 are // the same type. The value it returns is not interesting. // // Instead of making StaticAssertTypeEq a class template, we make it a // function template that invokes a helper class template. This // prevents a user from misusing StaticAssertTypeEq by // defining objects of that type. // // CAVEAT: // // When used inside a method of a class template, // StaticAssertTypeEq() is effective ONLY IF the method is // instantiated. For example, given: // // template class Foo { // public: // void Bar() { testing::StaticAssertTypeEq(); } // }; // // the code: // // void Test1() { Foo foo; } // // will NOT generate a compiler error, as Foo::Bar() is never // actually instantiated. Instead, you need: // // void Test2() { Foo foo; foo.Bar(); } // // to cause a compiler error. template bool StaticAssertTypeEq() { (void)internal::StaticAssertTypeEqHelper(); return true; } // Defines a test. // // The first parameter is the name of the test case, and the second // parameter is the name of the test within the test case. // // The convention is to end the test case name with "Test". For // example, a test case for the Foo class can be named FooTest. // // The user should put his test code between braces after using this // macro. Example: // // TEST(FooTest, InitializesCorrectly) { // Foo foo; // EXPECT_TRUE(foo.StatusIsOK()); // } // Note that we call GetTestTypeId() instead of GetTypeId< // ::testing::Test>() here to get the type ID of testing::Test. This // is to work around a suspected linker bug when using Google Test as // a framework on Mac OS X. The bug causes GetTypeId< // ::testing::Test>() to return different values depending on whether // the call is from the Google Test framework itself or from user test // code. GetTestTypeId() is guaranteed to always return the same // value, as it always calls GetTypeId<>() from the Google Test // framework. #define GTEST_TEST(test_case_name, test_name)\ GTEST_TEST_(test_case_name, test_name, \ ::testing::Test, ::testing::internal::GetTestTypeId()) // Define this macro to 1 to omit the definition of TEST(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_TEST # define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) #endif // Defines a test that uses a test fixture. // // The first parameter is the name of the test fixture class, which // also doubles as the test case name. The second parameter is the // name of the test within the test case. // // A test fixture class must be declared earlier. The user should put // his test code between braces after using this macro. Example: // // class FooTest : public testing::Test { // protected: // virtual void SetUp() { b_.AddElement(3); } // // Foo a_; // Foo b_; // }; // // TEST_F(FooTest, InitializesCorrectly) { // EXPECT_TRUE(a_.StatusIsOK()); // } // // TEST_F(FooTest, ReturnsElementCountCorrectly) { // EXPECT_EQ(0, a_.size()); // EXPECT_EQ(1, b_.size()); // } #define TEST_F(test_fixture, test_name)\ GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId()) } // namespace testing // Use this function in main() to run all tests. It returns 0 if all // tests are successful, or 1 otherwise. // // RUN_ALL_TESTS() should be invoked after the command line has been // parsed by InitGoogleTest(). // // This function was formerly a macro; thus, it is in the global // namespace and has an all-caps name. int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } #endif // GTEST_INCLUDE_GTEST_GTEST_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest-typed-test.h0000664000175000017500000002400214750344764020027 // Copyright 2008 Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ // This header implements typed tests and type-parameterized tests. // Typed (aka type-driven) tests repeat the same test for types in a // list. You must know which types you want to test with when writing // typed tests. Here's how you do it: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { public: ... typedef std::list List; static T shared_; T value_; }; // Next, associate a list of types with the test case, which will be // repeated for each type in the list. The typedef is necessary for // the macro to parse correctly. typedef testing::Types MyTypes; TYPED_TEST_CASE(FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // TYPED_TEST_CASE(FooTest, int); // Then, use TYPED_TEST() instead of TEST_F() to define as many typed // tests for this test case as you want. TYPED_TEST(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. // Since we are inside a derived class template, C++ requires use to // visit the members of FooTest via 'this'. TypeParam n = this->value_; // To visit static members of the fixture, add the TestFixture:: // prefix. n += TestFixture::shared_; // To refer to typedefs in the fixture, add the "typename // TestFixture::" prefix. typename TestFixture::List values; values.push_back(n); ... } TYPED_TEST(FooTest, HasPropertyA) { ... } #endif // 0 // Type-parameterized tests are abstract test patterns parameterized // by a type. Compared with typed tests, type-parameterized tests // allow you to define the test pattern without knowing what the type // parameters are. The defined pattern can be instantiated with // different types any number of times, in any number of translation // units. // // If you are designing an interface or concept, you can define a // suite of type-parameterized tests to verify properties that any // valid implementation of the interface/concept should have. Then, // each implementation can easily instantiate the test suite to verify // that it conforms to the requirements, without having to write // similar tests repeatedly. Here's an example: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { ... }; // Next, declare that you will define a type-parameterized test case // (the _P suffix is for "parameterized" or "pattern", whichever you // prefer): TYPED_TEST_CASE_P(FooTest); // Then, use TYPED_TEST_P() to define as many type-parameterized tests // for this type-parameterized test case as you want. TYPED_TEST_P(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. TypeParam n = 0; ... } TYPED_TEST_P(FooTest, HasPropertyA) { ... } // Now the tricky part: you need to register all test patterns before // you can instantiate them. The first argument of the macro is the // test case name; the rest are the names of the tests in this test // case. REGISTER_TYPED_TEST_CASE_P(FooTest, DoesBlah, HasPropertyA); // Finally, you are free to instantiate the pattern with the types you // want. If you put the above code in a header file, you can #include // it in multiple C++ source files and instantiate it multiple times. // // To distinguish different instances of the pattern, the first // argument to the INSTANTIATE_* macro is a prefix that will be added // to the actual test case name. Remember to pick unique prefixes for // different instances. typedef testing::Types MyTypes; INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); #endif // 0 #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-type-util.h" // Implements typed tests. #if GTEST_HAS_TYPED_TEST // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the typedef for the type parameters of the // given test case. # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define TYPED_TEST_CASE(CaseName, Types) \ typedef ::testing::internal::TypeList< Types >::type \ GTEST_TYPE_PARAMS_(CaseName) # define TYPED_TEST(CaseName, TestName) \ template \ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTest< \ CaseName, \ ::testing::internal::TemplateSel< \ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ GTEST_TYPE_PARAMS_(CaseName)>::Register(\ "", #CaseName, #TestName, 0); \ template \ void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() #endif // GTEST_HAS_TYPED_TEST // Implements type-parameterized tests. #if GTEST_HAS_TYPED_TEST_P // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the namespace name that the type-parameterized tests for // the given type-parameterized test case are defined in. The exact // name of the namespace is subject to change without notice. # define GTEST_CASE_NAMESPACE_(TestCaseName) \ gtest_case_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the variable used to remember the names of // the defined tests in the given test case. # define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ gtest_typed_test_case_p_state_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. // // Expands to the name of the variable used to remember the names of // the registered tests in the given test case. # define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ gtest_registered_test_names_##TestCaseName##_ // The variables defined in the type-parameterized test macros are // static as typically these macros are used in a .h file that can be // #included in multiple translation units linked together. # define TYPED_TEST_CASE_P(CaseName) \ static ::testing::internal::TypedTestCasePState \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) # define TYPED_TEST_P(CaseName, TestName) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ template \ class TestName : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ __FILE__, __LINE__, #CaseName, #TestName); \ } \ template \ void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() # define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ } \ static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ __FILE__, __LINE__, #__VA_ARGS__) // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTestCase::type>::Register(\ #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest-param-test.h.pump0000664000175000017500000004455414750344764021000 $$ -*- mode: c++; -*- $var n = 50 $$ Maximum length of Values arguments we want to support. $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Authors: vladl@google.com (Vlad Losev) // // Macros and functions for implementing parameterized tests // in Google C++ Testing Framework (Google Test) // // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // // Here is how you use value-parameterized tests: #if 0 // To write value-parameterized tests, first you should define a fixture // class. It is usually derived from testing::TestWithParam (see below for // another inheritance scheme that's sometimes useful in more complicated // class hierarchies), where the type of your parameter values. // TestWithParam is itself derived from testing::Test. T can be any // copyable type. If it's a raw pointer, you are responsible for managing the // lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. }; // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" // or "pattern", whichever you prefer to think. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method // of the TestWithParam class: EXPECT_TRUE(foo.Blah(GetParam())); ... } TEST_P(FooTest, HasBlahBlah) { ... } // Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test // case with any set of parameters you want. Google Test defines a number // of functions for generating test parameters. They return what we call // (surprise!) parameter generators. Here is a summary of them, which // are all in the testing namespace: // // // Range(begin, end [, step]) - Yields values {begin, begin+step, // begin+step+step, ...}. The values do not // include end. step defaults to 1. // Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. // ValuesIn(container) - Yields values from a C-style array, an STL // ValuesIn(begin,end) container, or an iterator range [begin, end). // Bool() - Yields sequence {false, true}. // Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product // for the math savvy) of the values generated // by the N generators. // // For more details, see comments at the definitions of these functions below // in this file. // // The following statement will instantiate tests from the FooTest test case // each with parameter values "meeny", "miny", and "moe". INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest, Values("meeny", "miny", "moe")); // To distinguish different instances of the pattern, (yes, you // can instantiate it more then once) the first argument to the // INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the // actual test case name. Remember to pick unique prefixes for different // instantiations. The tests from the instantiation above will have // these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" // * InstantiationName/FooTest.DoesBlah/2 for "moe" // * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" // * InstantiationName/FooTest.HasBlahBlah/1 for "miny" // * InstantiationName/FooTest.HasBlahBlah/2 for "moe" // // You can use these names in --gtest_filter. // // This statement will instantiate all tests from FooTest again, each // with parameter values "cat" and "dog": const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // The tests from the instantiation above will have these names: // // * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" // * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" // * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" // * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" // // Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // // Please also note that generator expressions (including parameters to the // generators) are evaluated in InitGoogleTest(), after main() has started. // This allows the user on one hand, to adjust generator parameters in order // to dynamically determine a set of tests to run and on the other hand, // give the user a chance to inspect the generated tests with Google Test // reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. // // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. // // // A parameterized test fixture must be derived from testing::Test and from // testing::WithParamInterface, where T is the type of the parameter // values. Inheriting from TestWithParam satisfies that requirement because // TestWithParam inherits from both Test and WithParamInterface. In more // complicated hierarchies, however, it is occasionally useful to inherit // separately from Test and WithParamInterface. For example: class BaseTest : public ::testing::Test { // You can inherit all the usual members for a non-parameterized test // fixture here. }; class DerivedTest : public BaseTest, public ::testing::WithParamInterface { // The usual test fixture members go here too. }; TEST_F(BaseTest, HasFoo) { // This is an ordinary non-parameterized test. } TEST_P(DerivedTest, DoesBlah) { // GetParam works just the same here as if you inherit from TestWithParam. EXPECT_TRUE(foo.Blah(GetParam())); } #endif // 0 #include "gtest/internal/gtest-port.h" #if !GTEST_OS_SYMBIAN # include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-param-util-generated.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- // parameterized tests. When a parameterized test case is instantiated // with a particular generator, Google Test creates and runs tests // for each element in the sequence produced by the generator. // // In the following sample, tests from test case FooTest are instantiated // each three times with parameter values 3, 5, and 8: // // class FooTest : public TestWithParam { ... }; // // TEST_P(FooTest, TestThis) { // } // TEST_P(FooTest, TestThat) { // } // INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); // // Range() returns generators providing sequences of values in a range. // // Synopsis: // Range(start, end) // - returns a generator producing a sequence of values {start, start+1, // start+2, ..., }. // Range(start, end, step) // - returns a generator producing a sequence of values {start, start+step, // start+step+step, ..., }. // Notes: // * The generated sequences never include end. For example, Range(1, 5) // returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) // returns a generator producing {1, 3, 5, 7}. // * start and end must have the same type. That type may be any integral or // floating-point type or a user defined type satisfying these conditions: // * It must be assignable (have operator=() defined). // * It must have operator+() (operator+(int-compatible type) for // two-operand version). // * It must have operator<() defined. // Elements in the resulting sequences will also have that type. // * Condition start < end must be satisfied in order for resulting sequences // to contain any elements. // template internal::ParamGenerator Range(T start, T end, IncrementT step) { return internal::ParamGenerator( new internal::RangeGenerator(start, end, step)); } template internal::ParamGenerator Range(T start, T end) { return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from // a container. // // Synopsis: // ValuesIn(const T (&array)[N]) // - returns a generator producing sequences with elements from // a C-style array. // ValuesIn(const Container& container) // - returns a generator producing sequences with elements from // an STL-style container. // ValuesIn(Iterator begin, Iterator end) // - returns a generator producing sequences with elements from // a range [begin, end) defined by a pair of STL-style iterators. These // iterators can also be plain C pointers. // // Please note that ValuesIn copies the values from the containers // passed in and keeps them to generate tests in RUN_ALL_TESTS(). // // Examples: // // This instantiates tests from test case StringTest // each with C-string values of "foo", "bar", and "baz": // // const char* strings[] = {"foo", "bar", "baz"}; // INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); // // This instantiates tests from test case StlStringTest // each with STL strings with values "a" and "b": // // ::std::vector< ::std::string> GetParameterStrings() { // ::std::vector< ::std::string> v; // v.push_back("a"); // v.push_back("b"); // return v; // } // // INSTANTIATE_TEST_CASE_P(CharSequence, // StlStringTest, // ValuesIn(GetParameterStrings())); // // // This will also instantiate tests from CharTest // each with parameter values 'a' and 'b': // // ::std::list GetParameterChars() { // ::std::list list; // list.push_back('a'); // list.push_back('b'); // return list; // } // ::std::list l = GetParameterChars(); // INSTANTIATE_TEST_CASE_P(CharSequence2, // CharTest, // ValuesIn(l.begin(), l.end())); // template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end) { typedef typename ::testing::internal::IteratorTraits ::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } template internal::ParamGenerator ValuesIn(const T (&array)[N]) { return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( const Container& container) { return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of // parameters. // // Synopsis: // Values(T v1, T v2, ..., T vN) // - returns a generator producing sequences with elements v1, v2, ..., vN. // // For example, this instantiates tests from test case BarTest each // with values "one", "two", and "three": // // INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); // // This instantiates tests from test case BazTest each with values 1, 2, 3.5. // The exact type of values will depend on the type of parameter in BazTest. // // INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); // // Currently, Values() supports from 1 to $n parameters. // $range i 1..n $for i [[ $range j 1..i template <$for j, [[typename T$j]]> internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) { return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]); } ]] // Bool() allows generating tests with parameters in a set of (false, true). // // Synopsis: // Bool() // - returns a generator producing sequences with elements {false, true}. // // It is useful when testing code that depends on Boolean flags. Combinations // of multiple flags can be tested when several Bool()'s are combined using // Combine() function. // // In the following example all tests in the test case FlagDependentTest // will be instantiated twice with parameters false and true. // // class FlagDependentTest : public testing::TestWithParam { // virtual void SetUp() { // external_flag = GetParam(); // } // } // INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); // inline internal::ParamGenerator Bool() { return Values(false, true); } # if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // // Synopsis: // Combine(gen1, gen2, ..., genN) // - returns a generator producing sequences with elements coming from // the Cartesian product of elements from the sequences generated by // gen1, gen2, ..., genN. The sequence elements will have a type of // tuple where T1, T2, ..., TN are the types // of elements from sequences produces by gen1, gen2, ..., genN. // // Combine can have up to $maxtuple arguments. This number is currently limited // by the maximum number of elements in the tuple implementation used by Google // Test. // // Example: // // This will instantiate tests in test case AnimalTest each one with // the parameter values tuple("cat", BLACK), tuple("cat", WHITE), // tuple("dog", BLACK), and tuple("dog", WHITE): // // enum Color { BLACK, GRAY, WHITE }; // class AnimalTest // : public testing::TestWithParam > {...}; // // TEST_P(AnimalTest, AnimalLooksNice) {...} // // INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, // Combine(Values("cat", "dog"), // Values(BLACK, WHITE))); // // This will instantiate tests in FlagDependentTest with all variations of two // Boolean flags: // // class FlagDependentTest // : public testing::TestWithParam > { // virtual void SetUp() { // // Assigns external_flag_1 and external_flag_2 values from the tuple. // tie(external_flag_1, external_flag_2) = GetParam(); // } // }; // // TEST_P(FlagDependentTest, TestFeature1) { // // Test your code using external_flag_1 and external_flag_2 here. // } // INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, // Combine(Bool(), Bool())); // $range i 2..maxtuple $for i [[ $range j 1..i template <$for j, [[typename Generator$j]]> internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( $for j, [[const Generator$j& g$j]]) { return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>( $for j, [[g$j]]); } ]] # endif // GTEST_HAS_COMBINE # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ public: \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ virtual void TestBody(); \ private: \ static int AddToRegistry() { \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \ #test_name, \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ return 0; \ } \ static int gtest_registering_dummy_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ int GTEST_TEST_CLASS_NAME_(test_case_name, \ test_name)::gtest_registering_dummy_ = \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() # define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ ::testing::internal::ParamGenerator \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ int gtest_##prefix##test_case_name##_dummy_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #prefix, \ >est_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__) } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest_prod.h0000664000175000017500000000442414750344764016761 // Copyright 2006, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // // Google C++ Testing Framework definitions useful in production code. #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ // When you need to test the private or protected members of a class, // use the FRIEND_TEST macro to declare your tests as friends of the // class. For example: // // class MyClass { // private: // void MyMethod(); // FRIEND_TEST(MyClassTest, MyMethod); // }; // // class MyClassTest : public testing::Test { // // ... // }; // // TEST_F(MyClassTest, MyMethod) { // // Can call MyClass::MyMethod() here. // } #define FRIEND_TEST(test_case_name, test_name)\ friend class test_case_name##_##test_name##_Test #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest-spi.h0000664000175000017500000002334014750344764016524 // Copyright 2007, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // // Utilities for testing Google Test itself and code that uses Google Test // (e.g. frameworks built on top of Google Test). #ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #include "gtest/gtest.h" namespace testing { // This helper class can be used to mock out Google Test failure reporting // so that we can test Google Test or code that builds on Google Test. // // An object of this class appends a TestPartResult object to the // TestPartResultArray object given in the constructor whenever a Google Test // failure is reported. It can either intercept only failures that are // generated in the same thread that created this object or it can intercept // all generated failures. The scope of this mock object can be controlled with // the second argument to the two arguments constructor. class GTEST_API_ ScopedFakeTestPartResultReporter : public TestPartResultReporterInterface { public: // The two possible mocking modes of this object. enum InterceptMode { INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. INTERCEPT_ALL_THREADS // Intercepts all failures. }; // The c'tor sets this object as the test part result reporter used // by Google Test. The 'result' parameter specifies where to report the // results. This reporter will only catch failures generated in the current // thread. DEPRECATED explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); // Same as above, but you can choose the interception scope of this object. ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, TestPartResultArray* result); // The d'tor restores the previous test part result reporter. virtual ~ScopedFakeTestPartResultReporter(); // Appends the TestPartResult object to the TestPartResultArray // received in the constructor. // // This method is from the TestPartResultReporterInterface // interface. virtual void ReportTestPartResult(const TestPartResult& result); private: void Init(); const InterceptMode intercept_mode_; TestPartResultReporterInterface* old_reporter_; TestPartResultArray* const result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); }; namespace internal { // A helper class for implementing EXPECT_FATAL_FAILURE() and // EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. class GTEST_API_ SingleFailureChecker { public: // The constructor remembers the arguments. SingleFailureChecker(const TestPartResultArray* results, TestPartResult::Type type, const string& substr); ~SingleFailureChecker(); private: const TestPartResultArray* const results_; const TestPartResult::Type type_; const string substr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); }; } // namespace internal } // namespace testing // A set of macros for testing Google Test assertions or code that's expected // to generate Google Test fatal failures. It verifies that the given // statement will cause exactly one fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_FATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - 'statement' cannot reference local non-static variables or // non-static members of the current object. // - 'statement' cannot return a value. // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. The AcceptsMacroThatExpandsToUnprotectedComma test in // gtest_unittest.cc will fail to compile if we do that. #define EXPECT_FATAL_FAILURE(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ALL_THREADS, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to // generate Google Test non-fatal failures. It asserts that the given // statement will cause exactly one non-fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // 'statement' is allowed to reference local variables and members of // the current object. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. If we do that, the code won't compile when the user gives // EXPECT_NONFATAL_FAILURE() a statement that contains a macro that // expands to code containing an unprotected comma. The // AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc // catches that. // // For the same reason, we have to write // if (::testing::internal::AlwaysTrue()) { statement; } // instead of // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) // to avoid an MSVC warning on unreachable code. #define EXPECT_NONFATAL_FAILURE(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest-printers.h0000664000175000017500000007557114750344764017614 // Copyright 2007, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // A user can teach this function how to print a class type T by // defining either operator<<() or PrintTo() in the namespace that // defines T. More specifically, the FIRST defined function in the // following list will be used (assuming T is defined in namespace // foo): // // 1. foo::PrintTo(const T&, ostream*) // 2. operator<<(ostream&, const T&) defined in either foo or the // global namespace. // // If none of the above is defined, it will print the debug string of // the value if it is a protocol buffer, or print the raw bytes in the // value otherwise. // // To aid debugging: when T is a reference type, the address of the // value is also printed; when T is a (const) char pointer, both the // pointer value and the NUL-terminated string it points to are // printed. // // We also provide some convenient wrappers: // // // Prints a value to a string. For a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // std::string ::testing::PrintToString(const T& value); // // // Prints a value tersely: for a reference type, the referenced // // value (but not the address) is printed; for a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // void ::testing::internal::UniversalTersePrint(const T& value, ostream*); // // // Prints value using the type inferred by the compiler. The difference // // from UniversalTersePrint() is that this function prints both the // // pointer and the NUL-terminated string for a (const or not) char pointer. // void ::testing::internal::UniversalPrint(const T& value, ostream*); // // // Prints the fields of a tuple tersely to a string vector, one // // element for each field. Tuple support must be enabled in // // gtest-port.h. // std::vector UniversalTersePrintTupleFieldsToStrings( // const Tuple& value); // // Known limitation: // // The print primitives print the elements of an STL-style container // using the compiler-inferred type of *iter where iter is a // const_iterator of the container. When const_iterator is an input // iterator but not a forward iterator, this inferred type may not // match value_type, and the print output may be incorrect. In // practice, this is rarely a problem as for most containers // const_iterator is a forward iterator. We'll fix this if there's an // actual need for it. Note that this fix cannot rely on value_type // being defined as many user-defined container types don't have // value_type. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #include // NOLINT #include #include #include #include #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-internal.h" namespace testing { // Definitions in the 'internal' and 'internal2' name spaces are // subject to change without notice. DO NOT USE THEM IN USER CODE! namespace internal2 { // Prints the given number of bytes in the given object to the given // ostream. GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ::std::ostream* os); // For selecting which printer to use when a given type has neither << // nor PrintTo(). enum TypeKind { kProtobuf, // a protobuf type kConvertibleToInteger, // a type implicitly convertible to BiggestInt // (e.g. a named or unnamed enum type) kOtherType // anything else }; // TypeWithoutFormatter::PrintValue(value, os) is called // by the universal printer to print a value of type T when neither // operator<< nor PrintTo() is defined for T, where kTypeKind is the // "kind" of T as defined by enum TypeKind. template class TypeWithoutFormatter { public: // This default version is called when kTypeKind is kOtherType. static void PrintValue(const T& value, ::std::ostream* os) { PrintBytesInObjectTo(reinterpret_cast(&value), sizeof(value), os); } }; // We print a protobuf using its ShortDebugString() when the string // doesn't exceed this many characters; otherwise we print it using // DebugString() for better readability. const size_t kProtobufOneLinerMaxLength = 50; template class TypeWithoutFormatter { public: static void PrintValue(const T& value, ::std::ostream* os) { const ::testing::internal::string short_str = value.ShortDebugString(); const ::testing::internal::string pretty_str = short_str.length() <= kProtobufOneLinerMaxLength ? short_str : ("\n" + value.DebugString()); *os << ("<" + pretty_str + ">"); } }; template class TypeWithoutFormatter { public: // Since T has no << operator or PrintTo() but can be implicitly // converted to BiggestInt, we print it as a BiggestInt. // // Most likely T is an enum type (either named or unnamed), in which // case printing it as an integer is the desired behavior. In case // T is not an enum, printing it as an integer is the best we can do // given that it has no user-defined printer. static void PrintValue(const T& value, ::std::ostream* os) { const internal::BiggestInt kBigInt = value; *os << kBigInt; } }; // Prints the given value to the given ostream. If the value is a // protocol message, its debug string is printed; if it's an enum or // of a type implicitly convertible to BiggestInt, it's printed as an // integer; otherwise the bytes in the value are printed. This is // what UniversalPrinter::Print() does when it knows nothing about // type T and T has neither << operator nor PrintTo(). // // A user can override this behavior for a class type Foo by defining // a << operator in the namespace where Foo is defined. // // We put this operator in namespace 'internal2' instead of 'internal' // to simplify the implementation, as much code in 'internal' needs to // use << in STL, which would conflict with our own << were it defined // in 'internal'. // // Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If // we define it to take an std::ostream instead, we'll get an // "ambiguous overloads" compiler error when trying to print a type // Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether // operator<<(std::ostream&, const T&) or // operator<<(std::basic_stream, const Foo&) is more // specific. template ::std::basic_ostream& operator<<( ::std::basic_ostream& os, const T& x) { TypeWithoutFormatter::value ? kProtobuf : internal::ImplicitlyConvertible::value ? kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); return os; } } // namespace internal2 } // namespace testing // This namespace MUST NOT BE NESTED IN ::testing, or the name look-up // magic needed for implementing UniversalPrinter won't work. namespace testing_internal { // Used to print a value that is not an STL-style container when the // user doesn't define PrintTo() for it. template void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { // With the following statement, during unqualified name lookup, // testing::internal2::operator<< appears as if it was declared in // the nearest enclosing namespace that contains both // ::testing_internal and ::testing::internal2, i.e. the global // namespace. For more details, refer to the C++ Standard section // 7.3.4-1 [namespace.udir]. This allows us to fall back onto // testing::internal2::operator<< in case T doesn't come with a << // operator. // // We cannot write 'using ::testing::internal2::operator<<;', which // gcc 3.3 fails to compile due to a compiler bug. using namespace ::testing::internal2; // NOLINT // Assuming T is defined in namespace foo, in the next statement, // the compiler will consider all of: // // 1. foo::operator<< (thanks to Koenig look-up), // 2. ::operator<< (as the current namespace is enclosed in ::), // 3. testing::internal2::operator<< (thanks to the using statement above). // // The operator<< whose type matches T best will be picked. // // We deliberately allow #2 to be a candidate, as sometimes it's // impossible to define #1 (e.g. when foo is ::std, defining // anything in it is undefined behavior unless you are a compiler // vendor.). *os << value; } } // namespace testing_internal namespace testing { namespace internal { // UniversalPrinter::Print(value, ostream_ptr) prints the given // value to the given ostream. The caller must ensure that // 'ostream_ptr' is not NULL, or the behavior is undefined. // // We define UniversalPrinter as a class template (as opposed to a // function template), as we need to partially specialize it for // reference types, which cannot be done with function templates. template class UniversalPrinter; template void UniversalPrint(const T& value, ::std::ostream* os); // Used to print an STL-style container when the user doesn't define // a PrintTo() for it. template void DefaultPrintTo(IsContainer /* dummy */, false_type /* is not a pointer */, const C& container, ::std::ostream* os) { const size_t kMaxCount = 32; // The maximum number of elements to print. *os << '{'; size_t count = 0; for (typename C::const_iterator it = container.begin(); it != container.end(); ++it, ++count) { if (count > 0) { *os << ','; if (count == kMaxCount) { // Enough has been printed. *os << " ..."; break; } } *os << ' '; // We cannot call PrintTo(*it, os) here as PrintTo() doesn't // handle *it being a native array. internal::UniversalPrint(*it, os); } if (count > 0) { *os << ' '; } *os << '}'; } // Used to print a pointer that is neither a char pointer nor a member // pointer, when the user doesn't define PrintTo() for it. (A member // variable pointer or member function pointer doesn't really point to // a location in the address space. Their representation is // implementation-defined. Therefore they will be printed as raw // bytes.) template void DefaultPrintTo(IsNotContainer /* dummy */, true_type /* is a pointer */, T* p, ::std::ostream* os) { if (p == NULL) { *os << "NULL"; } else { // C++ doesn't allow casting from a function pointer to any object // pointer. // // IsTrue() silences warnings: "Condition is always true", // "unreachable code". if (IsTrue(ImplicitlyConvertible::value)) { // T is not a function type. We just call << to print p, // relying on ADL to pick up user-defined << for their pointer // types, if any. *os << p; } else { // T is a function type, so '*os << p' doesn't do what we want // (it just prints p as bool). We want to print p as a const // void*. However, we cannot cast it to const void* directly, // even using reinterpret_cast, as earlier versions of gcc // (e.g. 3.4.5) cannot compile the cast when p is a function // pointer. Casting to UInt64 first solves the problem. *os << reinterpret_cast( reinterpret_cast(p)); } } } // Used to print a non-container, non-pointer value when the user // doesn't define PrintTo() for it. template void DefaultPrintTo(IsNotContainer /* dummy */, false_type /* is not a pointer */, const T& value, ::std::ostream* os) { ::testing_internal::DefaultPrintNonContainerTo(value, os); } // Prints the given value using the << operator if it has one; // otherwise prints the bytes in it. This is what // UniversalPrinter::Print() does when PrintTo() is not specialized // or overloaded for type T. // // A user can override this behavior for a class type Foo by defining // an overload of PrintTo() in the namespace where Foo is defined. We // give the user this option as sometimes defining a << operator for // Foo is not desirable (e.g. the coding style may prevent doing it, // or there is already a << operator but it doesn't do what the user // wants). template void PrintTo(const T& value, ::std::ostream* os) { // DefaultPrintTo() is overloaded. The type of its first two // arguments determine which version will be picked. If T is an // STL-style container, the version for container will be called; if // T is a pointer, the pointer version will be called; otherwise the // generic version will be called. // // Note that we check for container types here, prior to we check // for protocol message types in our operator<<. The rationale is: // // For protocol messages, we want to give people a chance to // override Google Mock's format by defining a PrintTo() or // operator<<. For STL containers, other formats can be // incompatible with Google Mock's format for the container // elements; therefore we check for container types here to ensure // that our format is used. // // The second argument of DefaultPrintTo() is needed to bypass a bug // in Symbian's C++ compiler that prevents it from picking the right // overload between: // // PrintTo(const T& x, ...); // PrintTo(T* x, ...); DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); } // The following list of PrintTo() overloads tells // UniversalPrinter::Print() how to print standard types (built-in // types, strings, plain arrays, and pointers). // Overloads for various char types. GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); inline void PrintTo(char c, ::std::ostream* os) { // When printing a plain char, we always treat it as unsigned. This // way, the output won't be affected by whether the compiler thinks // char is signed or not. PrintTo(static_cast(c), os); } // Overloads for other simple built-in types. inline void PrintTo(bool x, ::std::ostream* os) { *os << (x ? "true" : "false"); } // Overload for wchar_t type. // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its decimal code (except for L'\0'). // The L'\0' char is printed as "L'\\0'". The decimal code is printed // as signed integer when wchar_t is implemented by the compiler // as a signed type and is printed as an unsigned integer when wchar_t // is implemented as an unsigned type. GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); // Overloads for C strings. GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); inline void PrintTo(char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // signed/unsigned char is often used for representing binary data, so // we print pointers to it as void* to be safe. inline void PrintTo(const signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(const unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // MSVC can be configured to define wchar_t as a typedef of unsigned // short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native // type. When wchar_t is a typedef, defining an overload for const // wchar_t* would cause unsigned short* be printed as a wide string, // possibly causing invalid memory accesses. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Overloads for wide C strings GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); inline void PrintTo(wchar_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } #endif // Overload for C arrays. Multi-dimensional arrays are printed // properly. // Prints the given number of elements in an array, without printing // the curly braces. template void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { UniversalPrint(a[0], os); for (size_t i = 1; i != count; i++) { *os << ", "; UniversalPrint(a[i], os); } } // Overloads for ::string and ::std::string. #if GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); inline void PrintTo(const ::string& s, ::std::ostream* os) { PrintStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); inline void PrintTo(const ::std::string& s, ::std::ostream* os) { PrintStringTo(s, os); } // Overloads for ::wstring and ::std::wstring. #if GTEST_HAS_GLOBAL_WSTRING GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); inline void PrintTo(const ::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_TR1_TUPLE // Overload for ::std::tr1::tuple. Needed for printing function arguments, // which are packed as tuples. // Helper function for printing a tuple. T must be instantiated with // a tuple type. template void PrintTupleTo(const T& t, ::std::ostream* os); // Overloaded PrintTo() for tuples of various arities. We support // tuples of up-to 10 fields. The following implementation works // regardless of whether tr1::tuple is implemented using the // non-standard variadic template feature or not. inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo( const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } #endif // GTEST_HAS_TR1_TUPLE // Overload for std::pair. template void PrintTo(const ::std::pair& value, ::std::ostream* os) { *os << '('; // We cannot use UniversalPrint(value.first, os) here, as T1 may be // a reference type. The same for printing value.second. UniversalPrinter::Print(value.first, os); *os << ", "; UniversalPrinter::Print(value.second, os); *os << ')'; } // Implements printing a non-reference type T by letting the compiler // pick the right overload of PrintTo() for T. template class UniversalPrinter { public: // MSVC warns about adding const to a function type, so we want to // disable the warning. #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4180) // Temporarily disables warning 4180. #endif // _MSC_VER // Note: we deliberately don't call this PrintTo(), as that name // conflicts with ::testing::internal::PrintTo in the body of the // function. static void Print(const T& value, ::std::ostream* os) { // By default, ::testing::internal::PrintTo() is used for printing // the value. // // Thanks to Koenig look-up, if T is a class and has its own // PrintTo() function defined in its namespace, that function will // be visible here. Since it is more specific than the generic ones // in ::testing::internal, it will be picked by the compiler in the // following statement - exactly what we want. PrintTo(value, os); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif // _MSC_VER }; // UniversalPrintArray(begin, len, os) prints an array of 'len' // elements, starting at address 'begin'. template void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { if (len == 0) { *os << "{}"; } else { *os << "{ "; const size_t kThreshold = 18; const size_t kChunkSize = 8; // If the array has more than kThreshold elements, we'll have to // omit some details by printing only the first and the last // kChunkSize elements. // TODO(wan@google.com): let the user control the threshold using a flag. if (len <= kThreshold) { PrintRawArrayTo(begin, len, os); } else { PrintRawArrayTo(begin, kChunkSize, os); *os << ", ..., "; PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); } *os << " }"; } } // This overload prints a (const) char array compactly. GTEST_API_ void UniversalPrintArray( const char* begin, size_t len, ::std::ostream* os); // This overload prints a (const) wchar_t array compactly. GTEST_API_ void UniversalPrintArray( const wchar_t* begin, size_t len, ::std::ostream* os); // Implements printing an array type T[N]. template class UniversalPrinter { public: // Prints the given array, omitting some elements when there are too // many. static void Print(const T (&a)[N], ::std::ostream* os) { UniversalPrintArray(a, N, os); } }; // Implements printing a reference type T&. template class UniversalPrinter { public: // MSVC warns about adding const to a function type, so we want to // disable the warning. #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4180) // Temporarily disables warning 4180. #endif // _MSC_VER static void Print(const T& value, ::std::ostream* os) { // Prints the address of the value. We use reinterpret_cast here // as static_cast doesn't compile when T is a function type. *os << "@" << reinterpret_cast(&value) << " "; // Then prints the value itself. UniversalPrint(value, os); } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif // _MSC_VER }; // Prints a value tersely: for a reference type, the referenced value // (but not the address) is printed; for a (const) char pointer, the // NUL-terminated string (but not the pointer) is printed. template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T (&value)[N], ::std::ostream* os) { UniversalPrinter::Print(value, os); } }; template <> class UniversalTersePrinter { public: static void Print(const char* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(string(str), os); } } }; template <> class UniversalTersePrinter { public: static void Print(char* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; #if GTEST_HAS_STD_WSTRING template <> class UniversalTersePrinter { public: static void Print(const wchar_t* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(::std::wstring(str), os); } } }; #endif template <> class UniversalTersePrinter { public: static void Print(wchar_t* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; template void UniversalTersePrint(const T& value, ::std::ostream* os) { UniversalTersePrinter::Print(value, os); } // Prints a value using the type inferred by the compiler. The // difference between this and UniversalTersePrint() is that for a // (const) char pointer, this prints both the pointer and the // NUL-terminated string. template void UniversalPrint(const T& value, ::std::ostream* os) { // A workarond for the bug in VC++ 7.1 that prevents us from instantiating // UniversalPrinter with T directly. typedef T T1; UniversalPrinter::Print(value, os); } #if GTEST_HAS_TR1_TUPLE typedef ::std::vector Strings; // This helper template allows PrintTo() for tuples and // UniversalTersePrintTupleFieldsToStrings() to be defined by // induction on the number of tuple fields. The idea is that // TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N // fields in tuple t, and can be defined in terms of // TuplePrefixPrinter. // The inductive case. template struct TuplePrefixPrinter { // Prints the first N fields of a tuple. template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { TuplePrefixPrinter::PrintPrefixTo(t, os); *os << ", "; UniversalPrinter::type> ::Print(::std::tr1::get(t), os); } // Tersely prints the first N fields of a tuple to a string vector, // one element for each field. template static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); ::std::stringstream ss; UniversalTersePrint(::std::tr1::get(t), &ss); strings->push_back(ss.str()); } }; // Base cases. template <> struct TuplePrefixPrinter<0> { template static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} template static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} }; // We have to specialize the entire TuplePrefixPrinter<> class // template here, even though the definition of // TersePrintPrefixToStrings() is the same as the generic version, as // Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't // support specializing a method template of a class template. template <> struct TuplePrefixPrinter<1> { template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { UniversalPrinter::type>:: Print(::std::tr1::get<0>(t), os); } template static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { ::std::stringstream ss; UniversalTersePrint(::std::tr1::get<0>(t), &ss); strings->push_back(ss.str()); } }; // Helper function for printing a tuple. T must be instantiated with // a tuple type. template void PrintTupleTo(const T& t, ::std::ostream* os) { *os << "("; TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: PrintPrefixTo(t, os); *os << ")"; } // Prints the fields of a tuple tersely to a string vector, one // element for each field. See the comment before // UniversalTersePrint() for how we define "tersely". template Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { Strings result; TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: TersePrintPrefixToStrings(value, &result); return result; } #endif // GTEST_HAS_TR1_TUPLE } // namespace internal template ::std::string PrintToString(const T& value) { ::std::stringstream ss; internal::UniversalTersePrinter::Print(value, &ss); return ss.str(); } } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ stimfit-0.16.7/src/test/gtest/include/gtest/gtest-death-test.h0000664000175000017500000002640314750344764017776 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for death tests. It is // #included by gtest.h so a user doesn't need to include this // directly. #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #include "gtest/internal/gtest-death-test-internal.h" namespace testing { // This flag controls the style of death tests. Valid values are "threadsafe", // meaning that the death test child process will re-execute the test binary // from the start, running only a single death test, or "fast", // meaning that the child process will execute the test logic immediately // after forking. GTEST_DECLARE_string_(death_test_style); #if GTEST_HAS_DEATH_TEST namespace internal { // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. GTEST_API_ bool InDeathTestChild(); } // namespace internal // The following macros are useful for writing death tests. // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is // executed: // // 1. It generates a warning if there is more than one active // thread. This is because it's safe to fork() or clone() only // when there is a single thread. // // 2. The parent process clone()s a sub-process and runs the death // test in it; the sub-process exits with code 0 at the end of the // death test, if it hasn't exited already. // // 3. The parent process waits for the sub-process to terminate. // // 4. The parent process checks the exit code and error message of // the sub-process. // // Examples: // // ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); // for (int i = 0; i < 5; i++) { // EXPECT_DEATH(server.ProcessRequest(i), // "Invalid request .* in ProcessRequest()") // << "Failed to die on request " << i; // } // // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); // // bool KilledBySIGHUP(int exit_code) { // return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; // } // // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // // On the regular expressions used in death tests: // // On POSIX-compliant systems (*nix), we use the library, // which uses the POSIX extended regex syntax. // // On other platforms (e.g. Windows), we only support a simple regex // syntax implemented as part of Google Test. This limited // implementation should be enough most of the time when writing // death tests; though it lacks many features you can find in PCRE // or POSIX extended regex syntax. For example, we don't support // union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and // repetition count ("x{5,7}"), among others. // // Below is the syntax that we do support. We chose it to be a // subset of both PCRE and POSIX extended regex, so it's easy to // learn wherever you come from. In the following: 'A' denotes a // literal character, period (.), or a single \\ escape sequence; // 'x' and 'y' denote regular expressions; 'm' and 'n' are for // natural numbers. // // c matches any literal character c // \\d matches any decimal digit // \\D matches any character that's not a decimal digit // \\f matches \f // \\n matches \n // \\r matches \r // \\s matches any ASCII whitespace, including \n // \\S matches any character that's not a whitespace // \\t matches \t // \\v matches \v // \\w matches any letter, _, or decimal digit // \\W matches any character that \\w doesn't match // \\c matches any literal character c, which must be a punctuation // . matches any single character except \n // A? matches 0 or 1 occurrences of A // A* matches 0 or many occurrences of A // A+ matches 1 or many occurrences of A // ^ matches the beginning of a string (not that of each line) // $ matches the end of a string (not that of each line) // xy matches x followed by y // // If you accidentally use PCRE or POSIX extended regex features // not implemented by us, you will get a run-time failure. In that // case, please try to rewrite your regular expression within the // above syntax. // // This implementation is *not* meant to be as highly tuned or robust // as a compiled regex library, but should perform well enough for a // death test, which already incurs significant overhead by launching // a child process. // // Known caveats: // // A "threadsafe" style death test obtains the path to the test // program from argv[0] and re-executes it in the sub-process. For // simplicity, the current implementation doesn't search the PATH // when launching the sub-process. This means that the user must // invoke the test program via a path that contains at least one // path separator (e.g. path/to/foo_test and // /absolute/path/to/bar_test are fine, but foo_test is not). This // is rarely a problem as people usually don't put the test binary // directory in PATH. // // TODO(wan@google.com): make thread-safe death tests search the PATH. // Asserts that a given statement causes the program to exit, with an // integer exit status that satisfies predicate, and emitting error output // that matches regex. # define ASSERT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) // Like ASSERT_EXIT, but continues on to successive tests in the // test case, if any: # define EXPECT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) // Asserts that a given statement causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches regex. # define ASSERT_DEATH(statement, regex) \ ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Like ASSERT_DEATH, but continues on to successive tests in the // test case, if any: # define EXPECT_DEATH(statement, regex) \ EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Tests that an exit code describes a normal exit with a given exit code. class GTEST_API_ ExitedWithCode { public: explicit ExitedWithCode(int exit_code); bool operator()(int exit_status) const; private: // No implementation - assignment is unsupported. void operator=(const ExitedWithCode& other); const int exit_code_; }; # if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. class GTEST_API_ KilledBySignal { public: explicit KilledBySignal(int signum); bool operator()(int exit_status) const; private: const int signum_; }; # endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, // since the sideeffects of the call are only visible in opt mode, and not // in debug mode. // // In practice, this can be used to test functions that utilize the // LOG(DFATAL) macro using the following style: // // int DieInDebugOr12(int* sideeffect) { // if (sideeffect) { // *sideeffect = 12; // } // LOG(DFATAL) << "death"; // return 12; // } // // TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { // int sideeffect = 0; // // Only asserts in dbg. // EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); // // #ifdef NDEBUG // // opt-mode has sideeffect visible. // EXPECT_EQ(12, sideeffect); // #else // // dbg-mode no visible sideeffect. // EXPECT_EQ(0, sideeffect); // #endif // } // // This will assert that DieInDebugReturn12InOpt() crashes in debug // mode, usually due to a DCHECK or LOG(DFATAL), but returns the // appropriate fallback value (12 in this case) in opt mode. If you // need to test that a function has appropriate side-effects in opt // mode, include assertions against the side-effects. A general // pattern for this is: // // EXPECT_DEBUG_DEATH({ // // Side-effects here will have an effect after this statement in // // opt mode, but none in debug mode. // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // # ifdef NDEBUG # define EXPECT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # else # define EXPECT_DEBUG_DEATH(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ ASSERT_DEATH(statement, regex) # endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if // death tests are supported; otherwise they just issue a warning. This is // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ ASSERT_DEATH(statement, regex) #else # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) #endif } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/0000775000175000017500000000000014764352500016316 5stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-tuple.h.pump0000664000175000017500000002201214750344764021651 $$ -*- mode: c++; -*- $var n = 10 $$ Maximum number of tuple fields we want to support. $$ This meta comment fixes auto-indentation in Emacs. }} // Copyright 2009 Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // Implements a subset of TR1 tuple needed by Google Test and Google Mock. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #include // For ::std::pair. // The compiler used in Symbian has a bug that prevents us from declaring the // tuple template as a friend (it complains that tuple is redefined). This // hack bypasses the bug by declaring the members that should otherwise be // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ template friend class tuple; \ private: #endif $range i 0..n-1 $range j 0..n $range k 1..n // GTEST_n_TUPLE_(T) is the type of an n-tuple. #define GTEST_0_TUPLE_(T) tuple<> $for k [[ $range m 0..k-1 $range m2 k..n-1 #define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> ]] // GTEST_n_TYPENAMES_(T) declares a list of n typenames. $for j [[ $range m 0..j-1 #define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] ]] // In theory, defining stuff in the ::std namespace is undefined // behavior. We can do this as we are playing the role of a standard // library vendor. namespace std { namespace tr1 { template <$for i, [[typename T$i = void]]> class tuple; // Anything in namespace gtest_internal is Google Test's INTERNAL // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. namespace gtest_internal { // ByRef::type is T if T is a reference; otherwise it's const T&. template struct ByRef { typedef const T& type; }; // NOLINT template struct ByRef { typedef T& type; }; // NOLINT // A handy wrapper for ByRef. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type // AddRef::type is T if T is a reference; otherwise it's T&. This // is the same as tr1::add_reference::type. template struct AddRef { typedef T& type; }; // NOLINT template struct AddRef { typedef T& type; }; // NOLINT // A handy wrapper for AddRef. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type // A helper for implementing get(). template class Get; // A helper for implementing tuple_element. kIndexValid is true // iff k < the number of fields in tuple type T. template struct TupleElement; $for i [[ template struct TupleElement { typedef T$i type; }; ]] } // namespace gtest_internal template <> class tuple<> { public: tuple() {} tuple(const tuple& /* t */) {} tuple& operator=(const tuple& /* t */) { return *this; } }; $for k [[ $range m 0..k-1 template class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { public: template friend class gtest_internal::Get; tuple() : $for m, [[f$(m)_()]] {} explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] $for m, [[f$(m)_(f$m)]] {} tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} template tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} $if k == 2 [[ template tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} ]] tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { return CopyFrom(t); } $if k == 2 [[ template tuple& operator=(const ::std::pair& p) { f0_ = p.first; f1_ = p.second; return *this; } ]] GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { $for m [[ f$(m)_ = t.f$(m)_; ]] return *this; } $for m [[ T$m f$(m)_; ]] }; ]] // 6.1.3.2 Tuple creation functions. // Known limitations: we don't support passing an // std::tr1::reference_wrapper to make_tuple(). And we don't // implement tie(). inline tuple<> make_tuple() { return tuple<>(); } $for k [[ $range m 0..k-1 template inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); } ]] // 6.1.3.3 Tuple helper classes. template struct tuple_size; $for j [[ template struct tuple_size { static const int value = $j; }; ]] template struct tuple_element { typedef typename gtest_internal::TupleElement< k < (tuple_size::value), k, Tuple>::type type; }; #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type // 6.1.3.4 Element access. namespace gtest_internal { $for i [[ template <> class Get<$i> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) Field(Tuple& t) { return t.f$(i)_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) ConstField(const Tuple& t) { return t.f$(i)_; } }; ]] } // namespace gtest_internal template GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) get(GTEST_$(n)_TUPLE_(T)& t) { return gtest_internal::Get::Field(t); } template GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) get(const GTEST_$(n)_TUPLE_(T)& t) { return gtest_internal::Get::ConstField(t); } // 6.1.3.5 Relational operators // We only implement == and !=, as we don't have a need for the rest yet. namespace gtest_internal { // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the // first k fields of t1 equals the first k fields of t2. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if // k1 != k2. template struct SameSizeTuplePrefixComparator; template <> struct SameSizeTuplePrefixComparator<0, 0> { template static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { return true; } }; template struct SameSizeTuplePrefixComparator { template static bool Eq(const Tuple1& t1, const Tuple2& t2) { return SameSizeTuplePrefixComparator::Eq(t1, t2) && ::std::tr1::get(t1) == ::std::tr1::get(t2); } }; } // namespace gtest_internal template inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, const GTEST_$(n)_TUPLE_(U)& u) { return gtest_internal::SameSizeTuplePrefixComparator< tuple_size::value, tuple_size::value>::Eq(t, u); } template inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } // 6.1.4 Pairs. // Unimplemented. } // namespace tr1 } // namespace std $for j [[ #undef GTEST_$(j)_TUPLE_ ]] $for j [[ #undef GTEST_$(j)_TYPENAMES_ ]] #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ #undef GTEST_BY_REF_ #undef GTEST_ADD_REF_ #undef GTEST_TUPLE_ELEMENT_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump0000664000175000017500000002231014750344764024530 $$ -*- mode: c++; -*- $var n = 50 $$ Maximum length of Values arguments we want to support. $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. // Copyright 2008 Google Inc. // 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 Google Inc. 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. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently Google Test supports at most $n arguments in Values, // and at most $maxtuple arguments in Combine. Please contact // googletestframework@googlegroups.com if you need more. // Please note that the number of arguments to Combine is limited // by the maximum arity of the implementation of tr1::tuple which is // currently set at $maxtuple. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-port.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Forward declarations of ValuesIn(), which is implemented in // include/gtest/gtest-param-test.h. template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end); template internal::ParamGenerator ValuesIn(const T (&array)[N]); template internal::ParamGenerator ValuesIn( const Container& container); namespace internal { // Used in the Values() function to provide polymorphic capabilities. template class ValueArray1 { public: explicit ValueArray1(T1 v1) : v1_(v1) {} template operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray1& other); const T1 v1_; }; $range i 2..n $for i [[ $range j 1..i template <$for j, [[typename T$j]]> class ValueArray$i { public: ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {} template operator ParamGenerator() const { const T array[] = {$for j, [[static_cast(v$(j)_)]]}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray$i& other); $for j [[ const T$j v$(j)_; ]] }; ]] # if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced // by the argument generators. // $range i 2..maxtuple $for i [[ $range j 1..i $range k 2..i template <$for j, [[typename T$j]]> class CartesianProductGenerator$i : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > { public: typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType; CartesianProductGenerator$i($for j, [[const ParamGenerator& g$j]]) : $for j, [[g$(j)_(g$j)]] {} virtual ~CartesianProductGenerator$i() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]); } virtual ParamIteratorInterface* End() const { return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, $for j, [[ const ParamGenerator& g$j, const typename ParamGenerator::iterator& current$(j)]]) : base_(base), $for j, [[ begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j) ]] { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current$(i)_; $for k [[ if (current$(i+2-k)_ == end$(i+2-k)_) { current$(i+2-k)_ = begin$(i+2-k)_; ++current$(i+2-k-1)_; } ]] ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ($for j && [[ current$(j)_ == typed_other->current$(j)_ ]]); } private: Iterator(const Iterator& other) : base_(other.base_), $for j, [[ begin$(j)_(other.begin$(j)_), end$(j)_(other.end$(j)_), current$(j)_(other.current$(j)_) ]] { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType($for j, [[*current$(j)_]]); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return $for j || [[ current$(j)_ == end$(j)_ ]]; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. $for j [[ const typename ParamGenerator::iterator begin$(j)_; const typename ParamGenerator::iterator end$(j)_; typename ParamGenerator::iterator current$(j)_; ]] ParamType current_value_; }; // class CartesianProductGenerator$i::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator$i& other); $for j [[ const ParamGenerator g$(j)_; ]] }; // class CartesianProductGenerator$i ]] // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Helper classes providing Combine() with polymorphic features. They allow // casting CartesianProductGeneratorN to ParamGenerator if T is // convertible to U. // $range i 2..maxtuple $for i [[ $range j 1..i template <$for j, [[class Generator$j]]> class CartesianProductHolder$i { public: CartesianProductHolder$i($for j, [[const Generator$j& g$j]]) : $for j, [[g$(j)_(g$j)]] {} template <$for j, [[typename T$j]]> operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const { return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >( new CartesianProductGenerator$i<$for j, [[T$j]]>( $for j,[[ static_cast >(g$(j)_) ]])); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder$i& other); $for j [[ const Generator$j g$(j)_; ]] }; // class CartesianProductHolder$i ]] # endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-param-util-generated.h0000664000175000017500000056726014750344764023572 // This file was GENERATED by command: // pump.py gtest-param-util-generated.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // 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 Google Inc. 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. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently Google Test supports at most 50 arguments in Values, // and at most 10 arguments in Combine. Please contact // googletestframework@googlegroups.com if you need more. // Please note that the number of arguments to Combine is limited // by the maximum arity of the implementation of tr1::tuple which is // currently set at 10. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-port.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Forward declarations of ValuesIn(), which is implemented in // include/gtest/gtest-param-test.h. template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end); template internal::ParamGenerator ValuesIn(const T (&array)[N]); template internal::ParamGenerator ValuesIn( const Container& container); namespace internal { // Used in the Values() function to provide polymorphic capabilities. template class ValueArray1 { public: explicit ValueArray1(T1 v1) : v1_(v1) {} template operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray1& other); const T1 v1_; }; template class ValueArray2 { public: ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray2& other); const T1 v1_; const T2 v2_; }; template class ValueArray3 { public: ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray3& other); const T1 v1_; const T2 v2_; const T3 v3_; }; template class ValueArray4 { public: ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), v4_(v4) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray4& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; }; template class ValueArray5 { public: ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray5& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; }; template class ValueArray6 { public: ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray6& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; }; template class ValueArray7 { public: ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray7& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; }; template class ValueArray8 { public: ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray8& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; }; template class ValueArray9 { public: ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray9& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; }; template class ValueArray10 { public: ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray10& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; }; template class ValueArray11 { public: ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray11& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; }; template class ValueArray12 { public: ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray12& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; }; template class ValueArray13 { public: ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray13& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; }; template class ValueArray14 { public: ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray14& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; }; template class ValueArray15 { public: ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray15& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; }; template class ValueArray16 { public: ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray16& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; }; template class ValueArray17 { public: ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray17& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; }; template class ValueArray18 { public: ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray18& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; }; template class ValueArray19 { public: ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray19& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; }; template class ValueArray20 { public: ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray20& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; }; template class ValueArray21 { public: ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray21& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; }; template class ValueArray22 { public: ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray22& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; }; template class ValueArray23 { public: ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray23& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; }; template class ValueArray24 { public: ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray24& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; }; template class ValueArray25 { public: ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray25& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; }; template class ValueArray26 { public: ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray26& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; }; template class ValueArray27 { public: ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray27& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; }; template class ValueArray28 { public: ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray28& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; }; template class ValueArray29 { public: ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray29& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; }; template class ValueArray30 { public: ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray30& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; }; template class ValueArray31 { public: ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray31& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; }; template class ValueArray32 { public: ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray32& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; }; template class ValueArray33 { public: ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray33& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; }; template class ValueArray34 { public: ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray34& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; }; template class ValueArray35 { public: ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray35& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; }; template class ValueArray36 { public: ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray36& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; }; template class ValueArray37 { public: ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray37& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; }; template class ValueArray38 { public: ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray38& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; }; template class ValueArray39 { public: ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray39& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; }; template class ValueArray40 { public: ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray40& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; }; template class ValueArray41 { public: ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray41& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; }; template class ValueArray42 { public: ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray42& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; }; template class ValueArray43 { public: ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray43& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; }; template class ValueArray44 { public: ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray44& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; }; template class ValueArray45 { public: ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray45& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; }; template class ValueArray46 { public: ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray46& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; }; template class ValueArray47 { public: ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray47& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; }; template class ValueArray48 { public: ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray48& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; }; template class ValueArray49 { public: ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray49& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; }; template class ValueArray50 { public: ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_), static_cast(v50_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray50& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; const T50 v50_; }; # if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced // by the argument generators. // template class CartesianProductGenerator2 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator2(const ParamGenerator& g1, const ParamGenerator& g2) : g1_(g1), g2_(g2) {} virtual ~CartesianProductGenerator2() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current2_; if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; ParamType current_value_; }; // class CartesianProductGenerator2::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator2& other); const ParamGenerator g1_; const ParamGenerator g2_; }; // class CartesianProductGenerator2 template class CartesianProductGenerator3 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator3(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3) : g1_(g1), g2_(g2), g3_(g3) {} virtual ~CartesianProductGenerator3() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current3_; if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; ParamType current_value_; }; // class CartesianProductGenerator3::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator3& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; }; // class CartesianProductGenerator3 template class CartesianProductGenerator4 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator4(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4) : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} virtual ~CartesianProductGenerator4() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current4_; if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; ParamType current_value_; }; // class CartesianProductGenerator4::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator4& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; }; // class CartesianProductGenerator4 template class CartesianProductGenerator5 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator5(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} virtual ~CartesianProductGenerator5() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current5_; if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; ParamType current_value_; }; // class CartesianProductGenerator5::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator5& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; }; // class CartesianProductGenerator5 template class CartesianProductGenerator6 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator6(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} virtual ~CartesianProductGenerator6() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current6_; if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; ParamType current_value_; }; // class CartesianProductGenerator6::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator6& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; }; // class CartesianProductGenerator6 template class CartesianProductGenerator7 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator7(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} virtual ~CartesianProductGenerator7() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current7_; if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; ParamType current_value_; }; // class CartesianProductGenerator7::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator7& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; }; // class CartesianProductGenerator7 template class CartesianProductGenerator8 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator8(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} virtual ~CartesianProductGenerator8() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current8_; if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; ParamType current_value_; }; // class CartesianProductGenerator8::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator8& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; }; // class CartesianProductGenerator8 template class CartesianProductGenerator9 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator9(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} virtual ~CartesianProductGenerator9() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current9_; if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; ParamType current_value_; }; // class CartesianProductGenerator9::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator9& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; }; // class CartesianProductGenerator9 template class CartesianProductGenerator10 : public ParamGeneratorInterface< ::std::tr1::tuple > { public: typedef ::std::tr1::tuple ParamType; CartesianProductGenerator10(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9, const ParamGenerator& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} virtual ~CartesianProductGenerator10() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end(), g10_, g10_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9, const ParamGenerator& g10, const typename ParamGenerator::iterator& current10) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9), begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current10_; if (current10_ == end10_) { current10_ = begin10_; ++current9_; } if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_ && current10_ == typed_other->current10_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_), begin10_(other.begin10_), end10_(other.end10_), current10_(other.current10_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_, *current10_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_ || current10_ == end10_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; const typename ParamGenerator::iterator begin10_; const typename ParamGenerator::iterator end10_; typename ParamGenerator::iterator current10_; ParamType current_value_; }; // class CartesianProductGenerator10::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator10& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; const ParamGenerator g10_; }; // class CartesianProductGenerator10 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Helper classes providing Combine() with polymorphic features. They allow // casting CartesianProductGeneratorN to ParamGenerator if T is // convertible to U. // template class CartesianProductHolder2 { public: CartesianProductHolder2(const Generator1& g1, const Generator2& g2) : g1_(g1), g2_(g2) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator2( static_cast >(g1_), static_cast >(g2_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder2& other); const Generator1 g1_; const Generator2 g2_; }; // class CartesianProductHolder2 template class CartesianProductHolder3 { public: CartesianProductHolder3(const Generator1& g1, const Generator2& g2, const Generator3& g3) : g1_(g1), g2_(g2), g3_(g3) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator3( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder3& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; }; // class CartesianProductHolder3 template class CartesianProductHolder4 { public: CartesianProductHolder4(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4) : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator4( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder4& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; }; // class CartesianProductHolder4 template class CartesianProductHolder5 { public: CartesianProductHolder5(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator5( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder5& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; }; // class CartesianProductHolder5 template class CartesianProductHolder6 { public: CartesianProductHolder6(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator6( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder6& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; }; // class CartesianProductHolder6 template class CartesianProductHolder7 { public: CartesianProductHolder7(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator7( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder7& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; }; // class CartesianProductHolder7 template class CartesianProductHolder8 { public: CartesianProductHolder8(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator8( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder8& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; }; // class CartesianProductHolder8 template class CartesianProductHolder9 { public: CartesianProductHolder9(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator9( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder9& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; }; // class CartesianProductHolder9 template class CartesianProductHolder10 { public: CartesianProductHolder10(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} template operator ParamGenerator< ::std::tr1::tuple >() const { return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator10( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_), static_cast >(g10_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder10& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; const Generator10 g10_; }; // class CartesianProductHolder10 # endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-tuple.h0000664000175000017500000006707714750344764020715 // This file was GENERATED by command: // pump.py gtest-tuple.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2009 Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // Implements a subset of TR1 tuple needed by Google Test and Google Mock. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #include // For ::std::pair. // The compiler used in Symbian has a bug that prevents us from declaring the // tuple template as a friend (it complains that tuple is redefined). This // hack bypasses the bug by declaring the members that should otherwise be // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ template friend class tuple; \ private: #endif // GTEST_n_TUPLE_(T) is the type of an n-tuple. #define GTEST_0_TUPLE_(T) tuple<> #define GTEST_1_TUPLE_(T) tuple #define GTEST_2_TUPLE_(T) tuple #define GTEST_3_TUPLE_(T) tuple #define GTEST_4_TUPLE_(T) tuple #define GTEST_5_TUPLE_(T) tuple #define GTEST_6_TUPLE_(T) tuple #define GTEST_7_TUPLE_(T) tuple #define GTEST_8_TUPLE_(T) tuple #define GTEST_9_TUPLE_(T) tuple #define GTEST_10_TUPLE_(T) tuple // GTEST_n_TYPENAMES_(T) declares a list of n typenames. #define GTEST_0_TYPENAMES_(T) #define GTEST_1_TYPENAMES_(T) typename T##0 #define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 #define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 #define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3 #define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4 #define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5 #define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6 #define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 #define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8 #define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8, typename T##9 // In theory, defining stuff in the ::std namespace is undefined // behavior. We can do this as we are playing the role of a standard // library vendor. namespace std { namespace tr1 { template class tuple; // Anything in namespace gtest_internal is Google Test's INTERNAL // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. namespace gtest_internal { // ByRef::type is T if T is a reference; otherwise it's const T&. template struct ByRef { typedef const T& type; }; // NOLINT template struct ByRef { typedef T& type; }; // NOLINT // A handy wrapper for ByRef. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type // AddRef::type is T if T is a reference; otherwise it's T&. This // is the same as tr1::add_reference::type. template struct AddRef { typedef T& type; }; // NOLINT template struct AddRef { typedef T& type; }; // NOLINT // A handy wrapper for AddRef. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type // A helper for implementing get(). template class Get; // A helper for implementing tuple_element. kIndexValid is true // iff k < the number of fields in tuple type T. template struct TupleElement; template struct TupleElement { typedef T0 type; }; template struct TupleElement { typedef T1 type; }; template struct TupleElement { typedef T2 type; }; template struct TupleElement { typedef T3 type; }; template struct TupleElement { typedef T4 type; }; template struct TupleElement { typedef T5 type; }; template struct TupleElement { typedef T6 type; }; template struct TupleElement { typedef T7 type; }; template struct TupleElement { typedef T8 type; }; template struct TupleElement { typedef T9 type; }; } // namespace gtest_internal template <> class tuple<> { public: tuple() {} tuple(const tuple& /* t */) {} tuple& operator=(const tuple& /* t */) { return *this; } }; template class GTEST_1_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_() {} explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} tuple(const tuple& t) : f0_(t.f0_) {} template tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_1_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { f0_ = t.f0_; return *this; } T0 f0_; }; template class GTEST_2_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), f1_(f1) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_2_TUPLE_(U)& t) { return CopyFrom(t); } template tuple& operator=(const ::std::pair& p) { f0_ = p.first; f1_ = p.second; return *this; } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; return *this; } T0 f0_; T1 f1_; }; template class GTEST_3_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} template tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_3_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; return *this; } T0 f0_; T1 f1_; T2 f2_; }; template class GTEST_4_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), f3_(f3) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} template tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_4_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; }; template class GTEST_5_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} template tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_5_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; }; template class GTEST_6_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} template tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_6_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; }; template class GTEST_7_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} template tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_7_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; }; template class GTEST_8_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} template tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_8_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; }; template class GTEST_9_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} template tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_9_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; }; template class tuple { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), f9_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} template tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_10_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; f9_ = t.f9_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; T9 f9_; }; // 6.1.3.2 Tuple creation functions. // Known limitations: we don't support passing an // std::tr1::reference_wrapper to make_tuple(). And we don't // implement tie(). inline tuple<> make_tuple() { return tuple<>(); } template inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { return GTEST_1_TUPLE_(T)(f0); } template inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { return GTEST_2_TUPLE_(T)(f0, f1); } template inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { return GTEST_3_TUPLE_(T)(f0, f1, f2); } template inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3) { return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); } template inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4) { return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); } template inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5) { return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); } template inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6) { return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); } template inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); } template inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8) { return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); } template inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8, const T9& f9) { return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); } // 6.1.3.3 Tuple helper classes. template struct tuple_size; template struct tuple_size { static const int value = 0; }; template struct tuple_size { static const int value = 1; }; template struct tuple_size { static const int value = 2; }; template struct tuple_size { static const int value = 3; }; template struct tuple_size { static const int value = 4; }; template struct tuple_size { static const int value = 5; }; template struct tuple_size { static const int value = 6; }; template struct tuple_size { static const int value = 7; }; template struct tuple_size { static const int value = 8; }; template struct tuple_size { static const int value = 9; }; template struct tuple_size { static const int value = 10; }; template struct tuple_element { typedef typename gtest_internal::TupleElement< k < (tuple_size::value), k, Tuple>::type type; }; #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type // 6.1.3.4 Element access. namespace gtest_internal { template <> class Get<0> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) Field(Tuple& t) { return t.f0_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) ConstField(const Tuple& t) { return t.f0_; } }; template <> class Get<1> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) Field(Tuple& t) { return t.f1_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) ConstField(const Tuple& t) { return t.f1_; } }; template <> class Get<2> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) Field(Tuple& t) { return t.f2_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) ConstField(const Tuple& t) { return t.f2_; } }; template <> class Get<3> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) Field(Tuple& t) { return t.f3_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) ConstField(const Tuple& t) { return t.f3_; } }; template <> class Get<4> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) Field(Tuple& t) { return t.f4_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) ConstField(const Tuple& t) { return t.f4_; } }; template <> class Get<5> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) Field(Tuple& t) { return t.f5_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) ConstField(const Tuple& t) { return t.f5_; } }; template <> class Get<6> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) Field(Tuple& t) { return t.f6_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) ConstField(const Tuple& t) { return t.f6_; } }; template <> class Get<7> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) Field(Tuple& t) { return t.f7_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) ConstField(const Tuple& t) { return t.f7_; } }; template <> class Get<8> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) Field(Tuple& t) { return t.f8_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) ConstField(const Tuple& t) { return t.f8_; } }; template <> class Get<9> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) Field(Tuple& t) { return t.f9_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) ConstField(const Tuple& t) { return t.f9_; } }; } // namespace gtest_internal template GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::Field(t); } template GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(const GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::ConstField(t); } // 6.1.3.5 Relational operators // We only implement == and !=, as we don't have a need for the rest yet. namespace gtest_internal { // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the // first k fields of t1 equals the first k fields of t2. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if // k1 != k2. template struct SameSizeTuplePrefixComparator; template <> struct SameSizeTuplePrefixComparator<0, 0> { template static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { return true; } }; template struct SameSizeTuplePrefixComparator { template static bool Eq(const Tuple1& t1, const Tuple2& t2) { return SameSizeTuplePrefixComparator::Eq(t1, t2) && ::std::tr1::get(t1) == ::std::tr1::get(t2); } }; } // namespace gtest_internal template inline bool operator==(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return gtest_internal::SameSizeTuplePrefixComparator< tuple_size::value, tuple_size::value>::Eq(t, u); } template inline bool operator!=(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return !(t == u); } // 6.1.4 Pairs. // Unimplemented. } // namespace tr1 } // namespace std #undef GTEST_0_TUPLE_ #undef GTEST_1_TUPLE_ #undef GTEST_2_TUPLE_ #undef GTEST_3_TUPLE_ #undef GTEST_4_TUPLE_ #undef GTEST_5_TUPLE_ #undef GTEST_6_TUPLE_ #undef GTEST_7_TUPLE_ #undef GTEST_8_TUPLE_ #undef GTEST_9_TUPLE_ #undef GTEST_10_TUPLE_ #undef GTEST_0_TYPENAMES_ #undef GTEST_1_TYPENAMES_ #undef GTEST_2_TYPENAMES_ #undef GTEST_3_TYPENAMES_ #undef GTEST_4_TYPENAMES_ #undef GTEST_5_TYPENAMES_ #undef GTEST_6_TYPENAMES_ #undef GTEST_7_TYPENAMES_ #undef GTEST_8_TYPENAMES_ #undef GTEST_9_TYPENAMES_ #undef GTEST_10_TYPENAMES_ #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ #undef GTEST_BY_REF_ #undef GTEST_ADD_REF_ #undef GTEST_TUPLE_ELEMENT_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-string.h0000664000175000017500000001547014750344764021060 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares the String class and functions used internally by // Google Test. They are subject to change without notice. They should not used // by code external to Google Test. // // This header file is #included by . // It should not be #included by other files. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifdef __BORLANDC__ // string.h is not guaranteed to provide strcpy on C++ Builder. # include #endif #include #include #include "gtest/internal/gtest-port.h" namespace testing { namespace internal { // String - an abstract class holding static string utilities. class GTEST_API_ String { public: // Static utility methods // Clones a 0-terminated C string, allocating memory using new. The // caller is responsible for deleting the return value using // delete[]. Returns the cloned string, or NULL if the input is // NULL. // // This is different from strdup() in string.h, which allocates // memory using malloc(). static const char* CloneCString(const char* c_str); #if GTEST_OS_WINDOWS_MOBILE // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be // able to pass strings to Win32 APIs on CE we need to convert them // to 'Unicode', UTF-16. // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. // // The wide string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static LPCWSTR AnsiToUtf16(const char* c_str); // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. // // The returned string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static const char* Utf16ToAnsi(LPCWSTR utf16_str); #endif // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CStringEquals(const char* lhs, const char* rhs); // Converts a wide C string to a String using the UTF-8 encoding. // NULL will be converted to "(null)". If an error occurred during // the conversion, "(failed to convert from wide string)" is // returned. static std::string ShowWideCString(const wchar_t* wide_c_str); // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Compares two C strings, ignoring case. Returns true iff they // have the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs); // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Returns true iff the given string ends with the given suffix, ignoring // case. Any string is considered to end with an empty suffix. static bool EndsWithCaseInsensitive( const std::string& str, const std::string& suffix); // Formats an int value as "%02d". static std::string FormatIntWidth2(int value); // "%02d" for width == 2 // Formats an int value as "%X". static std::string FormatHexInt(int value); // Formats a byte as "%02X". static std::string FormatByte(unsigned char value); private: String(); // Not meant to be instantiated. }; // class String // Gets the content of the stringstream's buffer as an std::string. Each '\0' // character in the buffer is replaced with "\\0". GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-filepath.h0000664000175000017500000002260314750344764021342 // Copyright 2008, Google Inc. // 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 Google Inc. 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. // // Author: keith.ray@gmail.com (Keith Ray) // // Google Test filepath utilities // // This header file declares classes and functions used internally by // Google Test. They are subject to change without notice. // // This file is #included in . // Do not include this header file separately! #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #include "gtest/internal/gtest-string.h" namespace testing { namespace internal { // FilePath - a class for file and directory pathname manipulation which // handles platform-specific conventions (like the pathname separator). // Used for helper functions for naming files in a directory for xml output. // Except for Set methods, all methods are const or static, which provides an // "immutable value object" -- useful for peace of mind. // A FilePath with a value ending in a path separator ("like/this/") represents // a directory, otherwise it is assumed to represent a file. In either case, // it may or may not represent an actual file or directory in the file system. // Names are NOT checked for syntax correctness -- no checking for illegal // characters, malformed paths, etc. class GTEST_API_ FilePath { public: FilePath() : pathname_("") { } FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } explicit FilePath(const std::string& pathname) : pathname_(pathname) { Normalize(); } FilePath& operator=(const FilePath& rhs) { Set(rhs); return *this; } void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } const std::string& string() const { return pathname_; } const char* c_str() const { return pathname_.c_str(); } // Returns the current working directory, or "" if unsuccessful. static FilePath GetCurrentDir(); // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. static FilePath MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension); // Given directory = "dir", relative_path = "test.xml", // returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. static FilePath ConcatPaths(const FilePath& directory, const FilePath& relative_path); // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. static FilePath GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension); // Returns true iff the path is "". bool IsEmpty() const { return pathname_.empty(); } // If input name has a trailing separator character, removes it and returns // the name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath RemoveTrailingPathSeparator() const; // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveDirectoryName() const; // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveFileName() const; // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath RemoveExtension(const char* extension) const; // Creates directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create // directories for any reason. Will also return false if the FilePath does // not represent a directory (that is, it doesn't end with a path separator). bool CreateDirectoriesRecursively() const; // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool CreateFolder() const; // Returns true if FilePath describes something in the file-system, // either a file, directory, or whatever, and that something exists. bool FileOrDirectoryExists() const; // Returns true if pathname describes a directory in the file-system // that exists. bool DirectoryExists() const; // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool IsDirectory() const; // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool IsRootDirectory() const; // Returns true if pathname describes an absolute path. bool IsAbsolutePath() const; private: // Replaces multiple consecutive separators with a single separator. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // // A pathname with multiple consecutive separators may occur either through // user error or as a result of some scripts or APIs that generate a pathname // with a trailing separator. On other platforms the same API or script // may NOT generate a pathname with a trailing "/". Then elsewhere that // pathname may have another "/" and pathname components added to it, // without checking for the separator already being there. // The script language and operating system may allow paths like "foo//bar" // but some of the functions in FilePath will not handle that correctly. In // particular, RemoveTrailingPathSeparator() only removes one separator, and // it is called in CreateDirectoriesRecursively() assuming that it will change // a pathname from directory syntax (trailing separator) to filename syntax. // // On Windows this method also replaces the alternate path separator '/' with // the primary path separator '\\', so that for example "bar\\/\\foo" becomes // "bar\\foo". void Normalize(); // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; std::string pathname_; }; // class FilePath } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-internal.h0000664000175000017500000012616114750344764021366 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares functions and macros used internally by // Google Test. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX # include # include # include # include #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #include #include #include #include #include #include #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-type-util.h" // Due to C++ preprocessor weirdness, we need double indirection to // concatenate two tokens when one of them is __LINE__. Writing // // foo ## __LINE__ // // will result in the token foo__LINE__, instead of foo followed by // the current line number. For more details, see // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar class ProtocolMessage; namespace proto2 { class Message; } namespace testing { // Forward declarations. class AssertionResult; // Result of an assertion. class Message; // Represents a failure message. class Test; // Represents a test. class TestInfo; // Information about a test. class TestPartResult; // Result of a test part. class UnitTest; // A collection of test cases. template ::std::string PrintToString(const T& value); namespace internal { struct TraceInfo; // Information about a trace point. class ScopedTrace; // Implements scoped trace. class TestInfoImpl; // Opaque implementation of TestInfo class UnitTestImpl; // Opaque implementation of UnitTest // How many times InitGoogleTest() has been called. GTEST_API_ extern int g_init_gtest_count; // The text used in failure messages to indicate the start of the // stack trace. GTEST_API_ extern const char kStackTraceMarker[]; // Two overloaded helpers for checking at compile time whether an // expression is a null pointer literal (i.e. NULL or any 0-valued // compile-time integral constant). Their return values have // different sizes, so we can use sizeof() to test which version is // picked by the compiler. These helpers have no implementations, as // we only need their signatures. // // Given IsNullLiteralHelper(x), the compiler will pick the first // version if x can be implicitly converted to Secret*, and pick the // second version otherwise. Since Secret is a secret and incomplete // type, the only expression a user can write that has type Secret* is // a null pointer literal. Therefore, we know that x is a null // pointer literal if and only if the first version is picked by the // compiler. char IsNullLiteralHelper(Secret* p); char (&IsNullLiteralHelper(...))[2]; // NOLINT // A compile-time bool constant that is true if and only if x is a // null pointer literal (i.e. NULL or any 0-valued compile-time // integral constant). #ifdef GTEST_ELLIPSIS_NEEDS_POD_ // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_IS_NULL_LITERAL_(x) false #else # define GTEST_IS_NULL_LITERAL_(x) \ (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) #endif // GTEST_ELLIPSIS_NEEDS_POD_ // Appends the user-supplied message to the Google-Test-generated message. GTEST_API_ std::string AppendUserMessage( const std::string& gtest_msg, const Message& user_msg); #if GTEST_HAS_EXCEPTIONS // This exception is thrown by (and only by) a failed Google Test // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions // are enabled). We derive it from std::runtime_error, which is for // errors presumably detectable only at run time. Since // std::runtime_error inherits from std::exception, many testing // frameworks know how to extract and print the message inside it. class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { public: explicit GoogleTestFailureException(const TestPartResult& failure); }; #endif // GTEST_HAS_EXCEPTIONS // A helper class for creating scoped traces in user programs. class GTEST_API_ ScopedTrace { public: // The c'tor pushes the given source file location and message onto // a trace stack maintained by Google Test. ScopedTrace(const char* file, int line, const Message& message); // The d'tor pops the info pushed by the c'tor. // // Note that the d'tor is not virtual in order to be efficient. // Don't inherit from ScopedTrace! ~ScopedTrace(); private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); } GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its // c'tor and d'tor. Therefore it doesn't // need to be used otherwise. // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. GTEST_API_ AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case); // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. GTEST_API_ std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value); // This template class represents an IEEE floating-point number // (either single-precision or double-precision, depending on the // template parameters). // // The purpose of this class is to do more sophisticated number // comparison. (Due to round-off error, etc, it's very unlikely that // two floating-points will be equal exactly. Hence a naive // comparison by the == operation often doesn't work.) // // Format of IEEE floating-point: // // The most-significant bit being the leftmost, an IEEE // floating-point looks like // // sign_bit exponent_bits fraction_bits // // Here, sign_bit is a single bit that designates the sign of the // number. // // For float, there are 8 exponent bits and 23 fraction bits. // // For double, there are 11 exponent bits and 52 fraction bits. // // More details can be found at // http://en.wikipedia.org/wiki/IEEE_floating-point_standard. // // Template parameter: // // RawType: the raw floating-point type (either float or double) template class FloatingPoint { public: // Defines the unsigned integer type that has the same size as the // floating point number. typedef typename TypeWithSize::UInt Bits; // Constants. // # of bits in a number. static const size_t kBitCount = 8*sizeof(RawType); // # of fraction bits in a number. static const size_t kFractionBitCount = std::numeric_limits::digits - 1; // # of exponent bits in a number. static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; // The mask for the sign bit. static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); // The mask for the fraction bits. static const Bits kFractionBitMask = ~static_cast(0) >> (kExponentBitCount + 1); // The mask for the exponent bits. static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); // How many ULP's (Units in the Last Place) we want to tolerate when // comparing two numbers. The larger the value, the more error we // allow. A 0 value means that two numbers must be exactly the same // to be considered equal. // // The maximum error of a single floating-point operation is 0.5 // units in the last place. On Intel CPU's, all floating-point // calculations are done with 80-bit precision, while double has 64 // bits. Therefore, 4 should be enough for ordinary use. // // See the following article for more details on ULP: // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ static const size_t kMaxUlps = 4; // Constructs a FloatingPoint from a raw floating-point number. // // On an Intel CPU, passing a non-normalized NAN (Not a Number) // around may change its bits, although the new value is guaranteed // to be also a NAN. Therefore, don't expect this constructor to // preserve the bits in x when x is a NAN. explicit FloatingPoint(const RawType& x) { u_.value_ = x; } // Static methods // Reinterprets a bit pattern as a floating-point number. // // This function is needed to test the AlmostEquals() method. static RawType ReinterpretBits(const Bits bits) { FloatingPoint fp(0); fp.u_.bits_ = bits; return fp.u_.value_; } // Returns the floating-point number that represent positive infinity. static RawType Infinity() { return ReinterpretBits(kExponentBitMask); } // Returns the maximum representable finite floating-point number. static RawType Max(); // Non-static methods // Returns the bits that represents this number. const Bits &bits() const { return u_.bits_; } // Returns the exponent bits of this number. Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } // Returns the fraction bits of this number. Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } // Returns the sign bit of this number. Bits sign_bit() const { return kSignBitMask & u_.bits_; } // Returns true iff this is NAN (not a number). bool is_nan() const { // It's a NAN if the exponent bits are all ones and the fraction // bits are not entirely zeros. return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); } // Returns true iff this number is at most kMaxUlps ULP's away from // rhs. In particular, this function: // // - returns false if either number is (or both are) NAN. // - treats really large numbers as almost equal to infinity. // - thinks +0.0 and -0.0 are 0 DLP's apart. bool AlmostEquals(const FloatingPoint& rhs) const { // The IEEE standard says that any comparison operation involving // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= kMaxUlps; } private: // The data type used to store the actual floating-point number. union FloatingPointUnion { RawType value_; // The raw floating-point number. Bits bits_; // The bits that represent the number. }; // Converts an integer from the sign-and-magnitude representation to // the biased representation. More precisely, let N be 2 to the // power of (kBitCount - 1), an integer x is represented by the // unsigned number x + N. // // For instance, // // -N + 1 (the most negative number representable using // sign-and-magnitude) is represented by 1; // 0 is represented by N; and // N - 1 (the biggest number representable using // sign-and-magnitude) is represented by 2N - 1. // // Read http://en.wikipedia.org/wiki/Signed_number_representations // for more details on signed number representations. static Bits SignAndMagnitudeToBiased(const Bits &sam) { if (kSignBitMask & sam) { // sam represents a negative number. return ~sam + 1; } else { // sam represents a positive number. return kSignBitMask | sam; } } // Given two numbers in the sign-and-magnitude representation, // returns the distance between them as an unsigned number. static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, const Bits &sam2) { const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased2 = SignAndMagnitudeToBiased(sam2); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); } FloatingPointUnion u_; }; // We cannot use std::numeric_limits::max() as it clashes with the max() // macro defined by . template <> inline float FloatingPoint::Max() { return FLT_MAX; } template <> inline double FloatingPoint::Max() { return DBL_MAX; } // Typedefs the instances of the FloatingPoint template class that we // care to use. typedef FloatingPoint Float; typedef FloatingPoint Double; // In order to catch the mistake of putting tests that use different // test fixture classes in the same test case, we need to assign // unique IDs to fixture classes and compare them. The TypeId type is // used to hold such IDs. The user should treat TypeId as an opaque // type: the only operation allowed on TypeId values is to compare // them for equality using the == operator. typedef const void* TypeId; template class TypeIdHelper { public: // dummy_ must not have a const type. Otherwise an overly eager // compiler (e.g. MSVC 7.1 & 8.0) may try to merge // TypeIdHelper::dummy_ for different Ts as an "optimization". static bool dummy_; }; template bool TypeIdHelper::dummy_ = false; // GetTypeId() returns the ID of type T. Different values will be // returned for different types. Calling the function twice with the // same type argument is guaranteed to return the same ID. template TypeId GetTypeId() { // The compiler is required to allocate a different // TypeIdHelper::dummy_ variable for each T used to instantiate // the template. Therefore, the address of dummy_ is guaranteed to // be unique. return &(TypeIdHelper::dummy_); } // Returns the type ID of ::testing::Test. Always call this instead // of GetTypeId< ::testing::Test>() to get the type ID of // ::testing::Test, as the latter may give the wrong result due to a // suspected linker bug when compiling Google Test as a Mac OS X // framework. GTEST_API_ TypeId GetTestTypeId(); // Defines the abstract factory interface that creates instances // of a Test object. class TestFactoryBase { public: virtual ~TestFactoryBase() {} // Creates a test instance to run. The instance is both created and destroyed // within TestInfoImpl::Run() virtual Test* CreateTest() = 0; protected: TestFactoryBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); }; // This class provides implementation of TeastFactoryBase interface. // It is used in TEST and TEST_F macros. template class TestFactoryImpl : public TestFactoryBase { public: virtual Test* CreateTest() { return new TestClass; } }; #if GTEST_OS_WINDOWS // Predicate-formatters for implementing the HRESULT checking macros // {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} // We pass a long instead of HRESULT to avoid causing an // include dependency for the HRESULT type. GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, long hr); // NOLINT GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT #endif // GTEST_OS_WINDOWS // Types of SetUpTestCase() and TearDownTestCase() functions. typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param text representation of the test's value parameter, // or NULL if this is not a type-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. GTEST_API_ TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory); // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // State of the definition of a type-parameterized test case. class GTEST_API_ TypedTestCasePState { public: TypedTestCasePState() : registered_(false) {} // Adds the given test name to defined_test_names_ and return true // if the test case hasn't been registered; otherwise aborts the // program. bool AddTestName(const char* file, int line, const char* case_name, const char* test_name) { if (registered_) { fprintf(stderr, "%s Test %s must be defined before " "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", FormatFileLocation(file, line).c_str(), test_name, case_name); fflush(stderr); posix::Abort(); } defined_test_names_.insert(test_name); return true; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests); private: bool registered_; ::std::set defined_test_names_; }; // Skips to the first non-space char after the first comma in 'str'; // returns NULL if no comma is found in 'str'. inline const char* SkipComma(const char* str) { const char* comma = strchr(str, ','); if (comma == NULL) { return NULL; } while (IsSpace(*(++comma))) {} return comma; } // Returns the prefix of 'str' before the first comma in it; returns // the entire string if it contains no comma. inline std::string GetPrefixUntilComma(const char* str) { const char* comma = strchr(str, ','); return comma == NULL ? str : std::string(str, comma); } // TypeParameterizedTest::Register() // registers a list of type-parameterized tests with Google Test. The // return value is insignificant - we just need to return something // such that we can call this function in a namespace scope. // // Implementation note: The GTEST_TEMPLATE_ macro declares a template // template parameter. It's defined in gtest-type-util.h. template class TypeParameterizedTest { public: // 'index' is the index of the test in the type list 'Types' // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, // Types). Valid values for 'index' are [0, N - 1] where N is the // length of Types. static bool Register(const char* prefix, const char* case_name, const char* test_names, int index) { typedef typename Types::Head Type; typedef Fixture FixtureClass; typedef typename GTEST_BIND_(TestSel, Type) TestClass; // First, registers the first type-parameterized test in the type // list. MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + StreamableToString(index)).c_str(), GetPrefixUntilComma(test_names).c_str(), GetTypeName().c_str(), NULL, // No value parameter. GetTypeId(), TestClass::SetUpTestCase, TestClass::TearDownTestCase, new TestFactoryImpl); // Next, recurses (at compile time) with the tail of the type list. return TypeParameterizedTest ::Register(prefix, case_name, test_names, index + 1); } }; // The base case for the compile time recursion. template class TypeParameterizedTest { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/, int /*index*/) { return true; } }; // TypeParameterizedTestCase::Register() // registers *all combinations* of 'Tests' and 'Types' with Google // Test. The return value is insignificant - we just need to return // something such that we can call this function in a namespace scope. template class TypeParameterizedTestCase { public: static bool Register(const char* prefix, const char* case_name, const char* test_names) { typedef typename Tests::Head Head; // First, register the first test in 'Test' for each type in 'Types'. TypeParameterizedTest::Register( prefix, case_name, test_names, 0); // Next, recurses (at compile time) with the tail of the test list. return TypeParameterizedTestCase ::Register(prefix, case_name, SkipComma(test_names)); } }; // The base case for the compile time recursion. template class TypeParameterizedTestCase { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/) { return true; } }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( UnitTest* unit_test, int skip_count); // Helpers for suppressing warnings on unreachable code or constant // condition. // Always returns true. GTEST_API_ bool AlwaysTrue(); // Always returns false. inline bool AlwaysFalse() { return !AlwaysTrue(); } // Helper for suppressing false warning from Clang on a const char* // variable declared in a conditional expression always being NULL in // the else branch. struct GTEST_API_ ConstCharPtr { ConstCharPtr(const char* str) : value(str) {} operator bool() const { return true; } const char* value; }; // A simple Linear Congruential Generator for generating random // numbers with a uniform distribution. Unlike rand() and srand(), it // doesn't use global state (and therefore can't interfere with user // code). Unlike rand_r(), it's portable. An LCG isn't very random, // but it's good enough for our purposes. class GTEST_API_ Random { public: static const UInt32 kMaxRange = 1u << 31; explicit Random(UInt32 seed) : state_(seed) {} void Reseed(UInt32 seed) { state_ = seed; } // Generates a random number from [0, range). Crashes if 'range' is // 0 or greater than kMaxRange. UInt32 Generate(UInt32 range); private: UInt32 state_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); }; // Defining a variable of type CompileAssertTypesEqual will cause a // compiler error iff T1 and T2 are different types. template struct CompileAssertTypesEqual; template struct CompileAssertTypesEqual { }; // Removes the reference from a type if it is a reference type, // otherwise leaves it unchanged. This is the same as // tr1::remove_reference, which is not widely available yet. template struct RemoveReference { typedef T type; }; // NOLINT template struct RemoveReference { typedef T type; }; // NOLINT // A handy wrapper around RemoveReference that works when the argument // T depends on template parameters. #define GTEST_REMOVE_REFERENCE_(T) \ typename ::testing::internal::RemoveReference::type // Removes const from a type if it is a const type, otherwise leaves // it unchanged. This is the same as tr1::remove_const, which is not // widely available yet. template struct RemoveConst { typedef T type; }; // NOLINT template struct RemoveConst { typedef T type; }; // NOLINT // MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above // definition to fail to remove the const in 'const int[3]' and 'const // char[3][4]'. The following specialization works around the bug. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #if defined(_MSC_VER) && _MSC_VER < 1400 // This is the only specialization that allows VC++ 7.1 to remove const in // 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC // and thus needs to be conditionally compiled. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #endif // A handy wrapper around RemoveConst that works when the argument // T depends on template parameters. #define GTEST_REMOVE_CONST_(T) \ typename ::testing::internal::RemoveConst::type // Turns const U&, U&, const U, and U all into U. #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) // Adds reference to a type if it is not a reference type, // otherwise leaves it unchanged. This is the same as // tr1::add_reference, which is not widely available yet. template struct AddReference { typedef T& type; }; // NOLINT template struct AddReference { typedef T& type; }; // NOLINT // A handy wrapper around AddReference that works when the argument T // depends on template parameters. #define GTEST_ADD_REFERENCE_(T) \ typename ::testing::internal::AddReference::type // Adds a reference to const on top of T as necessary. For example, // it transforms // // char ==> const char& // const char ==> const char& // char& ==> const char& // const char& ==> const char& // // The argument T must depend on some template parameters. #define GTEST_REFERENCE_TO_CONST_(T) \ GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) // ImplicitlyConvertible::value is a compile-time bool // constant that's true iff type From can be implicitly converted to // type To. template class ImplicitlyConvertible { private: // We need the following helper functions only for their types. // They have no implementations. // MakeFrom() is an expression whose type is From. We cannot simply // use From(), as the type From may not have a public default // constructor. static From MakeFrom(); // These two functions are overloaded. Given an expression // Helper(x), the compiler will pick the first version if x can be // implicitly converted to type To; otherwise it will pick the // second version. // // The first version returns a value of size 1, and the second // version returns a value of size 2. Therefore, by checking the // size of Helper(x), which can be done at compile time, we can tell // which version of Helper() is used, and hence whether x can be // implicitly converted to type To. static char Helper(To); static char (&Helper(...))[2]; // NOLINT // We have to put the 'public' section after the 'private' section, // or MSVC refuses to compile the code. public: // MSVC warns about implicitly converting from double to int for // possible loss of data, so we need to temporarily disable the // warning. #ifdef _MSC_VER # pragma warning(push) // Saves the current warning state. # pragma warning(disable:4244) // Temporarily disables warning 4244. static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; # pragma warning(pop) // Restores the warning state. #elif defined(__BORLANDC__) // C++Builder cannot use member overload resolution during template // instantiation. The simplest workaround is to use its C++0x type traits // functions (C++Builder 2009 and above only). static const bool value = __is_convertible(From, To); #else static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; #endif // _MSV_VER }; template const bool ImplicitlyConvertible::value; // IsAProtocolMessage::value is a compile-time bool constant that's // true iff T is type ProtocolMessage, proto2::Message, or a subclass // of those. template struct IsAProtocolMessage : public bool_constant< ImplicitlyConvertible::value || ImplicitlyConvertible::value> { }; // When the compiler sees expression IsContainerTest(0), if C is an // STL-style container class, the first overload of IsContainerTest // will be viable (since both C::iterator* and C::const_iterator* are // valid types and NULL can be implicitly converted to them). It will // be picked over the second overload as 'int' is a perfect match for // the type of argument 0. If C::iterator or C::const_iterator is not // a valid type, the first overload is not viable, and the second // overload will be picked. Therefore, we can determine whether C is // a container class by checking the type of IsContainerTest(0). // The value of the expression is insignificant. // // Note that we look for both C::iterator and C::const_iterator. The // reason is that C++ injects the name of a class as a member of the // class itself (e.g. you can refer to class iterator as either // 'iterator' or 'iterator::iterator'). If we look for C::iterator // only, for example, we would mistakenly think that a class named // iterator is an STL container. // // Also note that the simpler approach of overloading // IsContainerTest(typename C::const_iterator*) and // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. typedef int IsContainer; template IsContainer IsContainerTest(int /* dummy */, typename C::iterator* /* it */ = NULL, typename C::const_iterator* /* const_it */ = NULL) { return 0; } typedef char IsNotContainer; template IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } // EnableIf::type is void when 'Cond' is true, and // undefined when 'Cond' is false. To use SFINAE to make a function // overload only apply when a particular expression is true, add // "typename EnableIf::type* = 0" as the last parameter. template struct EnableIf; template<> struct EnableIf { typedef void type; }; // NOLINT // Utilities for native arrays. // ArrayEq() compares two k-dimensional native arrays using the // elements' operator==, where k can be any integer >= 0. When k is // 0, ArrayEq() degenerates into comparing a single pair of values. template bool ArrayEq(const T* lhs, size_t size, const U* rhs); // This generic version is used when k is 0. template inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } // This overload is used when k >= 1. template inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { return internal::ArrayEq(lhs, N, rhs); } // This helper reduces code bloat. If we instead put its logic inside // the previous ArrayEq() function, arrays with different sizes would // lead to different copies of the template code. template bool ArrayEq(const T* lhs, size_t size, const U* rhs) { for (size_t i = 0; i != size; i++) { if (!internal::ArrayEq(lhs[i], rhs[i])) return false; } return true; } // Finds the first element in the iterator range [begin, end) that // equals elem. Element may be a native array type itself. template Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { for (Iter it = begin; it != end; ++it) { if (internal::ArrayEq(*it, elem)) return it; } return end; } // CopyArray() copies a k-dimensional native array using the elements' // operator=, where k can be any integer >= 0. When k is 0, // CopyArray() degenerates into copying a single value. template void CopyArray(const T* from, size_t size, U* to); // This generic version is used when k is 0. template inline void CopyArray(const T& from, U* to) { *to = from; } // This overload is used when k >= 1. template inline void CopyArray(const T(&from)[N], U(*to)[N]) { internal::CopyArray(from, N, *to); } // This helper reduces code bloat. If we instead put its logic inside // the previous CopyArray() function, arrays with different sizes // would lead to different copies of the template code. template void CopyArray(const T* from, size_t size, U* to) { for (size_t i = 0; i != size; i++) { internal::CopyArray(from[i], to + i); } } // The relation between an NativeArray object (see below) and the // native array it represents. enum RelationToSource { kReference, // The NativeArray references the native array. kCopy // The NativeArray makes a copy of the native array and // owns the copy. }; // Adapts a native array to a read-only STL-style container. Instead // of the complete STL container concept, this adaptor only implements // members useful for Google Mock's container matchers. New members // should be added as needed. To simplify the implementation, we only // support Element being a raw type (i.e. having no top-level const or // reference modifier). It's the client's responsibility to satisfy // this requirement. Element can be an array type itself (hence // multi-dimensional arrays are supported). template class NativeArray { public: // STL-style container typedefs. typedef Element value_type; typedef Element* iterator; typedef const Element* const_iterator; // Constructs from a native array. NativeArray(const Element* array, size_t count, RelationToSource relation) { Init(array, count, relation); } // Copy constructor. NativeArray(const NativeArray& rhs) { Init(rhs.array_, rhs.size_, rhs.relation_to_source_); } ~NativeArray() { // Ensures that the user doesn't instantiate NativeArray with a // const or reference type. static_cast(StaticAssertTypeEqHelper()); if (relation_to_source_ == kCopy) delete[] array_; } // STL-style container methods. size_t size() const { return size_; } const_iterator begin() const { return array_; } const_iterator end() const { return array_ + size_; } bool operator==(const NativeArray& rhs) const { return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin()); } private: // Initializes this object; makes a copy of the input array if // 'relation' is kCopy. void Init(const Element* array, size_t a_size, RelationToSource relation) { if (relation == kReference) { array_ = array; } else { Element* const copy = new Element[a_size]; CopyArray(array, a_size, copy); array_ = copy; } size_ = a_size; relation_to_source_ = relation; } const Element* array_; size_t size_; RelationToSource relation_to_source_; GTEST_DISALLOW_ASSIGN_(NativeArray); }; } // namespace internal } // namespace testing #define GTEST_MESSAGE_AT_(file, line, message, result_type) \ ::testing::internal::AssertHelper(result_type, file, line, message) \ = ::testing::Message() #define GTEST_MESSAGE_(message, result_type) \ GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) #define GTEST_FATAL_FAILURE_(message) \ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) #define GTEST_NONFATAL_FAILURE_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) #define GTEST_SUCCESS_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) // Suppresses MSVC warnings 4072 (unreachable code) for the code following // statement if it returns or throws (or doesn't return or throw in some // situations). #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ if (::testing::internal::AlwaysTrue()) { statement; } #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::ConstCharPtr gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ } \ catch (...) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws a different type."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ if (!gtest_caught_expected) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws nothing."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ fail(gtest_msg.value) #define GTEST_TEST_NO_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ fail("Expected: " #statement " doesn't throw an exception.\n" \ " Actual: it throws.") #define GTEST_TEST_ANY_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ bool gtest_caught_any = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ } \ if (!gtest_caught_any) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ fail("Expected: " #statement " throws an exception.\n" \ " Actual: it doesn't.") // Implements Boolean test assertions such as EXPECT_TRUE. expression can be // either a boolean expression or an AssertionResult. text is a textual // represenation of expression as it was passed into the EXPECT_TRUE. #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar_ = \ ::testing::AssertionResult(expression)) \ ; \ else \ fail(::testing::internal::GetBoolAssertionFailureMessage(\ gtest_ar_, text, #actual, #expected).c_str()) #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ fail("Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ " Actual: it does.") // Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ test_case_name##_##test_name##_Test // Helper macro for defining tests. #define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ public:\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ private:\ virtual void TestBody();\ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ };\ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ ::test_info_ =\ ::testing::internal::MakeAndRegisterTestInfo(\ #test_case_name, #test_name, NULL, NULL, \ (parent_id), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ new ::testing::internal::TestFactoryImpl<\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-death-test-internal.h0000664000175000017500000003216514750344764023426 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file defines internal utilities needed for implementing // death tests. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #include "gtest/internal/gtest-internal.h" #include namespace testing { namespace internal { GTEST_DECLARE_string_(internal_run_death_test); // Names of the flags (needed for parsing Google Test flags). const char kDeathTestStyleFlag[] = "death_test_style"; const char kDeathTestUseFork[] = "death_test_use_fork"; const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; #if GTEST_HAS_DEATH_TEST // DeathTest is a class that hides much of the complexity of the // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method // returns a concrete class that depends on the prevailing death test // style, as defined by the --gtest_death_test_style and/or // --gtest_internal_run_death_test flags. // In describing the results of death tests, these terms are used with // the corresponding definitions: // // exit status: The integer exit information in the format specified // by wait(2) // exit code: The integer code passed to exit(3), _exit(2), or // returned from main() class GTEST_API_ DeathTest { public: // Create returns false if there was an error determining the // appropriate action to take for the current death test; for example, // if the gtest_death_test_style flag is set to an invalid value. // The LastMessage method will return a more detailed message in that // case. Otherwise, the DeathTest pointer pointed to by the "test" // argument is set. If the death test should be skipped, the pointer // is set to NULL; otherwise, it is set to the address of a new concrete // DeathTest object that controls the execution of the current test. static bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); DeathTest(); virtual ~DeathTest() { } // A helper class that aborts a death test when it's deleted. class ReturnSentinel { public: explicit ReturnSentinel(DeathTest* test) : test_(test) { } ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } private: DeathTest* const test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); } GTEST_ATTRIBUTE_UNUSED_; // An enumeration of possible roles that may be taken when a death // test is encountered. EXECUTE means that the death test logic should // be executed immediately. OVERSEE means that the program should prepare // the appropriate environment for a child process to execute the death // test, then wait for it to complete. enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; // An enumeration of the three reasons that a test might be aborted. enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_THREW_EXCEPTION, TEST_DID_NOT_DIE }; // Assumes one of the above roles. virtual TestRole AssumeRole() = 0; // Waits for the death test to finish and returns its status. virtual int Wait() = 0; // Returns true if the death test passed; that is, the test process // exited during the test, its exit status matches a user-supplied // predicate, and its stderr output matches a user-supplied regular // expression. // The user-supplied predicate may be a macro expression rather // than a function pointer or functor, or else Wait and Passed could // be combined. virtual bool Passed(bool exit_status_ok) = 0; // Signals that the death test did not die as expected. virtual void Abort(AbortReason reason) = 0; // Returns a human-readable outcome message regarding the outcome of // the last death test. static const char* LastMessage(); static void set_last_death_test_message(const std::string& message); private: // A string containing a description of the outcome of the last death test. static std::string last_death_test_message_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); }; // Factory interface for death tests. May be mocked out for testing. class DeathTestFactory { public: virtual ~DeathTestFactory() { } virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) = 0; }; // A concrete DeathTestFactory implementation for normal use. class DefaultDeathTestFactory : public DeathTestFactory { public: virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); }; // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // Traps C++ exceptions escaping statement and reports them as test // failures. Note that trapping SEH exceptions is not implemented here. # if GTEST_HAS_EXCEPTIONS # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } catch (const ::std::exception& gtest_exception) { \ fprintf(\ stderr, \ "\n%s: Caught std::exception-derived exception escaping the " \ "death test statement. Exception message: %s\n", \ ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ gtest_exception.what()); \ fflush(stderr); \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } catch (...) { \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } # else # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) # endif // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. # define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ const ::testing::internal::RE& gtest_regex = (regex); \ ::testing::internal::DeathTest* gtest_dt; \ if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ __FILE__, __LINE__, >est_dt)) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ if (gtest_dt != NULL) { \ ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ gtest_dt_ptr(gtest_dt); \ switch (gtest_dt->AssumeRole()) { \ case ::testing::internal::DeathTest::OVERSEE_TEST: \ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ break; \ case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ default: \ break; \ } \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ fail(::testing::internal::DeathTest::LastMessage()) // The symbol "fail" here expands to something into which a message // can be streamed. // This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in // NDEBUG mode. In this case we need the statements to be executed, the regex is // ignored, and the macro must accept a streamed message even though the message // is never printed. # define GTEST_EXECUTE_STATEMENT_(statement, regex) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } else \ ::testing::Message() // A class representing the parsed contents of the // --gtest_internal_run_death_test flag, as it existed when // RUN_ALL_TESTS was called. class InternalRunDeathTestFlag { public: InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, int a_write_fd) : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} ~InternalRunDeathTestFlag() { if (write_fd_ >= 0) posix::Close(write_fd_); } const std::string& file() const { return file_; } int line() const { return line_; } int index() const { return index_; } int write_fd() const { return write_fd_; } private: std::string file_; int line_; int index_; int write_fd_; GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); }; // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); #else // GTEST_HAS_DEATH_TEST // This macro is used for implementing macros such as // EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where // death tests are not supported. Those macros must compile on such systems // iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on // systems that support death tests. This allows one to write such a macro // on a system that does not support death tests and be sure that it will // compile on a death-test supporting system. // // Parameters: // statement - A statement that a macro such as EXPECT_DEATH would test // for program termination. This macro has to make sure this // statement is compiled but not executed, to ensure that // EXPECT_DEATH_IF_SUPPORTED compiles with a certain // parameter iff EXPECT_DEATH compiles with it. // regex - A regex that a macro such as EXPECT_DEATH would use to test // the output of statement. This parameter has to be // compiled but not evaluated by this macro, to ensure that // this macro only accepts expressions that a macro such as // EXPECT_DEATH would accept. // terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED // and a return statement for ASSERT_DEATH_IF_SUPPORTED. // This ensures that ASSERT_DEATH_IF_SUPPORTED will not // compile inside functions where ASSERT_DEATH doesn't // compile. // // The branch that has an always false condition is used to ensure that // statement and regex are compiled (and thus syntactically correct) but // never executed. The unreachable code macro protects the terminator // statement from generating an 'unreachable code' warning in case // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. # define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_LOG_(WARNING) \ << "Death tests are not supported on this platform.\n" \ << "Statement '" #statement "' cannot be verified."; \ } else if (::testing::internal::AlwaysFalse()) { \ ::testing::internal::RE::PartialMatch(".*", (regex)); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ terminator; \ } else \ ::testing::Message() #endif // GTEST_HAS_DEATH_TEST } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-linked_ptr.h0000664000175000017500000001764514750344764021713 // Copyright 2003 Google Inc. // 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 Google Inc. 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. // // Authors: Dan Egnor (egnor@google.com) // // A "smart" pointer type with reference tracking. Every pointer to a // particular object is kept on a circular linked list. When the last pointer // to an object is destroyed or reassigned, the object is deleted. // // Used properly, this deletes the object when the last reference goes away. // There are several caveats: // - Like all reference counting schemes, cycles lead to leaks. // - Each smart pointer is actually two pointers (8 bytes instead of 4). // - Every time a pointer is assigned, the entire list of pointers to that // object is traversed. This class is therefore NOT SUITABLE when there // will often be more than two or three pointers to a particular object. // - References are only tracked as long as linked_ptr<> objects are copied. // If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS // will happen (double deletion). // // A good use of this class is storing object references in STL containers. // You can safely put linked_ptr<> in a vector<>. // Other uses may not be as good. // // Note: If you use an incomplete type with linked_ptr<>, the class // *containing* linked_ptr<> must have a constructor and destructor (even // if they do nothing!). // // Bill Gibbons suggested we use something like this. // // Thread Safety: // Unlike other linked_ptr implementations, in this implementation // a linked_ptr object is thread-safe in the sense that: // - it's safe to copy linked_ptr objects concurrently, // - it's safe to copy *from* a linked_ptr and read its underlying // raw pointer (e.g. via get()) concurrently, and // - it's safe to write to two linked_ptrs that point to the same // shared object concurrently. // TODO(wan@google.com): rename this to safe_linked_ptr to avoid // confusion with normal linked_ptr. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #include #include #include "gtest/internal/gtest-port.h" namespace testing { namespace internal { // Protects copying of all linked_ptr objects. GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); // This is used internally by all instances of linked_ptr<>. It needs to be // a non-template class because different types of linked_ptr<> can refer to // the same object (linked_ptr(obj) vs linked_ptr(obj)). // So, it needs to be possible for different types of linked_ptr to participate // in the same circular linked list, so we need a single class type here. // // DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. class linked_ptr_internal { public: // Create a new circle that includes only this instance. void join_new() { next_ = this; } // Many linked_ptr operations may change p.link_ for some linked_ptr // variable p in the same circle as this object. Therefore we need // to prevent two such operations from occurring concurrently. // // Note that different types of linked_ptr objects can coexist in a // circle (e.g. linked_ptr, linked_ptr, and // linked_ptr). Therefore we must use a single mutex to // protect all linked_ptr objects. This can create serious // contention in production code, but is acceptable in a testing // framework. // Join an existing circle. void join(linked_ptr_internal const* ptr) GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); linked_ptr_internal const* p = ptr; while (p->next_ != ptr) p = p->next_; p->next_ = this; next_ = ptr; } // Leave whatever circle we're part of. Returns true if we were the // last member of the circle. Once this is done, you can join() another. bool depart() GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); if (next_ == this) return true; linked_ptr_internal const* p = next_; while (p->next_ != this) p = p->next_; p->next_ = next_; return false; } private: mutable linked_ptr_internal const* next_; }; template class linked_ptr { public: typedef T element_type; // Take over ownership of a raw pointer. This should happen as soon as // possible after the object is created. explicit linked_ptr(T* ptr = NULL) { capture(ptr); } ~linked_ptr() { depart(); } // Copy an existing linked_ptr<>, adding ourselves to the list of references. template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } linked_ptr(linked_ptr const& ptr) { // NOLINT assert(&ptr != this); copy(&ptr); } // Assignment releases the old value and acquires the new. template linked_ptr& operator=(linked_ptr const& ptr) { depart(); copy(&ptr); return *this; } linked_ptr& operator=(linked_ptr const& ptr) { if (&ptr != this) { depart(); copy(&ptr); } return *this; } // Smart pointer members. void reset(T* ptr = NULL) { depart(); capture(ptr); } T* get() const { return value_; } T* operator->() const { return value_; } T& operator*() const { return *value_; } bool operator==(T* p) const { return value_ == p; } bool operator!=(T* p) const { return value_ != p; } template bool operator==(linked_ptr const& ptr) const { return value_ == ptr.get(); } template bool operator!=(linked_ptr const& ptr) const { return value_ != ptr.get(); } private: template friend class linked_ptr; T* value_; linked_ptr_internal link_; void depart() { if (link_.depart()) delete value_; } void capture(T* ptr) { value_ = ptr; link_.join_new(); } template void copy(linked_ptr const* ptr) { value_ = ptr->get(); if (value_) link_.join(&ptr->link_); else link_.join_new(); } }; template inline bool operator==(T* ptr, const linked_ptr& x) { return ptr == x.get(); } template inline bool operator!=(T* ptr, const linked_ptr& x) { return ptr != x.get(); } // A function to convert T* into linked_ptr // Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation // for linked_ptr >(new FooBarBaz(arg)) template linked_ptr make_linked_ptr(T* ptr) { return linked_ptr(ptr); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-type-util.h0000664000175000017500000055250214750344764021510 // This file was GENERATED by command: // pump.py gtest-type-util.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // Type utilities needed for implementing typed and type-parameterized // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently we support at most 50 types in a list, and at most 50 // type-parameterized tests in one type-parameterized test case. // Please contact googletestframework@googlegroups.com if you need // more. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #include "gtest/internal/gtest-port.h" // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). # if GTEST_HAS_CXXABI_H_ # include # elif defined(__HP_aCC) # include # endif // GTEST_HASH_CXXABI_H_ namespace testing { namespace internal { // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of // the typed-test-only section below. template std::string GetTypeName() { # if GTEST_HAS_RTTI const char* const name = typeid(T).name(); # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. # if GTEST_HAS_CXXABI_H_ using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); const std::string name_str(status == 0 ? readable_name : name); free(readable_name); return name_str; # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC # else return ""; # endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // AssertyTypeEq::type is defined iff T1 and T2 are the same // type. This can be used as a compile-time assertion to ensure that // two types are equal. template struct AssertTypeEq; template struct AssertTypeEq { typedef bool type; }; // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't // support directly. struct None {}; // The following family of struct and struct templates are used to // represent type lists. In particular, TypesN // represents a type list with N types (T1, T2, ..., and TN) in it. // Except for Types0, every struct in the family has two member types: // Head for the first type in the list, and Tail for the rest of the // list. // The empty type list. struct Types0 {}; // Type lists of length 1, 2, 3, and so on. template struct Types1 { typedef T1 Head; typedef Types0 Tail; }; template struct Types2 { typedef T1 Head; typedef Types1 Tail; }; template struct Types3 { typedef T1 Head; typedef Types2 Tail; }; template struct Types4 { typedef T1 Head; typedef Types3 Tail; }; template struct Types5 { typedef T1 Head; typedef Types4 Tail; }; template struct Types6 { typedef T1 Head; typedef Types5 Tail; }; template struct Types7 { typedef T1 Head; typedef Types6 Tail; }; template struct Types8 { typedef T1 Head; typedef Types7 Tail; }; template struct Types9 { typedef T1 Head; typedef Types8 Tail; }; template struct Types10 { typedef T1 Head; typedef Types9 Tail; }; template struct Types11 { typedef T1 Head; typedef Types10 Tail; }; template struct Types12 { typedef T1 Head; typedef Types11 Tail; }; template struct Types13 { typedef T1 Head; typedef Types12 Tail; }; template struct Types14 { typedef T1 Head; typedef Types13 Tail; }; template struct Types15 { typedef T1 Head; typedef Types14 Tail; }; template struct Types16 { typedef T1 Head; typedef Types15 Tail; }; template struct Types17 { typedef T1 Head; typedef Types16 Tail; }; template struct Types18 { typedef T1 Head; typedef Types17 Tail; }; template struct Types19 { typedef T1 Head; typedef Types18 Tail; }; template struct Types20 { typedef T1 Head; typedef Types19 Tail; }; template struct Types21 { typedef T1 Head; typedef Types20 Tail; }; template struct Types22 { typedef T1 Head; typedef Types21 Tail; }; template struct Types23 { typedef T1 Head; typedef Types22 Tail; }; template struct Types24 { typedef T1 Head; typedef Types23 Tail; }; template struct Types25 { typedef T1 Head; typedef Types24 Tail; }; template struct Types26 { typedef T1 Head; typedef Types25 Tail; }; template struct Types27 { typedef T1 Head; typedef Types26 Tail; }; template struct Types28 { typedef T1 Head; typedef Types27 Tail; }; template struct Types29 { typedef T1 Head; typedef Types28 Tail; }; template struct Types30 { typedef T1 Head; typedef Types29 Tail; }; template struct Types31 { typedef T1 Head; typedef Types30 Tail; }; template struct Types32 { typedef T1 Head; typedef Types31 Tail; }; template struct Types33 { typedef T1 Head; typedef Types32 Tail; }; template struct Types34 { typedef T1 Head; typedef Types33 Tail; }; template struct Types35 { typedef T1 Head; typedef Types34 Tail; }; template struct Types36 { typedef T1 Head; typedef Types35 Tail; }; template struct Types37 { typedef T1 Head; typedef Types36 Tail; }; template struct Types38 { typedef T1 Head; typedef Types37 Tail; }; template struct Types39 { typedef T1 Head; typedef Types38 Tail; }; template struct Types40 { typedef T1 Head; typedef Types39 Tail; }; template struct Types41 { typedef T1 Head; typedef Types40 Tail; }; template struct Types42 { typedef T1 Head; typedef Types41 Tail; }; template struct Types43 { typedef T1 Head; typedef Types42 Tail; }; template struct Types44 { typedef T1 Head; typedef Types43 Tail; }; template struct Types45 { typedef T1 Head; typedef Types44 Tail; }; template struct Types46 { typedef T1 Head; typedef Types45 Tail; }; template struct Types47 { typedef T1 Head; typedef Types46 Tail; }; template struct Types48 { typedef T1 Head; typedef Types47 Tail; }; template struct Types49 { typedef T1 Head; typedef Types48 Tail; }; template struct Types50 { typedef T1 Head; typedef Types49 Tail; }; } // namespace internal // We don't want to require the users to write TypesN<...> directly, // as that would require them to count the length. Types<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Types // will appear as Types in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Types, and Google Test will translate // that to TypesN internally to make error messages // readable. The translation is done by the 'type' member of the // Types template. template struct Types { typedef internal::Types50 type; }; template <> struct Types { typedef internal::Types0 type; }; template struct Types { typedef internal::Types1 type; }; template struct Types { typedef internal::Types2 type; }; template struct Types { typedef internal::Types3 type; }; template struct Types { typedef internal::Types4 type; }; template struct Types { typedef internal::Types5 type; }; template struct Types { typedef internal::Types6 type; }; template struct Types { typedef internal::Types7 type; }; template struct Types { typedef internal::Types8 type; }; template struct Types { typedef internal::Types9 type; }; template struct Types { typedef internal::Types10 type; }; template struct Types { typedef internal::Types11 type; }; template struct Types { typedef internal::Types12 type; }; template struct Types { typedef internal::Types13 type; }; template struct Types { typedef internal::Types14 type; }; template struct Types { typedef internal::Types15 type; }; template struct Types { typedef internal::Types16 type; }; template struct Types { typedef internal::Types17 type; }; template struct Types { typedef internal::Types18 type; }; template struct Types { typedef internal::Types19 type; }; template struct Types { typedef internal::Types20 type; }; template struct Types { typedef internal::Types21 type; }; template struct Types { typedef internal::Types22 type; }; template struct Types { typedef internal::Types23 type; }; template struct Types { typedef internal::Types24 type; }; template struct Types { typedef internal::Types25 type; }; template struct Types { typedef internal::Types26 type; }; template struct Types { typedef internal::Types27 type; }; template struct Types { typedef internal::Types28 type; }; template struct Types { typedef internal::Types29 type; }; template struct Types { typedef internal::Types30 type; }; template struct Types { typedef internal::Types31 type; }; template struct Types { typedef internal::Types32 type; }; template struct Types { typedef internal::Types33 type; }; template struct Types { typedef internal::Types34 type; }; template struct Types { typedef internal::Types35 type; }; template struct Types { typedef internal::Types36 type; }; template struct Types { typedef internal::Types37 type; }; template struct Types { typedef internal::Types38 type; }; template struct Types { typedef internal::Types39 type; }; template struct Types { typedef internal::Types40 type; }; template struct Types { typedef internal::Types41 type; }; template struct Types { typedef internal::Types42 type; }; template struct Types { typedef internal::Types43 type; }; template struct Types { typedef internal::Types44 type; }; template struct Types { typedef internal::Types45 type; }; template struct Types { typedef internal::Types46 type; }; template struct Types { typedef internal::Types47 type; }; template struct Types { typedef internal::Types48 type; }; template struct Types { typedef internal::Types49 type; }; namespace internal { # define GTEST_TEMPLATE_ template class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type // parameter, as a type. TemplateSel::Bind::type is defined // as the type Tmpl. This allows us to actually instantiate the // template "selected" by TemplateSel. // // This trick is necessary for simulating typedef for class templates, // which C++ doesn't support directly. template struct TemplateSel { template struct Bind { typedef Tmpl type; }; }; # define GTEST_BIND_(TmplSel, T) \ TmplSel::template Bind::type // A unique struct template used as the default value for the // arguments of class template Templates. This allows us to simulate // variadic templates (e.g. Templates, Templates, // and etc), which C++ doesn't support directly. template struct NoneT {}; // The following family of struct and struct templates are used to // represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except // for Templates0, every struct in the family has two member types: // Head for the selector of the first template in the list, and Tail // for the rest of the list. // The empty template list. struct Templates0 {}; // Template lists of length 1, 2, 3, and so on. template struct Templates1 { typedef TemplateSel Head; typedef Templates0 Tail; }; template struct Templates2 { typedef TemplateSel Head; typedef Templates1 Tail; }; template struct Templates3 { typedef TemplateSel Head; typedef Templates2 Tail; }; template struct Templates4 { typedef TemplateSel Head; typedef Templates3 Tail; }; template struct Templates5 { typedef TemplateSel Head; typedef Templates4 Tail; }; template struct Templates6 { typedef TemplateSel Head; typedef Templates5 Tail; }; template struct Templates7 { typedef TemplateSel Head; typedef Templates6 Tail; }; template struct Templates8 { typedef TemplateSel Head; typedef Templates7 Tail; }; template struct Templates9 { typedef TemplateSel Head; typedef Templates8 Tail; }; template struct Templates10 { typedef TemplateSel Head; typedef Templates9 Tail; }; template struct Templates11 { typedef TemplateSel Head; typedef Templates10 Tail; }; template struct Templates12 { typedef TemplateSel Head; typedef Templates11 Tail; }; template struct Templates13 { typedef TemplateSel Head; typedef Templates12 Tail; }; template struct Templates14 { typedef TemplateSel Head; typedef Templates13 Tail; }; template struct Templates15 { typedef TemplateSel Head; typedef Templates14 Tail; }; template struct Templates16 { typedef TemplateSel Head; typedef Templates15 Tail; }; template struct Templates17 { typedef TemplateSel Head; typedef Templates16 Tail; }; template struct Templates18 { typedef TemplateSel Head; typedef Templates17 Tail; }; template struct Templates19 { typedef TemplateSel Head; typedef Templates18 Tail; }; template struct Templates20 { typedef TemplateSel Head; typedef Templates19 Tail; }; template struct Templates21 { typedef TemplateSel Head; typedef Templates20 Tail; }; template struct Templates22 { typedef TemplateSel Head; typedef Templates21 Tail; }; template struct Templates23 { typedef TemplateSel Head; typedef Templates22 Tail; }; template struct Templates24 { typedef TemplateSel Head; typedef Templates23 Tail; }; template struct Templates25 { typedef TemplateSel Head; typedef Templates24 Tail; }; template struct Templates26 { typedef TemplateSel Head; typedef Templates25 Tail; }; template struct Templates27 { typedef TemplateSel Head; typedef Templates26 Tail; }; template struct Templates28 { typedef TemplateSel Head; typedef Templates27 Tail; }; template struct Templates29 { typedef TemplateSel Head; typedef Templates28 Tail; }; template struct Templates30 { typedef TemplateSel Head; typedef Templates29 Tail; }; template struct Templates31 { typedef TemplateSel Head; typedef Templates30 Tail; }; template struct Templates32 { typedef TemplateSel Head; typedef Templates31 Tail; }; template struct Templates33 { typedef TemplateSel Head; typedef Templates32 Tail; }; template struct Templates34 { typedef TemplateSel Head; typedef Templates33 Tail; }; template struct Templates35 { typedef TemplateSel Head; typedef Templates34 Tail; }; template struct Templates36 { typedef TemplateSel Head; typedef Templates35 Tail; }; template struct Templates37 { typedef TemplateSel Head; typedef Templates36 Tail; }; template struct Templates38 { typedef TemplateSel Head; typedef Templates37 Tail; }; template struct Templates39 { typedef TemplateSel Head; typedef Templates38 Tail; }; template struct Templates40 { typedef TemplateSel Head; typedef Templates39 Tail; }; template struct Templates41 { typedef TemplateSel Head; typedef Templates40 Tail; }; template struct Templates42 { typedef TemplateSel Head; typedef Templates41 Tail; }; template struct Templates43 { typedef TemplateSel Head; typedef Templates42 Tail; }; template struct Templates44 { typedef TemplateSel Head; typedef Templates43 Tail; }; template struct Templates45 { typedef TemplateSel Head; typedef Templates44 Tail; }; template struct Templates46 { typedef TemplateSel Head; typedef Templates45 Tail; }; template struct Templates47 { typedef TemplateSel Head; typedef Templates46 Tail; }; template struct Templates48 { typedef TemplateSel Head; typedef Templates47 Tail; }; template struct Templates49 { typedef TemplateSel Head; typedef Templates48 Tail; }; template struct Templates50 { typedef TemplateSel Head; typedef Templates49 Tail; }; // We don't want to require the users to write TemplatesN<...> directly, // as that would require them to count the length. Templates<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Templates // will appear as Templates in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Templates, and Google Test will translate // that to TemplatesN internally to make error messages // readable. The translation is done by the 'type' member of the // Templates template. template struct Templates { typedef Templates50 type; }; template <> struct Templates { typedef Templates0 type; }; template struct Templates { typedef Templates1 type; }; template struct Templates { typedef Templates2 type; }; template struct Templates { typedef Templates3 type; }; template struct Templates { typedef Templates4 type; }; template struct Templates { typedef Templates5 type; }; template struct Templates { typedef Templates6 type; }; template struct Templates { typedef Templates7 type; }; template struct Templates { typedef Templates8 type; }; template struct Templates { typedef Templates9 type; }; template struct Templates { typedef Templates10 type; }; template struct Templates { typedef Templates11 type; }; template struct Templates { typedef Templates12 type; }; template struct Templates { typedef Templates13 type; }; template struct Templates { typedef Templates14 type; }; template struct Templates { typedef Templates15 type; }; template struct Templates { typedef Templates16 type; }; template struct Templates { typedef Templates17 type; }; template struct Templates { typedef Templates18 type; }; template struct Templates { typedef Templates19 type; }; template struct Templates { typedef Templates20 type; }; template struct Templates { typedef Templates21 type; }; template struct Templates { typedef Templates22 type; }; template struct Templates { typedef Templates23 type; }; template struct Templates { typedef Templates24 type; }; template struct Templates { typedef Templates25 type; }; template struct Templates { typedef Templates26 type; }; template struct Templates { typedef Templates27 type; }; template struct Templates { typedef Templates28 type; }; template struct Templates { typedef Templates29 type; }; template struct Templates { typedef Templates30 type; }; template struct Templates { typedef Templates31 type; }; template struct Templates { typedef Templates32 type; }; template struct Templates { typedef Templates33 type; }; template struct Templates { typedef Templates34 type; }; template struct Templates { typedef Templates35 type; }; template struct Templates { typedef Templates36 type; }; template struct Templates { typedef Templates37 type; }; template struct Templates { typedef Templates38 type; }; template struct Templates { typedef Templates39 type; }; template struct Templates { typedef Templates40 type; }; template struct Templates { typedef Templates41 type; }; template struct Templates { typedef Templates42 type; }; template struct Templates { typedef Templates43 type; }; template struct Templates { typedef Templates44 type; }; template struct Templates { typedef Templates45 type; }; template struct Templates { typedef Templates46 type; }; template struct Templates { typedef Templates47 type; }; template struct Templates { typedef Templates48 type; }; template struct Templates { typedef Templates49 type; }; // The TypeList template makes it possible to use either a single type // or a Types<...> list in TYPED_TEST_CASE() and // INSTANTIATE_TYPED_TEST_CASE_P(). template struct TypeList { typedef Types1 type; }; template struct TypeList > { typedef typename Types::type type; }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-param-util.h0000664000175000017500000005717714750344764021637 // Copyright 2008 Google Inc. // 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 Google Inc. 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. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #include #include #include // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-linked_ptr.h" #include "gtest/internal/gtest-port.h" #include "gtest/gtest-printers.h" #if GTEST_HAS_PARAM_TEST namespace testing { namespace internal { // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Outputs a message explaining invalid registration of different // fixture class for the same test case. This may happen when // TEST_P macro is used to define two tests with the same name // but in different namespaces. GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line); template class ParamGeneratorInterface; template class ParamGenerator; // Interface for iterating over elements provided by an implementation // of ParamGeneratorInterface. template class ParamIteratorInterface { public: virtual ~ParamIteratorInterface() {} // A pointer to the base generator instance. // Used only for the purposes of iterator comparison // to make sure that two iterators belong to the same generator. virtual const ParamGeneratorInterface* BaseGenerator() const = 0; // Advances iterator to point to the next element // provided by the generator. The caller is responsible // for not calling Advance() on an iterator equal to // BaseGenerator()->End(). virtual void Advance() = 0; // Clones the iterator object. Used for implementing copy semantics // of ParamIterator. virtual ParamIteratorInterface* Clone() const = 0; // Dereferences the current iterator and provides (read-only) access // to the pointed value. It is the caller's responsibility not to call // Current() on an iterator equal to BaseGenerator()->End(). // Used for implementing ParamGenerator::operator*(). virtual const T* Current() const = 0; // Determines whether the given iterator and other point to the same // element in the sequence generated by the generator. // Used for implementing ParamGenerator::operator==(). virtual bool Equals(const ParamIteratorInterface& other) const = 0; }; // Class iterating over elements provided by an implementation of // ParamGeneratorInterface. It wraps ParamIteratorInterface // and implements the const forward iterator concept. template class ParamIterator { public: typedef T value_type; typedef const T& reference; typedef ptrdiff_t difference_type; // ParamIterator assumes ownership of the impl_ pointer. ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} ParamIterator& operator=(const ParamIterator& other) { if (this != &other) impl_.reset(other.impl_->Clone()); return *this; } const T& operator*() const { return *impl_->Current(); } const T* operator->() const { return impl_->Current(); } // Prefix version of operator++. ParamIterator& operator++() { impl_->Advance(); return *this; } // Postfix version of operator++. ParamIterator operator++(int /*unused*/) { ParamIteratorInterface* clone = impl_->Clone(); impl_->Advance(); return ParamIterator(clone); } bool operator==(const ParamIterator& other) const { return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); } bool operator!=(const ParamIterator& other) const { return !(*this == other); } private: friend class ParamGenerator; explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} scoped_ptr > impl_; }; // ParamGeneratorInterface is the binary interface to access generators // defined in other translation units. template class ParamGeneratorInterface { public: typedef T ParamType; virtual ~ParamGeneratorInterface() {} // Generator interface definition virtual ParamIteratorInterface* Begin() const = 0; virtual ParamIteratorInterface* End() const = 0; }; // Wraps ParamGeneratorInterface and provides general generator syntax // compatible with the STL Container concept. // This class implements copy initialization semantics and the contained // ParamGeneratorInterface instance is shared among all copies // of the original object. This is possible because that instance is immutable. template class ParamGenerator { public: typedef ParamIterator iterator; explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} ParamGenerator& operator=(const ParamGenerator& other) { impl_ = other.impl_; return *this; } iterator begin() const { return iterator(impl_->Begin()); } iterator end() const { return iterator(impl_->End()); } private: linked_ptr > impl_; }; // Generates values from a range of two comparable values. Can be used to // generate sequences of user-defined types that implement operator+() and // operator<(). // This class is used in the Range() function. template class RangeGenerator : public ParamGeneratorInterface { public: RangeGenerator(T begin, T end, IncrementT step) : begin_(begin), end_(end), step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} virtual ~RangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, begin_, 0, step_); } virtual ParamIteratorInterface* End() const { return new Iterator(this, end_, end_index_, step_); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, T value, int index, IncrementT step) : base_(base), value_(value), index_(index), step_(step) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { value_ = value_ + step_; index_++; } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const T* Current() const { return &value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const int other_index = CheckedDowncastToActualType(&other)->index_; return index_ == other_index; } private: Iterator(const Iterator& other) : ParamIteratorInterface(), base_(other.base_), value_(other.value_), index_(other.index_), step_(other.step_) {} // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; T value_; int index_; const IncrementT step_; }; // class RangeGenerator::Iterator static int CalculateEndIndex(const T& begin, const T& end, const IncrementT& step) { int end_index = 0; for (T i = begin; i < end; i = i + step) end_index++; return end_index; } // No implementation - assignment is unsupported. void operator=(const RangeGenerator& other); const T begin_; const T end_; const IncrementT step_; // The index for the end() iterator. All the elements in the generated // sequence are indexed (0-based) to aid iterator comparison. const int end_index_; }; // class RangeGenerator // Generates values from a pair of STL-style iterators. Used in the // ValuesIn() function. The elements are copied from the source range // since the source can be located on the stack, and the generator // is likely to persist beyond that stack frame. template class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { public: template ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) : container_(begin, end) {} virtual ~ValuesInIteratorRangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, container_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, container_.end()); } private: typedef typename ::std::vector ContainerType; class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, typename ContainerType::const_iterator iterator) : base_(base), iterator_(iterator) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { ++iterator_; value_.reset(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } // We need to use cached value referenced by iterator_ because *iterator_ // can return a temporary object (and of type other then T), so just // having "return &*iterator_;" doesn't work. // value_ is updated here and not in Advance() because Advance() // can advance iterator_ beyond the end of the range, and we cannot // detect that fact. The client code, on the other hand, is // responsible for not calling Current() on an out-of-range iterator. virtual const T* Current() const { if (value_.get() == NULL) value_.reset(new T(*iterator_)); return value_.get(); } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; return iterator_ == CheckedDowncastToActualType(&other)->iterator_; } private: Iterator(const Iterator& other) // The explicit constructor call suppresses a false warning // emitted by gcc when supplied with the -Wextra option. : ParamIteratorInterface(), base_(other.base_), iterator_(other.iterator_) {} const ParamGeneratorInterface* const base_; typename ContainerType::const_iterator iterator_; // A cached value of *iterator_. We keep it here to allow access by // pointer in the wrapping iterator's operator->(). // value_ needs to be mutable to be accessed in Current(). // Use of scoped_ptr helps manage cached value's lifetime, // which is bound by the lifespan of the iterator itself. mutable scoped_ptr value_; }; // class ValuesInIteratorRangeGenerator::Iterator // No implementation - assignment is unsupported. void operator=(const ValuesInIteratorRangeGenerator& other); const ContainerType container_; }; // class ValuesInIteratorRangeGenerator // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Stores a parameter value and later creates tests parameterized with that // value. template class ParameterizedTestFactory : public TestFactoryBase { public: typedef typename TestClass::ParamType ParamType; explicit ParameterizedTestFactory(ParamType parameter) : parameter_(parameter) {} virtual Test* CreateTest() { TestClass::SetParam(¶meter_); return new TestClass(); } private: const ParamType parameter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactoryBase is a base class for meta-factories that create // test factories for passing into MakeAndRegisterTestInfo function. template class TestMetaFactoryBase { public: virtual ~TestMetaFactoryBase() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactory creates test factories for passing into // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives // ownership of test factory pointer, same factory object cannot be passed // into that method twice. But ParameterizedTestCaseInfo is going to call // it for each Test/Parameter value combination. Thus it needs meta factory // creator class. template class TestMetaFactory : public TestMetaFactoryBase { public: typedef typename TestCase::ParamType ParamType; TestMetaFactory() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { return new ParameterizedTestFactory(parameter); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfoBase is a generic interface // to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase // accumulates test information provided by TEST_P macro invocations // and generators provided by INSTANTIATE_TEST_CASE_P macro invocations // and uses that information to register all resulting test instances // in RegisterTests method. The ParameterizeTestCaseRegistry class holds // a collection of pointers to the ParameterizedTestCaseInfo objects // and calls RegisterTests() on each of them when asked. class ParameterizedTestCaseInfoBase { public: virtual ~ParameterizedTestCaseInfoBase() {} // Base part of test case name for display purposes. virtual const string& GetTestCaseName() const = 0; // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const = 0; // UnitTest class invokes this method to register tests in this // test case right before running them in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. virtual void RegisterTests() = 0; protected: ParameterizedTestCaseInfoBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfo accumulates tests obtained from TEST_P // macro invocations for a particular test case and generators // obtained from INSTANTIATE_TEST_CASE_P macro invocations for that // test case. It registers tests with all values generated by all // generators when asked. template class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { public: // ParamType and GeneratorCreationFunc are private types but are required // for declarations of public methods AddTestPattern() and // AddTestCaseInstantiation(). typedef typename TestCase::ParamType ParamType; // A function that returns an instance of appropriate generator type. typedef ParamGenerator(GeneratorCreationFunc)(); explicit ParameterizedTestCaseInfo(const char* name) : test_case_name_(name) {} // Test case base name for display purposes. virtual const string& GetTestCaseName() const { return test_case_name_; } // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } // TEST_P macro uses AddTestPattern() to record information // about a single test in a LocalTestInfo structure. // test_case_name is the base name of the test case (without invocation // prefix). test_base_name is the name of an individual test without // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // test case base name and DoBar is test base name. void AddTestPattern(const char* test_case_name, const char* test_base_name, TestMetaFactoryBase* meta_factory) { tests_.push_back(linked_ptr(new TestInfo(test_case_name, test_base_name, meta_factory))); } // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information // about a generator. int AddTestCaseInstantiation(const string& instantiation_name, GeneratorCreationFunc* func, const char* /* file */, int /* line */) { instantiations_.push_back(::std::make_pair(instantiation_name, func)); return 0; // Return value used only to run this method in namespace scope. } // UnitTest class invokes this method to register tests in this test case // test cases right before running tests in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. // UnitTest has a guard to prevent from calling this method more then once. virtual void RegisterTests() { for (typename TestInfoContainer::iterator test_it = tests_.begin(); test_it != tests_.end(); ++test_it) { linked_ptr test_info = *test_it; for (typename InstantiationContainer::iterator gen_it = instantiations_.begin(); gen_it != instantiations_.end(); ++gen_it) { const string& instantiation_name = gen_it->first; ParamGenerator generator((*gen_it->second)()); string test_case_name; if ( !instantiation_name.empty() ) test_case_name = instantiation_name + "/"; test_case_name += test_info->test_case_base_name; int i = 0; for (typename ParamGenerator::iterator param_it = generator.begin(); param_it != generator.end(); ++param_it, ++i) { Message test_name_stream; test_name_stream << test_info->test_base_name << "/" << i; MakeAndRegisterTestInfo( test_case_name.c_str(), test_name_stream.GetString().c_str(), NULL, // No type parameter. PrintToString(*param_it).c_str(), GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, test_info->test_meta_factory->CreateTestFactory(*param_it)); } // for param_it } // for gen_it } // for test_it } // RegisterTests private: // LocalTestInfo structure keeps information about a single test registered // with TEST_P macro. struct TestInfo { TestInfo(const char* a_test_case_base_name, const char* a_test_base_name, TestMetaFactoryBase* a_test_meta_factory) : test_case_base_name(a_test_case_base_name), test_base_name(a_test_base_name), test_meta_factory(a_test_meta_factory) {} const string test_case_base_name; const string test_base_name; const scoped_ptr > test_meta_factory; }; typedef ::std::vector > TestInfoContainer; // Keeps pairs of // received from INSTANTIATE_TEST_CASE_P macros. typedef ::std::vector > InstantiationContainer; const string test_case_name_; TestInfoContainer tests_; InstantiationContainer instantiations_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); }; // class ParameterizedTestCaseInfo // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase // classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P // macros use it to locate their corresponding ParameterizedTestCaseInfo // descriptors. class ParameterizedTestCaseRegistry { public: ParameterizedTestCaseRegistry() {} ~ParameterizedTestCaseRegistry() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { delete *it; } } // Looks up or creates and returns a structure containing information about // tests and instantiations of a particular test case. template ParameterizedTestCaseInfo* GetTestCasePatternHolder( const char* test_case_name, const char* file, int line) { ParameterizedTestCaseInfo* typed_test_info = NULL; for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { if ((*it)->GetTestCaseName() == test_case_name) { if ((*it)->GetTestCaseTypeId() != GetTypeId()) { // Complain about incorrect usage of Google Test facilities // and terminate the program since we cannot guaranty correct // test case setup and tear-down in this case. ReportInvalidTestCaseType(test_case_name, file, line); posix::Abort(); } else { // At this point we are sure that the object we found is of the same // type we are looking for, so we downcast it to that type // without further checks. typed_test_info = CheckedDowncastToActualType< ParameterizedTestCaseInfo >(*it); } break; } } if (typed_test_info == NULL) { typed_test_info = new ParameterizedTestCaseInfo(test_case_name); test_case_infos_.push_back(typed_test_info); } return typed_test_info; } void RegisterTests() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { (*it)->RegisterTests(); } } private: typedef ::std::vector TestCaseInfoContainer; TestCaseInfoContainer test_case_infos_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); }; } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-port.h0000664000175000017500000020627414750344764020542 // Copyright 2005, Google Inc. // 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 Google Inc. 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. // // Authors: wan@google.com (Zhanyong Wan) // // Low-level types and utilities for porting Google Test to various // platforms. They are subject to change without notice. DO NOT USE // THEM IN USER CODE. // // This file is fundamental to Google Test. All other Google Test source // files are expected to #include this. Therefore, it cannot #include // any other Google Test header. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ // The user can define the following macros in the build script to // control Google Test's behavior. If the user doesn't define a macro // in this list, Google Test will define it. // // GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) // is/isn't available. // GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions // are enabled. // GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::string, which is different to std::string). // GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::wstring, which is different to std::wstring). // GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular // expressions are/aren't available. // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that // is/isn't available. // GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't // enabled. // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). // GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple // is/isn't available. // GTEST_HAS_SEH - Define it to 1/0 to indicate whether the // compiler supports Microsoft's "Structured // Exception Handling". // GTEST_HAS_STREAM_REDIRECTION // - Define it to 1/0 to indicate whether the // platform supports I/O stream redirection using // dup() and dup2(). // GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google // Test's own tr1 tuple implementation should be // used. Unused when the user sets // GTEST_HAS_TR1_TUPLE to 0. // GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test // is building in C++11/C++98 mode. // GTEST_LINKED_AS_SHARED_LIBRARY // - Define to 1 when compiling tests that use // Google Test as a shared library (known as // DLL on Windows). // GTEST_CREATE_SHARED_LIBRARY // - Define to 1 when compiling Google Test itself // as a shared library. // This header defines the following utilities: // // Macros indicating the current platform (defined to 1 if compiled on // the given platform; otherwise undefined): // GTEST_OS_AIX - IBM AIX // GTEST_OS_CYGWIN - Cygwin // GTEST_OS_HPUX - HP-UX // GTEST_OS_LINUX - Linux // GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_MAC - Mac OS X // GTEST_OS_IOS - iOS // GTEST_OS_IOS_SIMULATOR - iOS simulator // GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_OPENBSD - OpenBSD // GTEST_OS_QNX - QNX // GTEST_OS_SOLARIS - Sun Solaris // GTEST_OS_SYMBIAN - Symbian // GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) // GTEST_OS_WINDOWS_DESKTOP - Windows Desktop // GTEST_OS_WINDOWS_MINGW - MinGW // GTEST_OS_WINDOWS_MOBILE - Windows Mobile // GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the // most stable support. Since core members of the Google Test project // don't have access to other platforms, support for them may be less // stable. If you notice any problems on your platform, please notify // googletestframework@googlegroups.com (patches for fixing them are // even more welcome!). // // Note that it is possible that none of the GTEST_OS_* macros are defined. // // Macros indicating available Google Test features (defined to 1 if // the corresponding feature is supported; otherwise undefined): // GTEST_HAS_COMBINE - the Combine() function (for value-parameterized // tests) // GTEST_HAS_DEATH_TEST - death tests // GTEST_HAS_PARAM_TEST - value-parameterized tests // GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. // GTEST_USES_SIMPLE_RE - our own simple regex is used; // the above two are mutually exclusive. // GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // variable don't have to be used. // GTEST_DISALLOW_ASSIGN_ - disables operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // // Synchronization: // Mutex, MutexLock, ThreadLocal, GetThreadCount() // - synchronization primitives. // GTEST_IS_THREADSAFE - defined to 1 to indicate that the above // synchronization primitives have real implementations // and Google Test is thread-safe; or 0 otherwise. // // Template meta programming: // is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. // IteratorTraits - partial implementation of std::iterator_traits, which // is not available in libCstd when compiled with Sun C++. // // Smart pointers: // scoped_ptr - as in TR2. // // Regular expressions: // RE - a simple regular expression class using the POSIX // Extended Regular Expression syntax on UNIX-like // platforms, or a reduced regular exception syntax on // other platforms, including Windows. // // Logging: // GTEST_LOG_() - logs messages at the specified severity level. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. // // Stdout and stderr capturing: // CaptureStdout() - starts capturing stdout. // GetCapturedStdout() - stops capturing stdout and returns the captured // string. // CaptureStderr() - starts capturing stderr. // GetCapturedStderr() - stops capturing stderr and returns the captured // string. // // Integer types: // TypeWithSize - maps an integer to a int type. // Int32, UInt32, Int64, UInt64, TimeInMillis // - integers of known sizes. // BiggestInt - the biggest signed integer type. // // Command-line utilities: // GTEST_FLAG() - references a flag. // GTEST_DECLARE_*() - declares a flag. // GTEST_DEFINE_*() - defines a flag. // GetInjectableArgvs() - returns the command line as a vector of strings. // // Environment variable utilities: // GetEnv() - gets the value of an environment variable. // BoolFromGTestEnv() - parses a bool environment variable. // Int32FromGTestEnv() - parses an Int32 environment variable. // StringFromGTestEnv() - parses a string environment variable. #include // for isspace, etc #include // for ptrdiff_t #include #include #include #ifndef _WIN32_WCE # include # include #endif // !_WIN32_WCE #if defined __APPLE__ # include # include #endif #include // NOLINT #include // NOLINT #include // NOLINT #define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" #define GTEST_FLAG_PREFIX_ "gtest_" #define GTEST_FLAG_PREFIX_DASH_ "gtest-" #define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" #define GTEST_NAME_ "Google Test" #define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ // 40302 means version 4.3.2. # define GTEST_GCC_VER_ \ (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ # define GTEST_OS_CYGWIN 1 #elif defined __SYMBIAN32__ # define GTEST_OS_SYMBIAN 1 #elif defined _WIN32 # define GTEST_OS_WINDOWS 1 # ifdef _WIN32_WCE # define GTEST_OS_WINDOWS_MOBILE 1 # elif defined(__MINGW__) || defined(__MINGW32__) # define GTEST_OS_WINDOWS_MINGW 1 # else # define GTEST_OS_WINDOWS_DESKTOP 1 # endif // _WIN32_WCE #elif defined __APPLE__ # define GTEST_OS_MAC 1 # if TARGET_OS_IPHONE # define GTEST_OS_IOS 1 # if TARGET_IPHONE_SIMULATOR # define GTEST_OS_IOS_SIMULATOR 1 # endif # endif #elif defined __linux__ # define GTEST_OS_LINUX 1 # if defined __ANDROID__ # define GTEST_OS_LINUX_ANDROID 1 # endif #elif defined __MVS__ # define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) # define GTEST_OS_SOLARIS 1 #elif defined(_AIX) # define GTEST_OS_AIX 1 #elif defined(__hpux) # define GTEST_OS_HPUX 1 #elif defined __native_client__ # define GTEST_OS_NACL 1 #elif defined __OpenBSD__ # define GTEST_OS_OPENBSD 1 #elif defined __QNX__ # define GTEST_OS_QNX 1 #endif // __CYGWIN__ #ifndef GTEST_LANG_CXX11 // gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when // -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a // value for __cplusplus, and recent versions of clang, gcc, and // probably other compilers set that too in C++11 mode. # if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L // Compiling in at least C++11 mode. # define GTEST_LANG_CXX11 1 # else # define GTEST_LANG_CXX11 0 # endif #endif // Brings in definitions for functions used in the testing::internal::posix // namespace (read, write, close, chdir, isatty, stat). We do not currently // use them on Windows Mobile. #if !GTEST_OS_WINDOWS // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions // mentioned above. # include # include #elif !GTEST_OS_WINDOWS_MOBILE # include # include #endif #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. # include // NOLINT #endif // Defines this to true iff Google Test can use POSIX regular expressions. #ifndef GTEST_HAS_POSIX_RE # if GTEST_OS_LINUX_ANDROID // On Android, is only available starting with Gingerbread. # define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) # else # define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) # endif #endif #if GTEST_HAS_POSIX_RE // On some platforms, needs someone to define size_t, and // won't compile otherwise. We can #include it here as we already // included , which is guaranteed to define size_t through // . # include // NOLINT # define GTEST_USES_POSIX_RE 1 #elif GTEST_OS_WINDOWS // is not available on Windows. Use our own simple regex // implementation instead. # define GTEST_USES_SIMPLE_RE 1 #else // may not be available on this platform. Use our own // simple regex implementation instead. # define GTEST_USES_SIMPLE_RE 1 #endif // GTEST_HAS_POSIX_RE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. # ifndef _HAS_EXCEPTIONS # define _HAS_EXCEPTIONS 1 # endif // _HAS_EXCEPTIONS # define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS # elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__SUNPRO_CC) // Sun Pro CC supports exceptions. However, there is no compile-time way of // detecting whether they are enabled or not. Therefore, we assume that // they are enabled unless the user tells us otherwise. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__IBMCPP__) && __EXCEPTIONS // xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__HP_aCC) // Exception handling is in effect by default in HP aCC compiler. It has to // be turned of by +noeh compiler option if desired. # define GTEST_HAS_EXCEPTIONS 1 # else // For other compilers, we assume exceptions are disabled to be // conservative. # define GTEST_HAS_EXCEPTIONS 0 # endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS #if !defined(GTEST_HAS_STD_STRING) // Even though we don't use this macro any longer, we keep it in case // some clients still depend on it. # define GTEST_HAS_STD_STRING 1 #elif !GTEST_HAS_STD_STRING // The user told us that ::std::string isn't available. # error "Google Test cannot be used where ::std::string isn't available." #endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING // The user didn't tell us whether ::string is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_STRING 0 #endif // GTEST_HAS_GLOBAL_STRING #ifndef GTEST_HAS_STD_WSTRING // The user didn't tell us whether ::std::wstring is available, so we need // to figure it out. // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring // is available. // Cygwin 1.7 and below doesn't support ::std::wstring. // Solaris' libc++ doesn't support it either. Android has // no support for it at least as recent as Froyo (2.2). # define GTEST_HAS_STD_WSTRING \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_WSTRING \ (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING // Determines whether RTTI is available. #ifndef GTEST_HAS_RTTI // The user didn't tell us whether RTTI is enabled, so we need to // figure it out. # ifdef _MSC_VER # ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) # ifdef __GXX_RTTI // When building against STLport with the Android NDK and with // -frtti -fno-exceptions, the build fails at link time with undefined // references to __cxa_bad_typeid. Note sure if STL or toolchain bug, // so disable RTTI when detected. # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ !defined(__EXCEPTIONS) # define GTEST_HAS_RTTI 0 # else # define GTEST_HAS_RTTI 1 # endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS # else # define GTEST_HAS_RTTI 0 # endif // __GXX_RTTI // Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends // using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the // first version with C++ support. # elif defined(__clang__) # define GTEST_HAS_RTTI __has_feature(cxx_rtti) // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // both the typeid and dynamic_cast features are present. # elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) # ifdef __RTTI_ALL__ # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif # else // For all other compilers, we assume RTTI is enabled. # define GTEST_HAS_RTTI 1 # endif // _MSC_VER #endif // GTEST_HAS_RTTI // It's this header's responsibility to #include when RTTI // is enabled. #if GTEST_HAS_RTTI # include #endif // Determines whether Google Test can use the pthreads library. #ifndef GTEST_HAS_PTHREAD // The user didn't tell us explicitly, so we assume pthreads support is // available on Linux and Mac. // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. # define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ || GTEST_OS_QNX) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD // gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is // true. # include // NOLINT // For timespec and nanosleep, used below. # include // NOLINT #endif // Determines whether Google Test can use tr1/tuple. You can define // this macro to 0 to prevent Google Test from using tuple (any // feature depending on tuple with be disabled in this mode). #ifndef GTEST_HAS_TR1_TUPLE # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) // STLport, provided with the Android NDK, has neither or . # define GTEST_HAS_TR1_TUPLE 0 # else // The user didn't tell us not to do it, so we assume it's OK. # define GTEST_HAS_TR1_TUPLE 1 # endif #endif // GTEST_HAS_TR1_TUPLE // Determines whether Google Test's own tr1 tuple implementation // should be used. #ifndef GTEST_USE_OWN_TR1_TUPLE // The user didn't tell us, so we need to figure it out. // We use our own TR1 tuple if we aren't sure the user has an // implementation of it already. At this time, libstdc++ 4.0.0+ and // MSVC 2010 are the only mainstream standard libraries that come // with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler // pretends to be GCC by defining __GNUC__ and friends, but cannot // compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 // tuple in a 323 MB Feature Pack download, which we cannot assume the // user has. QNX's QCC compiler is a modified GCC but it doesn't // support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, // and it can be used with some compilers that define __GNUC__. # if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 # define GTEST_ENV_HAS_TR1_TUPLE_ 1 # endif // C++11 specifies that provides std::tuple. Use that if gtest is used // in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 // can build with clang but need to use gcc4.2's libstdc++). # if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) # define GTEST_ENV_HAS_STD_TUPLE_ 1 # endif # if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ # define GTEST_USE_OWN_TR1_TUPLE 0 # else # define GTEST_USE_OWN_TR1_TUPLE 1 # endif #endif // GTEST_USE_OWN_TR1_TUPLE // To avoid conditional compilation everywhere, we make it // gtest-port.h's responsibility to #include the header implementing // tr1/tuple. #if GTEST_HAS_TR1_TUPLE # if GTEST_USE_OWN_TR1_TUPLE # include "gtest/internal/gtest-tuple.h" # elif GTEST_ENV_HAS_STD_TUPLE_ # include // C++11 puts its tuple into the ::std namespace rather than // ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. // This causes undefined behavior, but supported compilers react in // the way we intend. namespace std { namespace tr1 { using ::std::get; using ::std::make_tuple; using ::std::tuple; using ::std::tuple_element; using ::std::tuple_size; } } # elif GTEST_OS_SYMBIAN // On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to // use STLport's tuple implementation, which unfortunately doesn't // work as the copy of STLport distributed with Symbian is incomplete. // By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to // use its own tuple implementation. # ifdef BOOST_HAS_TR1_TUPLE # undef BOOST_HAS_TR1_TUPLE # endif // BOOST_HAS_TR1_TUPLE // This prevents , which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's . # define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED # include # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the header. This does // not conform to the TR1 spec, which requires the header to be . # if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 // Until version 4.3.2, gcc has a bug that causes , // which is #included by , to not compile when RTTI is // disabled. _TR1_FUNCTIONAL is the header guard for // . Hence the following #define is a hack to prevent // from being included. # define _TR1_FUNCTIONAL 1 # include # undef _TR1_FUNCTIONAL // Allows the user to #include // if he chooses to. # else # include // NOLINT # endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 # else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. # include // NOLINT # endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE // Determines whether clone(2) is supported. // Usually it will only be available on Linux, excluding // Linux on the Itanium architecture. // Also see http://linux.die.net/man/2/clone. #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. # if GTEST_OS_LINUX && !defined(__ia64__) # if GTEST_OS_LINUX_ANDROID // On Android, clone() is only available on ARM starting with Gingerbread. # if defined(__arm__) && __ANDROID_API__ >= 9 # define GTEST_HAS_CLONE 1 # else # define GTEST_HAS_CLONE 0 # endif # else # define GTEST_HAS_CLONE 1 # endif # else # define GTEST_HAS_CLONE 0 # endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE // Determines whether to support stream redirection. This is used to test // output correctness and to implement death tests. #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all // platforms except known mobile ones. # if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN # define GTEST_HAS_STREAM_REDIRECTION 0 # else # define GTEST_HAS_STREAM_REDIRECTION 1 # endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN #endif // GTEST_HAS_STREAM_REDIRECTION // Determines whether to support death tests. // Google Test does not support death tests for VC 7.1 and earlier as // abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. #if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ GTEST_OS_OPENBSD || GTEST_OS_QNX) # define GTEST_HAS_DEATH_TEST 1 # include // NOLINT #endif // We don't support MSVC 7.1 with exceptions disabled now. Therefore // all the compilers we care about are adequate for supporting // value-parameterized tests. #define GTEST_HAS_PARAM_TEST 1 // Determines whether to support type-driven tests. // Typed tests need and variadic macros, which GCC, VC++ 8.0, // Sun Pro CC, IBM Visual Age, and HP aCC support. #if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ defined(__IBMCPP__) || defined(__HP_aCC) # define GTEST_HAS_TYPED_TEST 1 # define GTEST_HAS_TYPED_TEST_P 1 #endif // Determines whether to support Combine(). This only makes sense when // value-parameterized tests are enabled. The implementation doesn't // work on Sun Studio since it doesn't understand templated conversion // operators. #if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) # define GTEST_HAS_COMBINE 1 #endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. #define GTEST_WIDE_STRING_USES_UTF16_ \ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) // Determines whether test results can be streamed to a socket. #if GTEST_OS_LINUX # define GTEST_CAN_STREAM_RESULTS_ 1 #endif // Defines some utility macros. // The GNU compiler emits a warning if nested "if" statements are followed by // an "else" statement and braces are not used to explicitly disambiguate the // "else" binding. This leads to problems with code like: // // if (gate) // ASSERT_*(condition) << "Some message"; // // The "switch (0) case 0:" idiom is used to suppress this. #ifdef __INTEL_COMPILER # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #else # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT #endif // Use this annotation at the end of a struct/class definition to // prevent the compiler from optimizing away instances that are never // used. This is useful when all interesting logic happens inside the // c'tor and / or d'tor. Example: // // struct Foo { // Foo() { ... } // } GTEST_ATTRIBUTE_UNUSED_; // // Also use it after a variable or parameter declaration to tell the // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) # define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) #else # define GTEST_ATTRIBUTE_UNUSED_ #endif // A macro to disallow operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_ASSIGN_(type)\ void operator=(type const &) // A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ type(type const &);\ GTEST_DISALLOW_ASSIGN_(type) // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations // following the argument list: // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; #if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) # define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) #else # define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally // does not exist on any other system. #ifndef GTEST_HAS_SEH // The user didn't tell us, so we need to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // These two compilers are known to support SEH. # define GTEST_HAS_SEH 1 # else // Assume no SEH. # define GTEST_HAS_SEH 0 # endif #endif // GTEST_HAS_SEH #ifdef _MSC_VER # if GTEST_LINKED_AS_SHARED_LIBRARY # define GTEST_API_ __declspec(dllimport) # elif GTEST_CREATE_SHARED_LIBRARY # define GTEST_API_ __declspec(dllexport) # endif #endif // _MSC_VER #ifndef GTEST_API_ # define GTEST_API_ #endif #ifdef __GNUC__ // Ask the compiler to never inline a given function. # define GTEST_NO_INLINE_ __attribute__((noinline)) #else # define GTEST_NO_INLINE_ #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. #if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) # define GTEST_HAS_CXXABI_H_ 1 #else # define GTEST_HAS_CXXABI_H_ 0 #endif namespace testing { class Message; namespace internal { // A secret type that Google Test users don't know about. It has no // definition on purpose. Therefore it's impossible to create a // Secret object, which is what we want. class Secret; // The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time // expression is true. For example, you could use it to verify the // size of a static array: // // GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, // content_type_names_incorrect_size); // // or to make sure a struct is smaller than a certain size: // // GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); // // The second argument to the macro is the name of the variable. If // the expression is false, most compilers will issue a warning/error // containing the name of the variable. template struct CompileAssert { }; #define GTEST_COMPILE_ASSERT_(expr, msg) \ typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ // Implementation details of GTEST_COMPILE_ASSERT_: // // - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // // - The simpler definition // // #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] // // does not work, as gcc supports variable-length arrays whose sizes // are determined at run-time (this is gcc's extension and not part // of the C++ standard). As a result, gcc fails to reject the // following code with the simple definition: // // int foo; // GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is // // not a compile-time constant. // // - By using the type CompileAssert<(bool(expr))>, we ensures that // expr is a compile-time constant. (Template arguments must be // determined at compile-time.) // // - The outter parentheses in CompileAssert<(bool(expr))> are necessary // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written // // CompileAssert // // instead, these compilers will refuse to compile // // GTEST_COMPILE_ASSERT_(5 > 0, some_message); // // (They seem to think the ">" in "5 > 0" marks the end of the // template argument list.) // // - The array size is (bool(expr) ? 1 : -1), instead of simply // // ((expr) ? 1 : -1). // // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. // StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. // // This template is declared, but intentionally undefined. template struct StaticAssertTypeEqHelper; template struct StaticAssertTypeEqHelper {}; #if GTEST_HAS_GLOBAL_STRING typedef ::string string; #else typedef ::std::string string; #endif // GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_WSTRING typedef ::wstring wstring; #elif GTEST_HAS_STD_WSTRING typedef ::std::wstring wstring; #endif // GTEST_HAS_GLOBAL_WSTRING // A helper for suppressing warnings on constant condition. It just // returns 'condition'. GTEST_API_ bool IsTrue(bool condition); // Defines scoped_ptr. // This implementation of scoped_ptr is PARTIAL - it only contains // enough stuff to satisfy Google Test's need. template class scoped_ptr { public: typedef T element_type; explicit scoped_ptr(T* p = NULL) : ptr_(p) {} ~scoped_ptr() { reset(); } T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } T* get() const { return ptr_; } T* release() { T* const ptr = ptr_; ptr_ = NULL; return ptr; } void reset(T* p = NULL) { if (p != ptr_) { if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. delete ptr_; } ptr_ = p; } } private: T* ptr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); }; // Defines RE. // A simple C++ wrapper for . It uses the POSIX Extended // Regular Expression syntax. class GTEST_API_ RE { public: // A copy constructor is required by the Standard to initialize object // references from r-values. RE(const RE& other) { Init(other.pattern()); } // Constructs an RE from a string. RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT #if GTEST_HAS_GLOBAL_STRING RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT #endif // GTEST_HAS_GLOBAL_STRING RE(const char* regex) { Init(regex); } // NOLINT ~RE(); // Returns the string representation of the regex. const char* pattern() const { return pattern_; } // FullMatch(str, re) returns true iff regular expression re matches // the entire str. // PartialMatch(str, re) returns true iff regular expression re // matches a substring of str (including str itself). // // TODO(wan@google.com): make FullMatch() and PartialMatch() work // when str contains NUL characters. static bool FullMatch(const ::std::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::std::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #if GTEST_HAS_GLOBAL_STRING static bool FullMatch(const ::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #endif // GTEST_HAS_GLOBAL_STRING static bool FullMatch(const char* str, const RE& re); static bool PartialMatch(const char* str, const RE& re); private: void Init(const char* regex); // We use a const char* instead of an std::string, as Google Test used to be // used where std::string is not available. TODO(wan@google.com): change to // std::string. const char* pattern_; bool is_valid_; #if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). #else // GTEST_USES_SIMPLE_RE const char* full_pattern_; // For FullMatch(); #endif GTEST_DISALLOW_ASSIGN_(RE); }; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, int line); // Defines logging utilities: // GTEST_LOG_(severity) - logs messages at the specified severity level. The // message itself is streamed into the macro. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL }; // Formats log entry severity, provides a stream object for streaming the // log message, and terminates the message with a newline when going out of // scope. class GTEST_API_ GTestLog { public: GTestLog(GTestLogSeverity severity, const char* file, int line); // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. ~GTestLog(); ::std::ostream& GetStream() { return ::std::cerr; } private: const GTestLogSeverity severity_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); }; #define GTEST_LOG_(severity) \ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } // INTERNAL IMPLEMENTATION - DO NOT USE. // // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition // is not satisfied. // Synopsys: // GTEST_CHECK_(boolean_condition); // or // GTEST_CHECK_(boolean_condition) << "Additional message"; // // This checks the condition and if the condition is not satisfied // it prints message about the condition violation, including the // condition itself, plus additional message streamed into it, if any, // and then it aborts the program. It aborts the program irrespective of // whether it is built in the debug mode or not. #define GTEST_CHECK_(condition) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::IsTrue(condition)) \ ; \ else \ GTEST_LOG_(FATAL) << "Condition " #condition " failed. " // An all-mode assert to verify that the given POSIX-style function // call returns 0 (indicating success). Known limitation: this // doesn't expand to a balanced 'if' statement, so enclose the macro // in {} if you need to use it as the only statement in an 'if' // branch. #define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ if (const int gtest_error = (posix_call)) \ GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Use ImplicitCast_ as a safe version of static_cast for upcasting in // the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a // const Foo*). When you use ImplicitCast_, the compiler checks that // the cast is safe. Such explicit ImplicitCast_s are necessary in // surprisingly many situations where C++ demands an exact type match // instead of an argument type convertable to a target type. // // The syntax for using ImplicitCast_ is the same as for static_cast: // // ImplicitCast_(expr) // // ImplicitCast_ would have been part of the C++ standard library, // but the proposal was submitted too late. It will probably make // its way into the language in the future. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., implicit_cast). The internal // namespace alone is not enough because the function can be found by ADL. template inline To ImplicitCast_(To x) { return x; } // When you upcast (that is, cast a pointer from type Foo to type // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts // always succeed. When you downcast (that is, cast a pointer from // type Foo to type SubclassOfFoo), static_cast<> isn't safe, because // how do you know the pointer is really of type SubclassOfFoo? It // could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, // when you downcast, you should use this macro. In debug mode, we // use dynamic_cast<> to double-check the downcast is legal (we die // if it's not). In normal mode, we do the efficient static_cast<> // instead. Thus, it's important to test in debug mode to make sure // the cast is legal! // This is the only place in the code we should use dynamic_cast<>. // In particular, you SHOULDN'T be using dynamic_cast<> in order to // do RTTI (eg code like this: // if (dynamic_cast(foo)) HandleASubclass1Object(foo); // if (dynamic_cast(foo)) HandleASubclass2Object(foo); // You should design the code some other way not to need this. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., down_cast). The internal // namespace alone is not enough because the function can be found by ADL. template // use like this: DownCast_(foo); inline To DownCast_(From* f) { // so we only accept pointers // Ensures that To is a sub-type of From *. This test is here only // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. if (false) { const To to = NULL; ::testing::internal::ImplicitCast_(to); } #if GTEST_HAS_RTTI // RTTI: debug mode only! GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); #endif return static_cast(f); } // Downcasts the pointer of type Base to Derived. // Derived must be a subclass of Base. The parameter MUST // point to a class of type Derived, not any subclass of it. // When RTTI is available, the function performs a runtime // check to enforce this. template Derived* CheckedDowncastToActualType(Base* base) { #if GTEST_HAS_RTTI GTEST_CHECK_(typeid(*base) == typeid(Derived)); return dynamic_cast(base); // NOLINT #else return static_cast(base); // Poor man's downcast. #endif } #if GTEST_HAS_STREAM_REDIRECTION // Defines the stderr capturer: // CaptureStdout - starts capturing stdout. // GetCapturedStdout - stops capturing stdout and returns the captured string. // CaptureStderr - starts capturing stderr. // GetCapturedStderr - stops capturing stderr and returns the captured string. // GTEST_API_ void CaptureStdout(); GTEST_API_ std::string GetCapturedStdout(); GTEST_API_ void CaptureStderr(); GTEST_API_ std::string GetCapturedStderr(); #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST const ::std::vector& GetInjectableArgvs(); void SetInjectableArgvs(const ::std::vector* new_argvs); // A copy of all command line arguments. Set by InitGoogleTest(). extern ::std::vector g_argvs; #endif // GTEST_HAS_DEATH_TEST // Defines synchronization primitives. #if GTEST_HAS_PTHREAD // Sleeps for (roughly) n milli-seconds. This function is only for // testing Google Test's own constructs. Don't use it in user tests, // either directly or indirectly. inline void SleepMilliseconds(int n) { const timespec time = { 0, // 0 seconds. n * 1000L * 1000L, // And n ms. }; nanosleep(&time, NULL); } // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created // and destroyed in the controller thread. // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. class Notification { public: Notification() : notified_(false) { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); } ~Notification() { pthread_mutex_destroy(&mutex_); } // Notifies all threads created with this notification to start. Must // be called from the controller thread. void Notify() { pthread_mutex_lock(&mutex_); notified_ = true; pthread_mutex_unlock(&mutex_); } // Blocks until the controller thread notifies. Must be called from a test // thread. void WaitForNotification() { for (;;) { pthread_mutex_lock(&mutex_); const bool notified = notified_; pthread_mutex_unlock(&mutex_); if (notified) break; SleepMilliseconds(10); } } private: pthread_mutex_t mutex_; bool notified_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; // As a C-function, ThreadFuncWithCLinkage cannot be templated itself. // Consequently, it cannot select a correct instantiation of ThreadWithParam // in order to call its Run(). Introducing ThreadWithParamBase as a // non-templated base class for ThreadWithParam allows us to bypass this // problem. class ThreadWithParamBase { public: virtual ~ThreadWithParamBase() {} virtual void Run() = 0; }; // pthread_create() accepts a pointer to a function type with the C linkage. // According to the Standard (7.5/1), function types with different linkages // are different even if they are otherwise identical. Some compilers (for // example, SunStudio) treat them as different types. Since class methods // cannot be defined with C-linkage we need to define a free C-function to // pass into pthread_create(). extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { static_cast(thread)->Run(); return NULL; } // Helper class for testing Google Test's multi-threading constructs. // To use it, write: // // void ThreadFunc(int param) { /* Do things with param */ } // Notification thread_can_start; // ... // // The thread_can_start parameter is optional; you can supply NULL. // ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); // thread_can_start.Notify(); // // These classes are only for testing Google Test's own constructs. Do // not use them in user tests, either directly or indirectly. template class ThreadWithParam : public ThreadWithParamBase { public: typedef void (*UserThreadFunc)(T); ThreadWithParam( UserThreadFunc func, T param, Notification* thread_can_start) : func_(func), param_(param), thread_can_start_(thread_can_start), finished_(false) { ThreadWithParamBase* const base = this; // The thread can be created only after all fields except thread_ // have been initialized. GTEST_CHECK_POSIX_SUCCESS_( pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); } ~ThreadWithParam() { Join(); } void Join() { if (!finished_) { GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); finished_ = true; } } virtual void Run() { if (thread_can_start_ != NULL) thread_can_start_->WaitForNotification(); func_(param_); } private: const UserThreadFunc func_; // User-supplied thread function. const T param_; // User-supplied parameter to the thread function. // When non-NULL, used to block execution until the controller thread // notifies. Notification* const thread_can_start_; bool finished_; // true iff we know that the thread function has finished. pthread_t thread_; // The native thread object. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; // MutexBase and Mutex implement mutex on pthreads-based platforms. They // are used in conjunction with class MutexLock: // // Mutex mutex; // ... // MutexLock lock(&mutex); // Acquires the mutex and releases it at the end // // of the current scope. // // MutexBase implements behavior for both statically and dynamically // allocated mutexes. Do not use MutexBase directly. Instead, write // the following to define a static mutex: // // GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); // // You can forward declare a static mutex like this: // // GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); // // To create a dynamic mutex, just define an object of type Mutex. class MutexBase { public: // Acquires this mutex. void Lock() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); owner_ = pthread_self(); has_owner_ = true; } // Releases this mutex. void Unlock() { // Since the lock is being released the owner_ field should no longer be // considered valid. We don't protect writing to has_owner_ here, as it's // the caller's responsibility to ensure that the current thread holds the // mutex when this is called. has_owner_ = false; GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); } // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. void AssertHeld() const { GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) << "The current thread is not holding the mutex @" << this; } // A static mutex may be used before main() is entered. It may even // be used before the dynamic initialization stage. Therefore we // must be able to initialize a static mutex object at link time. // This means MutexBase has to be a POD and its member variables // have to be public. public: pthread_mutex_t mutex_; // The underlying pthread mutex. // has_owner_ indicates whether the owner_ field below contains a valid thread // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All // accesses to the owner_ field should be protected by a check of this field. // An alternative might be to memset() owner_ to all zeros, but there's no // guarantee that a zero'd pthread_t is necessarily invalid or even different // from pthread_self(). bool has_owner_; pthread_t owner_; // The thread holding the mutex. }; // Forward-declares a static mutex. # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, // instead relying on default initialization for the unspecified fields. In // particular, the owner_ field (a pthread_t) is not explicitly initialized. // This allows initialization to work whether pthread_t is a scalar or struct. // The flag -Wmissing-field-initializers must not be specified for this to work. # define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } // The Mutex class can only be used for mutexes created at runtime. It // shares its API with MutexBase otherwise. class Mutex : public MutexBase { public: Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); has_owner_ = false; } ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; // We cannot name this class MutexLock as the ctor declaration would // conflict with a macro named MutexLock, which is defined on some // platforms. Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } ~GTestMutexLock() { mutex_->Unlock(); } private: MutexBase* const mutex_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); }; typedef GTestMutexLock MutexLock; // Helpers for ThreadLocal. // pthread_key_create() requires DeleteThreadLocalValue() to have // C-linkage. Therefore it cannot be templatized to access // ThreadLocal. Hence the need for class // ThreadLocalValueHolderBase. class ThreadLocalValueHolderBase { public: virtual ~ThreadLocalValueHolderBase() {} }; // Called by pthread to delete thread-local data stored by // pthread_setspecific(). extern "C" inline void DeleteThreadLocalValue(void* value_holder) { delete static_cast(value_holder); } // Implements thread-local storage on pthreads-based systems. // // // Thread 1 // ThreadLocal tl(100); // 100 is the default value for each thread. // // // Thread 2 // tl.set(150); // Changes the value for thread 2 only. // EXPECT_EQ(150, tl.get()); // // // Thread 1 // EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. // tl.set(200); // EXPECT_EQ(200, tl.get()); // // The template type argument T must have a public copy constructor. // In addition, the default ThreadLocal constructor requires T to have // a public default constructor. // // An object managed for a thread by a ThreadLocal instance is deleted // when the thread exits. Or, if the ThreadLocal instance dies in // that thread, when the ThreadLocal dies. It's the user's // responsibility to ensure that all other threads using a ThreadLocal // have exited when it dies, or the per-thread objects for those // threads will not be deleted. // // Google Test only uses global ThreadLocal objects. That means they // will die after main() has returned. Therefore, no per-thread // object managed by Google Test will be leaked as long as all threads // using Google Test have exited when main() returns. template class ThreadLocal { public: ThreadLocal() : key_(CreateKey()), default_() {} explicit ThreadLocal(const T& value) : key_(CreateKey()), default_(value) {} ~ThreadLocal() { // Destroys the managed object for the current thread, if any. DeleteThreadLocalValue(pthread_getspecific(key_)); // Releases resources associated with the key. This will *not* // delete managed objects for other threads. GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); } T* pointer() { return GetOrCreateValue(); } const T* pointer() const { return GetOrCreateValue(); } const T& get() const { return *pointer(); } void set(const T& value) { *pointer() = value; } private: // Holds a value of type T. class ValueHolder : public ThreadLocalValueHolderBase { public: explicit ValueHolder(const T& value) : value_(value) {} T* pointer() { return &value_; } private: T value_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); }; static pthread_key_t CreateKey() { pthread_key_t key; // When a thread exits, DeleteThreadLocalValue() will be called on // the object managed for that thread. GTEST_CHECK_POSIX_SUCCESS_( pthread_key_create(&key, &DeleteThreadLocalValue)); return key; } T* GetOrCreateValue() const { ThreadLocalValueHolderBase* const holder = static_cast(pthread_getspecific(key_)); if (holder != NULL) { return CheckedDowncastToActualType(holder)->pointer(); } ValueHolder* const new_holder = new ValueHolder(default_); ThreadLocalValueHolderBase* const holder_base = new_holder; GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); return new_holder->pointer(); } // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; const T default_; // The default value for each thread. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; # define GTEST_IS_THREADSAFE 1 #else // GTEST_HAS_PTHREAD // A dummy implementation of synchronization primitives (mutex, lock, // and thread-local variable). Necessary for compiling Google Test where // mutex is not supported - using Google Test in multiple threads is not // supported on such platforms. class Mutex { public: Mutex() {} void Lock() {} void Unlock() {} void AssertHeld() const {} }; # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::Mutex mutex # define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex class GTestMutexLock { public: explicit GTestMutexLock(Mutex*) {} // NOLINT }; typedef GTestMutexLock MutexLock; template class ThreadLocal { public: ThreadLocal() : value_() {} explicit ThreadLocal(const T& value) : value_(value) {} T* pointer() { return &value_; } const T* pointer() const { return &value_; } const T& get() const { return value_; } void set(const T& value) { value_ = value; } private: T value_; }; // The above synchronization primitives have dummy implementations. // Therefore Google Test is not thread-safe. # define GTEST_IS_THREADSAFE 0 #endif // GTEST_HAS_PTHREAD // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. GTEST_API_ size_t GetThreadCount(); // Passing non-POD classes through ellipsis (...) crashes the ARM // compiler and generates a warning in Sun Studio. The Nokia Symbian // and the IBM XL C/C++ compiler try to instantiate a copy constructor // for objects passed through ellipsis (...), failing for uncopyable // objects. We define this to ensure that only POD is passed through // ellipsis on these systems. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_ELLIPSIS_NEEDS_POD_ 1 #else # define GTEST_CAN_COMPARE_NULL 1 #endif // The Nokia Symbian and IBM XL C/C++ compilers cannot decide between // const T& and const T* in a function template. These compilers // _can_ decide between class template specializations for T and T*, // so a tr1::type_traits-like is_pointer works. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) # define GTEST_NEEDS_IS_POINTER_ 1 #endif template struct bool_constant { typedef bool_constant type; static const bool value = bool_value; }; template const bool bool_constant::value; typedef bool_constant false_type; typedef bool_constant true_type; template struct is_pointer : public false_type {}; template struct is_pointer : public true_type {}; template struct IteratorTraits { typedef typename Iterator::value_type value_type; }; template struct IteratorTraits { typedef T value_type; }; template struct IteratorTraits { typedef T value_type; }; #if GTEST_OS_WINDOWS # define GTEST_PATH_SEP_ "\\" # define GTEST_HAS_ALT_PATH_SEP_ 1 // The biggest signed integer type the compiler supports. typedef __int64 BiggestInt; #else # define GTEST_PATH_SEP_ "/" # define GTEST_HAS_ALT_PATH_SEP_ 0 typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS // Utilities for char. // isspace(int ch) and friends accept an unsigned char or EOF. char // may be signed, depending on the compiler (or compiler flags). // Therefore we need to cast a char to unsigned char before calling // isspace(), etc. inline bool IsAlpha(char ch) { return isalpha(static_cast(ch)) != 0; } inline bool IsAlNum(char ch) { return isalnum(static_cast(ch)) != 0; } inline bool IsDigit(char ch) { return isdigit(static_cast(ch)) != 0; } inline bool IsLower(char ch) { return islower(static_cast(ch)) != 0; } inline bool IsSpace(char ch) { return isspace(static_cast(ch)) != 0; } inline bool IsUpper(char ch) { return isupper(static_cast(ch)) != 0; } inline bool IsXDigit(char ch) { return isxdigit(static_cast(ch)) != 0; } inline bool IsXDigit(wchar_t ch) { const unsigned char low_byte = static_cast(ch); return ch == low_byte && isxdigit(low_byte) != 0; } inline char ToLower(char ch) { return static_cast(tolower(static_cast(ch))); } inline char ToUpper(char ch) { return static_cast(toupper(static_cast(ch))); } // The testing::internal::posix namespace holds wrappers for common // POSIX functions. These wrappers hide the differences between // Windows/MSVC and POSIX systems. Since some compilers define these // standard functions as macros, the wrapper cannot have the same name // as the wrapped function. namespace posix { // Functions with a different name on Windows. #if GTEST_OS_WINDOWS typedef struct _stat StatStruct; # ifdef __BORLANDC__ inline int IsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } # else // !__BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int IsATTY(int /* fd */) { return 0; } # else inline int IsATTY(int fd) { return _isatty(fd); } # endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } # endif // __BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. # else inline int FileNo(FILE* file) { return _fileno(file); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } # endif // GTEST_OS_WINDOWS_MOBILE #else typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } inline int IsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } inline int RmDir(const char* dir) { return rmdir(dir); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #endif // GTEST_OS_WINDOWS // Functions deprecated by MSVC 8.0. #ifdef _MSC_VER // Temporarily disable warning 4996 (deprecated function). # pragma warning(push) # pragma warning(disable:4996) #endif inline const char* StrNCpy(char* dest, const char* src, size_t n) { return strncpy(dest, src, n); } // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // StrError() aren't needed on Windows CE at this time and thus not // defined there. #if !GTEST_OS_WINDOWS_MOBILE inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { return fopen(path, mode); } #if !GTEST_OS_WINDOWS_MOBILE inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } #endif inline int FClose(FILE* fp) { return fclose(fp); } #if !GTEST_OS_WINDOWS_MOBILE inline int Read(int fd, void* buf, unsigned int count) { return static_cast(read(fd, buf, count)); } inline int Write(int fd, const void* buf, unsigned int count) { return static_cast(write(fd, buf, count)); } inline int Close(int fd) { return close(fd); } inline const char* StrError(int errnum) { return strerror(errnum); } #endif inline const char* GetEnv(const char* name) { #if GTEST_OS_WINDOWS_MOBILE // We are on Windows CE, which has no environment variables. return NULL; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // Environment variables which we programmatically clear will be set to the // empty string rather than unset (NULL). Handle that case. const char* const env = getenv(name); return (env != NULL && env[0] != '\0') ? env : NULL; #else return getenv(name); #endif } #ifdef _MSC_VER # pragma warning(pop) // Restores the warning state. #endif #if GTEST_OS_WINDOWS_MOBILE // Windows CE has no C library. The abort() function is used in // several places in Google Test. This implementation provides a reasonable // imitation of standard behaviour. void Abort(); #else inline void Abort() { abort(); } #endif // GTEST_OS_WINDOWS_MOBILE } // namespace posix // MSVC "deprecates" snprintf and issues warnings wherever it is used. In // order to avoid these warnings, we need to use _snprintf or _snprintf_s on // MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate // function in order to achieve that. We use macro definition here because // snprintf is a variadic function. #if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // MSVC 2005 and above support variadic macros. # define GTEST_SNPRINTF_(buffer, size, format, ...) \ _snprintf_s(buffer, size, size, format, __VA_ARGS__) #elif defined(_MSC_VER) // Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't // complain about _snprintf. # define GTEST_SNPRINTF_ _snprintf #else # define GTEST_SNPRINTF_ snprintf #endif // The maximum number a BiggestInt can represent. This definition // works no matter BiggestInt is represented in one's complement or // two's complement. // // We cannot rely on numeric_limits in STL, as __int64 and long long // are not part of standard C++ and numeric_limits doesn't need to be // defined for them. const BiggestInt kMaxBiggestInt = ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); // This template class serves as a compile-time function from size to // type. It maps a size in bytes to a primitive type with that // size. e.g. // // TypeWithSize<4>::UInt // // is typedef-ed to be unsigned int (unsigned integer made up of 4 // bytes). // // Such functionality should belong to STL, but I cannot find it // there. // // Google Test uses this class in the implementation of floating-point // comparison. // // For now it only handles UInt (unsigned int) as that's all Google Test // needs. Other types can be easily added in the future if need // arises. template class TypeWithSize { public: // This prevents the user from using TypeWithSize with incorrect // values of N. typedef void UInt; }; // The specialization for size 4. template <> class TypeWithSize<4> { public: // unsigned int has size 4 in both gcc and MSVC. // // As base/basictypes.h doesn't compile on Windows, we cannot use // uint32, uint64, and etc here. typedef int Int; typedef unsigned int UInt; }; // The specialization for size 8. template <> class TypeWithSize<8> { public: #if GTEST_OS_WINDOWS typedef __int64 Int; typedef unsigned __int64 UInt; #else typedef long long Int; // NOLINT typedef unsigned long long UInt; // NOLINT #endif // GTEST_OS_WINDOWS }; // Integer types of known sizes. typedef TypeWithSize<4>::Int Int32; typedef TypeWithSize<4>::UInt UInt32; typedef TypeWithSize<8>::Int Int64; typedef TypeWithSize<8>::UInt UInt64; typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Utilities for command line flags and environment variables. // Macro for referencing flags. #define GTEST_FLAG(name) FLAGS_gtest_##name // Macros for declaring flags. #define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) #define GTEST_DECLARE_int32_(name) \ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) #define GTEST_DECLARE_string_(name) \ GTEST_API_ extern ::std::string GTEST_FLAG(name) // Macros for defining flags. #define GTEST_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_int32_(name, default_val, doc) \ GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) // Thread annotations #define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) #define GTEST_LOCK_EXCLUDED_(locks) // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns // false. // TODO(chandlerc): Find a better way to refactor flag and environment parsing // out of both gtest-port.cc and gtest.cc to avoid exporting this utility // function. bool ParseInt32(const Message& src_text, const char* str, Int32* value); // Parses a bool/Int32/string from the environment variable // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ stimfit-0.16.7/src/test/gtest/include/gtest/internal/gtest-type-util.h.pump0000664000175000017500000002214514750344764022463 $$ -*- mode: c++; -*- $var n = 50 $$ Maximum length of type lists we want to support. // Copyright 2008 Google Inc. // 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 Google Inc. 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. // // Author: wan@google.com (Zhanyong Wan) // Type utilities needed for implementing typed and type-parameterized // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently we support at most $n types in a list, and at most $n // type-parameterized tests in one type-parameterized test case. // Please contact googletestframework@googlegroups.com if you need // more. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #include "gtest/internal/gtest-port.h" // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). # if GTEST_HAS_CXXABI_H_ # include # elif defined(__HP_aCC) # include # endif // GTEST_HASH_CXXABI_H_ namespace testing { namespace internal { // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of // the typed-test-only section below. template std::string GetTypeName() { # if GTEST_HAS_RTTI const char* const name = typeid(T).name(); # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. # if GTEST_HAS_CXXABI_H_ using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); const std::string name_str(status == 0 ? readable_name : name); free(readable_name); return name_str; # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC # else return ""; # endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // AssertyTypeEq::type is defined iff T1 and T2 are the same // type. This can be used as a compile-time assertion to ensure that // two types are equal. template struct AssertTypeEq; template struct AssertTypeEq { typedef bool type; }; // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't // support directly. struct None {}; // The following family of struct and struct templates are used to // represent type lists. In particular, TypesN // represents a type list with N types (T1, T2, ..., and TN) in it. // Except for Types0, every struct in the family has two member types: // Head for the first type in the list, and Tail for the rest of the // list. // The empty type list. struct Types0 {}; // Type lists of length 1, 2, 3, and so on. template struct Types1 { typedef T1 Head; typedef Types0 Tail; }; $range i 2..n $for i [[ $range j 1..i $range k 2..i template <$for j, [[typename T$j]]> struct Types$i { typedef T1 Head; typedef Types$(i-1)<$for k, [[T$k]]> Tail; }; ]] } // namespace internal // We don't want to require the users to write TypesN<...> directly, // as that would require them to count the length. Types<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Types // will appear as Types in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Types, and Google Test will translate // that to TypesN internally to make error messages // readable. The translation is done by the 'type' member of the // Types template. $range i 1..n template <$for i, [[typename T$i = internal::None]]> struct Types { typedef internal::Types$n<$for i, [[T$i]]> type; }; template <> struct Types<$for i, [[internal::None]]> { typedef internal::Types0 type; }; $range i 1..n-1 $for i [[ $range j 1..i $range k i+1..n template <$for j, [[typename T$j]]> struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { typedef internal::Types$i<$for j, [[T$j]]> type; }; ]] namespace internal { # define GTEST_TEMPLATE_ template class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type // parameter, as a type. TemplateSel::Bind::type is defined // as the type Tmpl. This allows us to actually instantiate the // template "selected" by TemplateSel. // // This trick is necessary for simulating typedef for class templates, // which C++ doesn't support directly. template struct TemplateSel { template struct Bind { typedef Tmpl type; }; }; # define GTEST_BIND_(TmplSel, T) \ TmplSel::template Bind::type // A unique struct template used as the default value for the // arguments of class template Templates. This allows us to simulate // variadic templates (e.g. Templates, Templates, // and etc), which C++ doesn't support directly. template struct NoneT {}; // The following family of struct and struct templates are used to // represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except // for Templates0, every struct in the family has two member types: // Head for the selector of the first template in the list, and Tail // for the rest of the list. // The empty template list. struct Templates0 {}; // Template lists of length 1, 2, 3, and so on. template struct Templates1 { typedef TemplateSel Head; typedef Templates0 Tail; }; $range i 2..n $for i [[ $range j 1..i $range k 2..i template <$for j, [[GTEST_TEMPLATE_ T$j]]> struct Templates$i { typedef TemplateSel Head; typedef Templates$(i-1)<$for k, [[T$k]]> Tail; }; ]] // We don't want to require the users to write TemplatesN<...> directly, // as that would require them to count the length. Templates<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Templates // will appear as Templates in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Templates, and Google Test will translate // that to TemplatesN internally to make error messages // readable. The translation is done by the 'type' member of the // Templates template. $range i 1..n template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> struct Templates { typedef Templates$n<$for i, [[T$i]]> type; }; template <> struct Templates<$for i, [[NoneT]]> { typedef Templates0 type; }; $range i 1..n-1 $for i [[ $range j 1..i $range k i+1..n template <$for j, [[GTEST_TEMPLATE_ T$j]]> struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { typedef Templates$i<$for j, [[T$j]]> type; }; ]] // The TypeList template makes it possible to use either a single type // or a Types<...> list in TYPED_TEST_CASE() and // INSTANTIATE_TYPED_TEST_CASE_P(). template struct TypeList { typedef Types1 type; }; $range i 1..n template <$for i, [[typename T$i]]> struct TypeList > { typedef typename Types<$for i, [[T$i]]>::type type; }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ stimfit-0.16.7/src/test/gtest/CONTRIBUTORS0000664000175000017500000000251614750344764013545 # This file contains a list of people who've made non-trivial # contribution to the Google C++ Testing Framework project. People # who commit code to the project are encouraged to add their names # here. Please keep the list sorted by first names. Ajay Joshi Balázs Dán Bharat Mediratta Chandler Carruth Chris Prince Chris Taylor Dan Egnor Eric Roman Hady Zalek Jeffrey Yasskin Jói Sigurðsson Keir Mierle Keith Ray Kenton Varda Manuel Klimek Markus Heule Mika Raento Miklós Fazekas Pasi Valminen Patrick Hanna Patrick Riley Peter Kaminski Preston Jackson Rainer Klaffenboeck Russ Cox Russ Rufer Sean Mcafee Sigurður Ásgeirsson Tracy Bialik Vadim Berman Vlad Losev Zhanyong Wan stimfit-0.16.7/src/biosig/0000775000175000017500000000000014764352501011101 5stimfit-0.16.7/src/biosig/biosig4c++/0000775000175000017500000000000014764352501012732 5stimfit-0.16.7/src/biosig/biosig4c++/igor/0000775000175000017500000000000014764352501013672 5stimfit-0.16.7/src/biosig/biosig4c++/igor/IgorBin.h0000664000175000017500000002221114752215315015310 /* Copyright (C) 2013 Alois Schloegl Copyright (C) 1999 Wavematrix, Inc. Lake Oswego OR, USA This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ // IgorBin.h -- structures and #defines for dealing with Igor binary data. #include #ifdef __cplusplus extern "C" { #endif // All structures written to disk are 2-byte-aligned. #if __GNUC__ #pragma pack(push,2) /* igor uses a 32bit memory model, all pointers are 32 bit. in order to keep the structs containing poiners aligned, all pointers need to be remapped to uint32_t. */ #define ptr_t uint32_t #define Handle uint32_t #elif GENERATINGPOWERPC #pragma options align=mac68k #endif // From IgorMath.h #define NT_CMPLX 1 // Complex numbers. #define NT_FP32 2 // 32 bit fp numbers. #define NT_FP64 4 // 64 bit fp numbers. #define NT_I8 8 // 8 bit signed integer. Requires Igor Pro 2.0 or later. #define NT_I16 0x10 // 16 bit integer numbers. Requires Igor Pro 2.0 or later. #define NT_I32 0x20 // 32 bit integer numbers. Requires Igor Pro 2.0 or later. #define NT_UNSIGNED 0x40 // Makes above signed integers unsigned. Requires Igor Pro 3.0 or later. // From wave.h #define MAXDIMS 4 // From binary.h typedef struct BinHeader1 { int16_t version; // Version number for backwards compatibility. int32_t wfmSize; // The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding. int16_t checksum; // Checksum over this header and the wave header. } BinHeader1; typedef struct BinHeader2 { int16_t version; // Version number for backwards compatibility. int32_t wfmSize; // The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding. int32_t noteSize; // The size of the note text. int32_t pictSize; // Reserved. Write zero. Ignore on read. int16_t checksum; // Checksum over this header and the wave header. } BinHeader2; typedef struct BinHeader3 { int16_t version; // Version number for backwards compatibility. int32_t wfmSize; // The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding. int32_t noteSize; // The size of the note text. int32_t formulaSize; // The size of the dependency formula, if any. int32_t pictSize; // Reserved. Write zero. Ignore on read. int16_t checksum; // Checksum over this header and the wave header. } BinHeader3; typedef struct BinHeader5 { int16_t version; // Version number for backwards compatibility. int16_t checksum; // Checksum over this header and the wave header. int32_t wfmSize; // The size of the WaveHeader5 data structure plus the wave data. int32_t formulaSize; // The size of the dependency formula, if any. int32_t noteSize; // The size of the note text. int32_t dataEUnitsSize; // The size of optional extended data units. int32_t dimEUnitsSize[MAXDIMS]; // The size of optional extended dimension units. int32_t dimLabelsSize[MAXDIMS]; // The size of optional dimension labels. int32_t sIndicesSize; // The size of string indicies if this is a text wave. int32_t optionsSize1; // Reserved. Write zero. Ignore on read. int32_t optionsSize2; // Reserved. Write zero. Ignore on read. } BinHeader5; // From wave.h #define MAX_WAVE_NAME2 18 // Maximum length of wave name in version 1 and 2 files. Does not include the trailing null. #define MAX_WAVE_NAME5 31 // Maximum length of wave name in version 5 files. Does not include the trailing null. #define MAX_UNIT_CHARS 3 // Header to an array of waveform data. struct WaveHeader2 { int16_t type; // See types (e.g. NT_FP64) above. Zero for text waves. // struct WaveHeader2 **next; // Used in memory only. Write zero. Ignore on read. ptr_t next; char bname[MAX_WAVE_NAME2+2]; // Name of wave plus trailing null. int16_t whVersion; // Write 0. Ignore on read. int16_t srcFldr; // Used in memory only. Write zero. Ignore on read. Handle fileName; // Used in memory only. Write zero. Ignore on read. char dataUnits[MAX_UNIT_CHARS+1]; // Natural data units go here - null if none. char xUnits[MAX_UNIT_CHARS+1]; // Natural x-axis units go here - null if none. int32_t npnts; // Number of data points in wave. int16_t aModified; // Used in memory only. Write zero. Ignore on read. double hsA,hsB; // X value for point p = hsA*p + hsB int16_t wModified; // Used in memory only. Write zero. Ignore on read. int16_t swModified; // Used in memory only. Write zero. Ignore on read. int16_t fsValid; // True if full scale values have meaning. double topFullScale,botFullScale; // The min full scale value for wave. char useBits; // Used in memory only. Write zero. Ignore on read. char kindBits; // Reserved. Write zero. Ignore on read. //void **formula; // Used in memory only. Write zero. Ignore on read. ptr_t formula; int32_t depID; // Used in memory only. Write zero. Ignore on read. uint32_t creationDate; // DateTime of creation. Not used in version 1 files. char wUnused[2]; // Reserved. Write zero. Ignore on read. uint32_t modDate; // DateTime of last modification. Handle waveNoteH; // Used in memory only. Write zero. Ignore on read. float wData[4]; // The start of the array of waveform data. }; typedef struct WaveHeader2 WaveHeader2; typedef WaveHeader2 *WavePtr2; typedef WavePtr2 *waveHandle2; struct WaveHeader5 { //struct WaveHeader5 **next; // link to next wave in linked list. ptr_t next; uint32_t creationDate; // DateTime of creation. uint32_t modDate; // DateTime of last modification. int32_t npnts; // Total number of points (multiply dimensions up to first zero). int16_t type; // See types (e.g. NT_FP64) above. Zero for text waves. int16_t dLock; // Reserved. Write zero. Ignore on read. char whpad1[6]; // Reserved. Write zero. Ignore on read. int16_t whVersion; // Write 1. Ignore on read. char bname[MAX_WAVE_NAME5+1]; // Name of wave plus trailing null. int32_t whpad2; // Reserved. Write zero. Ignore on read. //struct DataFolder **dFolder; // Used in memory only. Write zero. Ignore on read. ptr_t dFolder; // Dimensioning info. [0] == rows, [1] == cols etc int32_t nDim[MAXDIMS]; // Number of of items in a dimension -- 0 means no data. double sfA[MAXDIMS]; // Index value for element e of dimension d = sfA[d]*e + sfB[d]. double sfB[MAXDIMS]; // SI units char dataUnits[MAX_UNIT_CHARS+1]; // Natural data units go here - null if none. char dimUnits[MAXDIMS][MAX_UNIT_CHARS+1]; // Natural dimension units go here - null if none. int16_t fsValid; // TRUE if full scale values have meaning. int16_t whpad3; // Reserved. Write zero. Ignore on read. double topFullScale,botFullScale; // The max and max full scale value for wave. Handle dataEUnits; // Used in memory only. Write zero. Ignore on read. Handle dimEUnits[MAXDIMS]; // Used in memory only. Write zero. Ignore on read. Handle dimLabels[MAXDIMS]; // Used in memory only. Write zero. Ignore on read. Handle waveNoteH; // Used in memory only. Write zero. Ignore on read. int32_t whUnused[16]; // Reserved. Write zero. Ignore on read. // The following stuff is considered private to Igor. int16_t aModified; // Used in memory only. Write zero. Ignore on read. int16_t wModified; // Used in memory only. Write zero. Ignore on read. int16_t swModified; // Used in memory only. Write zero. Ignore on read. char useBits; // Used in memory only. Write zero. Ignore on read. char kindBits; // Reserved. Write zero. Ignore on read. //void **formula; // Used in memory only. Write zero. Ignore on read. ptr_t formula; int32_t depID; // Used in memory only. Write zero. Ignore on read. int16_t whpad4; // Reserved. Write zero. Ignore on read. int16_t srcFldr; // Used in memory only. Write zero. Ignore on read. Handle fileName; // Used in memory only. Write zero. Ignore on read. //int32_t **sIndices; // Used in memory only. Write zero. Ignore on read. ptr_t sIndices; float wData[1]; // The start of the array of data. Must be 64 bit aligned. }; typedef struct WaveHeader5 WaveHeader5; typedef WaveHeader5 *WavePtr5; typedef WavePtr5 *WaveHandle5; #if __GNUC__ #pragma pack(pop) #undef ptr_t #undef Handle #elif GENERATINGPOWERPC #pragma options align=reset #endif // All structures written to disk are 2-byte-aligned. #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/biosig2.c0000664000175000017500000013327614752215315014366 /* Copyright (C) 2012-2018 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "biosig.h" /* ============================================================= setter and getter functions for accessing fields of HDRTYPE ============================================================= */ enum FileFormat biosig_get_filetype(HDRTYPE *hdr) { if (hdr==NULL) return noFile; return hdr->TYPE; } int biosig_set_filetype(HDRTYPE *hdr, enum FileFormat format) { if (hdr==NULL) return -1; hdr->TYPE=format; if (format==GDF) hdr->VERSION = 1.0/0.0; // use latest version return 0; } #if (BIOSIG_VERSION < 10700) ATT_DEPREC int biosig_set_flags(HDRTYPE *hdr, char compression, char ucal, char overflowdetection) { fprintf(stderr,"Warning libbiosig2: function biosig_set_flags() is deprecated, use biosig_(re)set_flag() instead\n"); if (hdr==NULL) return -1; hdr->FLAG.UCAL = ucal; hdr->FLAG.OVERFLOWDETECTION = overflowdetection; hdr->FILE.COMPRESSION = compression; return 0; } #endif int biosig_get_flag(HDRTYPE *hdr, unsigned flags) { if (hdr==NULL) return -1; return flags & ( \ (!!hdr->FLAG.OVERFLOWDETECTION) * (unsigned)BIOSIG_FLAG_OVERFLOWDETECTION \ + (!!hdr->FLAG.UCAL) * (unsigned)BIOSIG_FLAG_UCAL \ + (!!hdr->FILE.COMPRESSION) * (unsigned)BIOSIG_FLAG_COMPRESSION \ + (!!hdr->FLAG.UCAL) * (unsigned)BIOSIG_FLAG_UCAL \ + (!!hdr->FLAG.ROW_BASED_CHANNELS)* (unsigned)BIOSIG_FLAG_ROW_BASED_CHANNELS \ ) ; } int biosig_set_flag(HDRTYPE *hdr, unsigned flags) { if (hdr==NULL) return -1; hdr->FLAG.UCAL |= !!(flags & BIOSIG_FLAG_UCAL); hdr->FLAG.OVERFLOWDETECTION |= !!(flags & BIOSIG_FLAG_OVERFLOWDETECTION); hdr->FILE.COMPRESSION |= !!(flags & BIOSIG_FLAG_COMPRESSION); hdr->FLAG.ROW_BASED_CHANNELS |= !!(flags & BIOSIG_FLAG_ROW_BASED_CHANNELS); return 0; }; int biosig_reset_flag(HDRTYPE *hdr, unsigned flags) { if (hdr==NULL) return -1; hdr->FLAG.UCAL &= !(flags & BIOSIG_FLAG_UCAL); hdr->FLAG.OVERFLOWDETECTION &= !(flags & BIOSIG_FLAG_OVERFLOWDETECTION); hdr->FILE.COMPRESSION &= !(flags & BIOSIG_FLAG_COMPRESSION); hdr->FLAG.ROW_BASED_CHANNELS &= !(flags & BIOSIG_FLAG_ROW_BASED_CHANNELS); return 0; }; int biosig_get_targetsegment(HDRTYPE *hdr) { if (hdr==NULL) return -1; return hdr->FLAG.TARGETSEGMENT; }; const char* biosig_get_filename(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->FileName; }; float biosig_get_version(HDRTYPE *hdr) { if (hdr==NULL) return NAN; return hdr->VERSION; }; int biosig_set_targetsegment(HDRTYPE *hdr, unsigned targetsegment) { return biosig_set_segment_selection(hdr, 0, targetsegment); }; int biosig_set_segment_selection(HDRTYPE *hdr, int k, uint32_t argSweepSel) {; if (hdr==NULL) return -1; if (k>5 || k<0) return -3; if (k==0) { if (argSweepSel > 127) { fprintf(stderr,"Warning libbiosig2: biosig_set_targetsegment is larger than 127 (%i)\n", argSweepSel); return -2; } hdr->FLAG.TARGETSEGMENT = argSweepSel; } else hdr->AS.SegSel[k-1] = argSweepSel; return 0; } uint32_t* biosig_get_segment_selection(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return (uint32_t*)&(hdr->AS.SegSel); }; long biosig_get_number_of_channels(HDRTYPE *hdr) { if (hdr==NULL) return -1; long k,m; for (k=0,m=0; kNS; k++) if (hdr->CHANNEL[k].OnOff==1) { m++; } return m; } size_t biosig_get_number_of_records(HDRTYPE *hdr) { if (hdr==NULL) return -1; return hdr->NRec; } size_t biosig_get_number_of_samples(HDRTYPE *hdr) { if (hdr==NULL) return -1; return hdr->NRec*hdr->SPR; } size_t biosig_get_number_of_samples_per_record(HDRTYPE *hdr) { if (hdr==NULL) return -1; return hdr->SPR; } size_t biosig_get_number_of_segments(HDRTYPE *hdr) { if (hdr==NULL) return 0; if (hdr->SPR==0) return 0; size_t k, n; for (k=0, n=1; kEVENT.N; k++) if (hdr->EVENT.TYP[k]==0x7ffe) n++; return n; } int biosig_set_number_of_channels(HDRTYPE *hdr, int ns) { if (hdr==NULL) return -1; // define variable header void *ptr = realloc(hdr->CHANNEL, ns*sizeof(CHANNEL_TYPE)); if (ptr==NULL) return -1; hdr->CHANNEL = (CHANNEL_TYPE*)ptr; int k; for (k=hdr->NS; k < ns; k++) { // initialize new channels CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Label[0] = 0; hc->LeadIdCode= 0; strcpy(hc->Transducer, "EEG: Ag-AgCl electrodes"); hc->PhysDimCode = 19+4256; // uV hc->PhysMax = +100; hc->PhysMin = -100; hc->DigMax = +2047; hc->DigMin = -2048; hc->Cal = NAN; hc->Off = 0.0; hc->TOffset = 0.0; hc->GDFTYP = 3; // int16 hc->SPR = 1; // one sample per block hc->bi = 2*k; hc->bi8 = 16*k; hc->OnOff = 1; hc->HighPass = 0.16; hc->LowPass = 70.0; hc->Notch = 50; hc->Impedance = INFINITY; hc->fZ = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; } hdr->NS = ns; return 0; } int biosig_set_number_of_samples(HDRTYPE *hdr, ssize_t nrec, ssize_t spr) { if (hdr==NULL) return -1; if (nrec >= 0) hdr->NRec = nrec; if (spr >= 0) hdr->SPR = spr; return 0; } //ATT_DEPREC int biosig_set_number_of_segments(HDRTYPE *hdr, ) int biosig_get_datablock(HDRTYPE *hdr, double **data, size_t *rows, size_t *columns ) { if (hdr==NULL) return -1; *data = hdr->data.block; *rows = hdr->data.size[0]; *columns = hdr->data.size[1]; return 0; } biosig_data_type* biosig_get_data(HDRTYPE *hdr, char flag ) { if (hdr==NULL) return NULL; hdr->FLAG.ROW_BASED_CHANNELS = flag; sread(NULL, 0, hdr->NRec, hdr); return hdr->data.block; } double biosig_get_samplerate(HDRTYPE *hdr) { if (hdr==NULL) return NAN; return hdr->SampleRate; } int biosig_set_samplerate(HDRTYPE *hdr, double fs) { if (hdr==NULL) return -1; hdr->SampleRate=fs; return 0; } size_t biosig_get_number_of_events(HDRTYPE *hdr) { if (hdr==NULL) return 0; return hdr->EVENT.N; } size_t biosig_set_number_of_events(HDRTYPE *hdr, size_t N) { if (hdr==NULL) return 0; size_t k; hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, N * 4 ); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, N * 2 ); for (k = hdr->EVENT.N; kEVENT.POS[k] = 0; hdr->EVENT.TYP[k] = 0; } k = ( (hdr->EVENT.DUR==NULL) || (hdr->EVENT.CHN==NULL) ) ? 0 : hdr->EVENT.N; hdr->EVENT.DUR = (uint32_t*) realloc(hdr->EVENT.DUR, N * 4 ); hdr->EVENT.CHN = (uint16_t*) realloc(hdr->EVENT.CHN, N * 2 ); for (; kEVENT.CHN[k] = 0; hdr->EVENT.DUR[k] = 0; } k = (hdr->EVENT.TimeStamp==NULL) ? 0 : hdr->EVENT.N; hdr->EVENT.TimeStamp = (gdf_time*) realloc(hdr->EVENT.TimeStamp, N * 8 ); for (; kEVENT.TimeStamp[k] = 0; } hdr->EVENT.N = N; return hdr->EVENT.N; } int biosig_get_nth_event(HDRTYPE *hdr, size_t n, uint16_t *typ, uint32_t *pos, uint16_t *chn, uint32_t *dur, gdf_time *timestamp, const char **desc) { if (hdr==NULL) return -1; if (hdr->EVENT.N <= n) return -1; uint16_t TYP=hdr->EVENT.TYP[n]; if (typ != NULL) *typ = TYP; if (pos != NULL) *pos = hdr->EVENT.POS[n]; if (chn != NULL) *chn = (hdr->EVENT.CHN==NULL) ? 0 : hdr->EVENT.CHN[n]; if (dur != NULL) *dur = (hdr->EVENT.DUR==NULL) ? 0 : hdr->EVENT.DUR[n]; if (timestamp != NULL) *timestamp = (hdr->EVENT.TimeStamp==NULL) ? 0 : hdr->EVENT.TimeStamp[n]; if ( (desc != NULL) ) *desc = (TYP < hdr->EVENT.LenCodeDesc) ? hdr->EVENT.CodeDesc[TYP] : NULL; return 0; } int biosig_set_nth_event(HDRTYPE *hdr, size_t n, uint16_t* typ, uint32_t *pos, uint16_t *chn, uint32_t *dur, gdf_time *timestamp, char *Desc) { if (hdr==NULL) return -1; if (hdr->EVENT.N <= n) biosig_set_number_of_events(hdr, n+1); if (typ != NULL) hdr->EVENT.TYP[n] = *typ; else if (typ == NULL) FreeTextEvent(hdr, n, Desc); // sets hdr->EVENT.TYP[n] if (pos != NULL) hdr->EVENT.POS[n] = *pos; if (chn != NULL) hdr->EVENT.CHN[n] = *chn; if (dur != NULL) hdr->EVENT.DUR[n] = *dur; if (timestamp != NULL) hdr->EVENT.TimeStamp[n] = *timestamp; return 0; } double biosig_get_eventtable_samplerate(HDRTYPE *hdr) { if (hdr==NULL) return NAN; return hdr->EVENT.SampleRate; } int biosig_set_eventtable_samplerate(HDRTYPE *hdr, double fs) { if (hdr==NULL) return -1; hdr->EVENT.SampleRate=fs; return 0; } int biosig_change_eventtable_samplerate(HDRTYPE *hdr, double fs) { if (hdr==NULL) return -1; if (hdr->EVENT.SampleRate==fs) return 0; size_t k; double ratio = fs/hdr->EVENT.SampleRate; for (k = 0; k < hdr->EVENT.N; k++) { uint32_t POS = hdr->EVENT.POS[k]; hdr->EVENT.POS[k] = ratio*POS; if (hdr->EVENT.DUR != NULL) hdr->EVENT.DUR[k] = (POS + hdr->EVENT.DUR[k]) * ratio - hdr->EVENT.POS[k]; } hdr->EVENT.SampleRate=fs; return 0; } // deprecated because time resolution is lost, use gdftime and its tools instead. __attribute__ ((deprecated)) int biosig_get_startdatetime(HDRTYPE *hdr, struct tm *T) { if (hdr==NULL) return -1; gdf_time2tm_time_r(hdr->T0, T); return (ldexp(hdr->T0,-32)<100.0); } int biosig_set_startdatetime(HDRTYPE *hdr, struct tm T) { if (hdr==NULL) return -1; hdr->T0 = tm_time2gdf_time(&T); return (ldexp(hdr->T0,-32)<100.0); } gdf_time biosig_get_startdatetime_gdf(HDRTYPE *hdr) { if (hdr==NULL) return 0; return(hdr->T0); } int biosig_set_startdatetime_gdf(HDRTYPE *hdr, gdf_time T) { if (hdr==NULL) return -1; hdr->T0 = T; return (ldexp(hdr->T0,-32)<100.0); } // deprecated because time resolution is lost, use gdftime and its tools instead. __attribute__ ((deprecated)) int biosig_get_birthdate(HDRTYPE *hdr, struct tm *T) { if (hdr==NULL) return -1; gdf_time2tm_time_r(hdr->Patient.Birthday, T); return (ldexp(hdr->Patient.Birthday,-32)<100.0); } int biosig_set_birthdate(HDRTYPE *hdr, struct tm T) { if (hdr==NULL) return -1; hdr->Patient.Birthday = tm_time2gdf_time(&T); return (ldexp(hdr->Patient.Birthday,-32)<100.0); } const char* biosig_get_patient_name(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->Patient.Name; } const char* biosig_get_patient_lastname(HDRTYPE *hdr, size_t *LengthLastName) { if (hdr==NULL) return NULL; *LengthLastName = strcspn(hdr->Patient.Name, "\x1f"); return hdr->Patient.Name; } const char* biosig_get_patient_firstname(HDRTYPE *hdr, size_t *LengthFirstName) { if (hdr==NULL) return NULL; char *tmpstr = strchr(hdr->Patient.Name, 0x1f); if (tmpstr==NULL) { *LengthFirstName = 0; return NULL; } *LengthFirstName = strcspn(tmpstr, "\x1f"); return tmpstr; } const char* biosig_get_patient_secondlastname(HDRTYPE *hdr, size_t *LengthSecondLastName) { if (hdr==NULL) return NULL; char *tmpstr = strchr(hdr->Patient.Name, 0x1f); if (tmpstr != NULL) tmpstr = strchr(tmpstr, 0x1f); if (tmpstr==NULL) { *LengthSecondLastName = 0; return NULL; } *LengthSecondLastName = strcspn(tmpstr, "\x1f"); return tmpstr; } const char* biosig_get_patient_id(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->Patient.Id; } const char* biosig_get_recording_id(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->ID.Recording; } const char* biosig_get_technician(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->ID.Technician; } const char* biosig_get_manufacturer_name(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->ID.Manufacturer.Name; } const char* biosig_get_manufacturer_model(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->ID.Manufacturer.Model; } const char* biosig_get_manufacturer_version(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->ID.Manufacturer.Version; } const char* biosig_get_manufacturer_serial_number(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->ID.Manufacturer.SerialNumber; } const char* biosig_get_application_specific_information(HDRTYPE *hdr) { if (hdr==NULL) return NULL; return hdr->AS.bci2000; } int biosig_set_patient_name(HDRTYPE *hdr, const char* name) { if (hdr==NULL) return -1; strncpy(hdr->Patient.Name, name, MAX_LENGTH_NAME); hdr->Patient.Name[MAX_LENGTH_NAME]=0; } int biosig_set_patient_name_structured(HDRTYPE *hdr, const char* LastName, const char* FirstName, const char* SecondLastName) { if (hdr==NULL) return -1; size_t len1 = (LastName ? strlen(LastName) : 0 ); size_t len2 = (FirstName ? strlen(FirstName) : 0 ); size_t len3 = (SecondLastName ? strlen(SecondLastName) : 0 ); if (len1+len2+len3+2 > MAX_LENGTH_NAME) { fprintf(stderr,"Error in function %s(...): total length of name too large (%i > %i)\n",__func__, (int)(len1+len2+len3+2), MAX_LENGTH_NAME); return -1; } strcpy(hdr->Patient.Name, LastName); // Flawfinder: ignore if (FirstName != NULL) { hdr->Patient.Name[len1]=0x1f; strcpy(hdr->Patient.Name+len1+1, FirstName); // Flawfinder: ignore } if (SecondLastName != NULL) { hdr->Patient.Name[len1+len2+1]=0x1f; strcpy(hdr->Patient.Name+len1+len2+2, SecondLastName); // Flawfinder: ignore } return 0; } int biosig_set_patient_id(HDRTYPE *hdr, const char* id) { if (hdr==NULL) return -1; strncpy(hdr->Patient.Id, id, MAX_LENGTH_PID); hdr->Patient.Id[MAX_LENGTH_PID]=0; return 0; } int biosig_set_recording_id(HDRTYPE *hdr, const char* rid) { if (hdr==NULL) return -1; strncpy(hdr->ID.Recording, rid, MAX_LENGTH_RID); hdr->ID.Recording[MAX_LENGTH_RID]=0; return 0; } int biosig_set_technician(HDRTYPE *hdr, const char* technician) { if (hdr==NULL) return -1; hdr->ID.Technician = (char*)technician; return 0; } int biosig_set_manufacturer_name(HDRTYPE *hdr, const char* rid) { if (hdr==NULL) return -1; hdr->ID.Manufacturer.Name = (char*)rid; return 0; } int biosig_set_manufacturer_model(HDRTYPE *hdr, const char* rid) { if (hdr==NULL) return -1; hdr->ID.Manufacturer.Model = rid; return 0; } int biosig_set_manufacturer_version(HDRTYPE *hdr, const char* rid) { if (hdr==NULL) return -1; hdr->ID.Manufacturer.Version = rid; return 0; } int biosig_set_manufacturer_serial_number(HDRTYPE *hdr, const char* rid) { if (hdr==NULL) return -1; hdr->ID.Manufacturer.SerialNumber = rid; return 0; } int biosig_set_application_specific_information(HDRTYPE *hdr, const char* appinfo) { if (hdr==NULL) return -1; hdr->AS.bci2000 = strdup(appinfo); return 0; } // returns M-th channel, M is 0-based CHANNEL_TYPE* biosig_get_channel(HDRTYPE *hdr, int M) { if (hdr==NULL) return NULL; typeof(hdr->NS) k,m; for (k=0,m=0; kNS; k++) if (hdr->CHANNEL[k].OnOff==1) { if (M==m) return hdr->CHANNEL+k; m++; } return NULL; } int biosig_channel_change_scale_to_physdimcode(CHANNEL_TYPE *hc, uint16_t physdimcode) { if (hc==NULL) return -1; if (hc->PhysDimCode == physdimcode) return 0; // nothing to do if ( (hc->PhysDimCode & 0xffe0) != (physdimcode & 0xffe0) ) return -2; // units do not match double scale = PhysDimScale(hc->PhysDimCode); scale /= PhysDimScale(physdimcode); hc->PhysDimCode = physdimcode; hc->PhysMax *= scale; hc->PhysMin *= scale; hc->Cal *= scale; hc->Off *= scale; return(0); } const char* biosig_channel_get_label(CHANNEL_TYPE *hc) { if (hc==NULL) return NULL; return hc->Label; } uint16_t biosig_channel_get_physdimcode(CHANNEL_TYPE *hc) { if (hc==NULL) return 0; return hc->PhysDimCode; } const char* biosig_channel_get_physdim(CHANNEL_TYPE *hc) { if (hc==NULL) return NULL; return PhysDim3(hc->PhysDimCode); } int biosig_channel_set_label(CHANNEL_TYPE *hc, const char* label) { if (hc==NULL) return -1; strncpy(hc->Label, label, MAX_LENGTH_LABEL); hc->Label[MAX_LENGTH_LABEL]=0; return 0; } int biosig_channel_set_physdimcode(CHANNEL_TYPE *hc, uint16_t physdimcode) { if (hc==NULL) return -1; hc->PhysDimCode = physdimcode; return 0; } int biosig_channel_get_scaling(CHANNEL_TYPE *hc, double *PhysMax, double *PhysMin, double *DigMax, double *DigMin) { if (hc==NULL) return -1; if (PhysMax != NULL) *PhysMax = hc->PhysMax; if (PhysMin != NULL) *PhysMax = hc->PhysMin; if (DigMax != NULL) *DigMax = hc->DigMax; if (DigMin != NULL) *DigMin = hc->DigMin; return 0; } int biosig_channel_set_scaling(CHANNEL_TYPE *hc, double PhysMax, double PhysMin, double DigMax, double DigMin) { if (hc==NULL) return -1; hc->PhysMax = PhysMax; hc->PhysMin = PhysMin; hc->DigMax = DigMax; hc->DigMin = DigMin; hc->Cal = ( PhysMax - PhysMin) / ( DigMax - DigMin ); hc->Off = PhysMin - DigMin * hc->Cal; return 0; } double biosig_channel_get_cal(CHANNEL_TYPE *hc) { if (hc==NULL) return -1; double cal = ( hc->PhysMax - hc->PhysMin) / ( hc->DigMax - hc->DigMin ); assert(cal==hc->Cal); return (cal); } double biosig_channel_get_off(CHANNEL_TYPE *hc) { if (hc==NULL) return -1; double off = hc->PhysMin - hc->DigMin * hc->Cal; assert(off==hc->Off); return off; } int biosig_channel_set_cal(CHANNEL_TYPE *hc, double cal) { if (hc==NULL) return -1; hc->Cal = cal; return 0; } int biosig_channel_set_off(CHANNEL_TYPE *hc, double off) { if (hc==NULL) return -1; hc->Off = off; return 0; } int biosig_channel_get_filter(CHANNEL_TYPE *hc, double *LowPass, double *HighPass, double *Notch) { if (hc==NULL) return -1; if (LowPass != NULL) *LowPass = hc->LowPass; if (HighPass != NULL) *HighPass = hc->HighPass; if (Notch != NULL) *Notch = hc->Notch; return 0; } int biosig_channel_set_filter(CHANNEL_TYPE *hc, double LowPass, double HighPass, double Notch) { if (hc==NULL) return -1; hc->LowPass = LowPass; hc->HighPass = HighPass; hc->Notch = Notch; return 0; } double biosig_channel_get_timing_offset(CHANNEL_TYPE *hc) { if (hc==NULL) return -1; return hc->TOffset; } int biosig_channel_set_timing_offset(CHANNEL_TYPE *hc, double off) { if (hc==NULL) return -1; hc->TOffset = off; return 0; } double biosig_channel_get_impedance(CHANNEL_TYPE *hc) { if (hc==NULL) return -1; return ( (hc->PhysDimCode & 0x7ffe) == 4256 ) ? hc->Impedance : NAN; } int biosig_channel_set_impedance(CHANNEL_TYPE *hc, double val) { if (hc==NULL) return -1; if ( (hc->PhysDimCode & 0x7ffe) != 4256 ) return -1; hc->Impedance = val; return 0; } uint16_t biosig_channel_get_datatype(CHANNEL_TYPE *hc) { if (hc==NULL) return -1; return hc->GDFTYP; } int biosig_channel_set_datatype(CHANNEL_TYPE *hc, uint16_t gdftyp) { if (hc==NULL) return -1; hc->GDFTYP = gdftyp; return 0; } double biosig_get_channel_samplerate(HDRTYPE *hdr, int chan) { CHANNEL_TYPE *hc = biosig_get_channel(hdr, chan); if (hc==NULL) return -1; if (hdr==NULL) return -1; return (hdr->SampleRate * hc->SPR / hdr->SPR); } size_t biosig_channel_get_samples_per_record(CHANNEL_TYPE *hc) { if (hc==NULL) return -1; return hc->SPR; } int biosig_channel_set_samples_per_record(CHANNEL_TYPE *hc, size_t spr) { if (hc==NULL) return -1; hc->SPR = spr; return 0; } int biosig_set_channel_samplerate_and_samples_per_record(HDRTYPE *hdr, int chan, ssize_t spr, double fs) { CHANNEL_TYPE *hc = biosig_get_channel(hdr,chan); if (hc==NULL) return -1; if ((spr <= 0) && (fs >= 0.0)) { hc->SPR = hdr->SPR * fs / hdr->SampleRate; return 0; } if ((spr >= 0) && (fs != fs)) { hc->SPR = spr; return 0; } assert (hdr->SampleRate * hc->SPR == fs * hdr->SPR); return (hdr->SampleRate * hc->SPR != fs * hdr->SPR); } const char *biosig_channel_get_transducer(CHANNEL_TYPE *hc) { if (hc==NULL) return(NULL); return (hc->Transducer); } int biosig_channel_set_transducer(CHANNEL_TYPE *hc, const char *transducer) { if (hc==NULL) return(-1); strncpy(hc->Transducer, transducer, MAX_LENGTH_TRANSDUCER+1); return (0); } /* DO NOT USE DO NOT USE DO NOT USE DO NOT USE the functions below are experimental and have not been used so far in any productions system They will be removed or significantly changed . DO NOT USE DO NOT USE DO NOT USE DO NOT USE */ #define hdrlistlen 64 struct hdrlist_t { HDRTYPE *hdr; // header information as defined in level 1 interface //const char *filename; // name of file, is always hdr->FileName uint16_t NS; // number of effective channels, only CHANNEL[].OnOff==1 are considered size_t *chanpos; // position of file handle for each channel } ; struct hdrlist_t hdrlist[hdrlistlen]; CHANNEL_TYPE *getChannelHeader(HDRTYPE *hdr, uint16_t channel) { // returns channel header - skip Off-channels CHANNEL_TYPE *hc = hdr->CHANNEL; typeof(hdr->NS) chan = 0; while (1) { if (hc->OnOff==1) { if (chan==channel) return hc; chan++; } hc++; } return NULL; } int biosig_lib_version(void) { return (BIOSIG_VERSION); } biosig_handle_t biosig2_open_file_readonly(const char *path, int read_annotations) { /* on success returns handle. */ HDRTYPE *hdr = sopen(path,"r",NULL); if (serror2(hdr)) { destructHDR(hdr); return(NULL); } if (read_annotations) sort_eventtable(hdr); return(hdr); } int biosig_open_file_readonly(const char *path, int read_annotations) { /* on success returns handle. */ int k = 0; while (k < hdrlistlen && hdrlist[k].hdr != NULL) k++; if (k >= hdrlistlen) return(-1); HDRTYPE *hdr = sopen(path,"r",NULL); hdrlist[k].hdr = hdr; //hdrlist[k].filename = hdr->FileName; hdrlist[k].NS = 0; hdrlist[k].chanpos = calloc(hdrlist[k].NS,sizeof(size_t)); if (read_annotations) sort_eventtable(hdrlist[k].hdr); return(k); } int biosig2_close_file(biosig_handle_t hdr) { destructHDR(hdr); return(0); } int biosig_close_file(int handle) { destructHDR(hdrlist[handle].hdr); hdrlist[handle].hdr = NULL; if (hdrlist[handle].chanpos) free(hdrlist[handle].chanpos); hdrlist[handle].NS = 0; //hdrlist[handle].filename = NULL; #if 0 int k; for (k=0; k= hdrlistlen || hdrlist[handle].hdr==NULL || hdrlist[handle].NS<=channel ) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; CHANNEL_TYPE *hc = getChannelHeader(hdr,channel); size_t stride = 1; // stride between consecutive samples of same channel, depends on data orientation hdr->FLAG.ROW_BASED_CHANNELS size_t div = hdr->SPR/hc->SPR; // stride if sample rate of channel is smaller than the overall sampling rate size_t POS = hdrlist[handle].chanpos[channel]*div; // size_t LEN = n*div; size_t startpos = POS/hdr->SPR; // round towards 0 size_t endpos = (POS+LEN)/hdr->SPR + ((POS+LEN)%hdr->SPR != 0); // round towards infinity if (hdr->AS.first > startpos || (endpos-startpos) > hdr->AS.length || hdr->FLAG.UCAL!=UCAL) { // read data when not in data buffer hdr->data.block hdr->FLAG.UCAL = UCAL; sread(NULL, startpos, endpos - startpos, hdr); } // when starting position is not aligned with start of data size_t offset = hdr->AS.first * hdr->SPR - POS; // find starting position and stride of data double *data = hdr->data.block; if (hdr->FLAG.ROW_BASED_CHANNELS) { stride = hdr->data.size[0]; data = hdr->data.block + channel + offset * stride; } else { data = hdr->data.block + offset + channel * hdr->data.size[0]; } size_t k; for (k = 0; k < n; k++) { buf[k] = data[k*div*stride]; // copy data into output buffer } hdrlist[handle].chanpos[channel] += n; // update position pointer of channel chan return (0); } /* int biosig_read_physical_samples(int handle, size_t biosig_signal, size_t n, double *buf) { return biosig_read_samples(handle, biosig_signal, n, buf, (unsigned char)(0)); } int biosig_read_digital_samples(int handle, size_t biosig_signal, size_t n, double *buf) { return biosig_read_samples(handle, biosig_signal, n, buf, (unsigned char)(1)); } */ size_t biosig_seek(int handle, long long offset, int whence) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; sseek(hdr, offset, whence); return (hdr->FILE.POS); } size_t biosig_tell(int handle) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); return(stell(hdrlist[handle].hdr)); } void biosig_rewind(int handle, int biosig_signal) { /* It is equivalent to: (void) biosig_seek(int handle, int biosig_signal, 0LL, biosig_SEEK_SET) */ if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return; srewind(hdrlist[handle].hdr); } biosig_handle_t biosig2_open_file_writeonly(const char *path, enum FileFormat filetype, int number_of_signals) { /* TODO: does not open file and write to file */ HDRTYPE *hdr = constructHDR(number_of_signals,0); hdr->FLAG.UCAL = 0; hdr->FLAG.OVERFLOWDETECTION = 0; hdr->FILE.COMPRESSION = 0; return(hdr); } int biosig_open_file_writeonly(const char *path, enum FileFormat filetype, int number_of_signals) { /* TODO: does not open file and write to file */ #if 1 int k = 0; while (k < hdrlistlen && hdrlist[k].hdr != NULL) k++; if (k>=hdrlistlen) return -1; HDRTYPE *hdr = constructHDR(number_of_signals,0); #else HDRTYPE *hdr = constructHDR(number_of_signals,0); if (hdr==NULL) return (-1); hdr->FileName = strdup(path); hdr->TYPE = filetype; int k = 0; while (k < hdrlistlen && hdrlist[k].hdr != NULL) k++; if (k>=hdrlistlen) { void *ptr = realloc(hdrlist, (k+1)*sizeof(*hdrlist)); if (ptr==NULL) return (-1); hdrlist = (struct hdrlist_t*) ptr; hdrlistlen = k+1; } #endif hdr->FLAG.UCAL = 0; hdr->FLAG.OVERFLOWDETECTION = 0; hdr->FILE.COMPRESSION = 0; hdrlist[k].hdr = hdr; return(0); } double biosig_get_global_samplefrequency(int handle) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NAN); return (hdrlist[handle].hdr->SampleRate); } int biosig_set_global_samplefrequency(int handle, double samplefrequency) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); hdrlist[handle].hdr->SampleRate = samplefrequency; return 0; } double biosig_get_samplefrequency(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NAN); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NAN); return (hdr->SampleRate*hdr->CHANNEL[biosig_signal].SPR/hdr->SPR); } int biosig_set_samplefrequency(int handle, int biosig_signal, double samplefrequency) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = 0; int ch; for (ch = 0; ch < hdr->NS; ch++) { if (hdr->CHANNEL[ch].OnOff==1) { if (ns==biosig_signal) break; ns++; } } if (ch >= hdr->NS) return(-1); // FIXME: resulting sampling rate might depend on calling order; what's the overall sampling rate ? if (samplefrequency != hdr->SampleRate) { double spr = samplefrequency * hdr->SPR / hdr->SampleRate; hdr->CHANNEL[biosig_signal].SPR = spr; if (spr != ceil(spr)) return (-2); return 0; } hdr->CHANNEL[ch].SPR = hdr->SPR; return 0; } double biosig_get_physical_maximum(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NAN); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NAN); return (hdr->CHANNEL[biosig_signal].PhysMax); } int biosig_set_physical_maximum(int handle, int biosig_signal, double phys_max) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].PhysMax = phys_max; return (0); } double biosig_get_physical_minimum(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NAN); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NAN); return (hdr->CHANNEL[biosig_signal].PhysMin); } int biosig_set_physical_minimum(int handle, int biosig_signal, double phys_min) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].PhysMin = phys_min; return (0); } double biosig_get_digital_maximum(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NAN); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NAN); return (hdr->CHANNEL[biosig_signal].DigMax); } int biosig_set_digital_maximum(int handle, int biosig_signal, double dig_max) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].DigMax = dig_max; return (0); } double biosig_get_digital_minimum(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NAN); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NAN); return (hdr->CHANNEL[biosig_signal].DigMin); } int biosig_set_digital_minimum(int handle, int biosig_signal, double dig_min) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].DigMin = dig_min; return (0); } const char *biosig_get_label(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NULL); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NULL); return (hdr->CHANNEL[biosig_signal].Label); } int biosig_set_label(int handle, int biosig_signal, const char *label) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); strncpy(hdr->CHANNEL[biosig_signal].Label, label, MAX_LENGTH_LABEL); return (0); } int biosig_set_prefilter(int handle, int biosig_signal, const char *prefilter) { // TODO: parse prefilter and call biosig_set_{highpass,lowpass,notch}filter return fprintf(stderr,"Warning: biosig_set_prefilter(...) is not implemented, use instead biosig_set_highpassfilter(),biosig_set_lowpassfilter(),biosig_set_notchfilter().\n"); } int biosig_set_highpassfilter(int handle, int biosig_signal, double frequency) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].HighPass = frequency; return 0; } int biosig_set_lowpassfilter(int handle, int biosig_signal, double frequency) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].LowPass = frequency; return 0; } int biosig_set_notchfilter(int handle, int biosig_signal, double frequency) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].Notch = frequency; return (0); } const char *biosig_get_transducer(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NULL); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NULL); return (hdr->CHANNEL[biosig_signal].Transducer); } int biosig_set_transducer(int handle, int biosig_signal, const char *transducer) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); strncpy(hdr->CHANNEL[biosig_signal].Transducer, transducer, MAX_LENGTH_TRANSDUCER+1); return (0); } const char *biosig_physical_dimension(int handle, int biosig_signal) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NULL); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(NULL); return (PhysDim3(hdr->CHANNEL[biosig_signal].PhysDimCode)); } int biosig_set_physical_dimension(int handle, int biosig_signal, const char *phys_dim) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; typeof(hdr->NS) ns = hdr->NS; if (biosig_signal >= ns) return(-1); hdr->CHANNEL[biosig_signal].PhysDimCode = PhysDimCode(phys_dim); return (0); } int edf_set_startdatetime(int handle, int startdate_year, int startdate_month, int startdate_day, int starttime_hour, int starttime_minute, int starttime_second) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; struct tm T; T.tm_year = startdate_year; T.tm_mon = startdate_month; T.tm_mday = startdate_day; T.tm_hour = starttime_hour; T.tm_min = starttime_minute; T.tm_sec = starttime_second; hdr->T0 = tm_time2gdf_time(&T); return (0); } const char *biosig_get_patientname(int handle) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NULL); return(hdrlist[handle].hdr->Patient.Name); } int biosig_set_patientname(int handle, const char *patientname) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); strncpy(hdrlist[handle].hdr->Patient.Name, patientname, MAX_LENGTH_NAME+1); return (0); } const char *biosig_get_patientcode(int handle) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NULL); return(hdrlist[handle].hdr->Patient.Id); } int biosig_set_patientcode(int handle, const char *patientcode) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); strncpy(hdrlist[handle].hdr->Patient.Id, patientcode, MAX_LENGTH_PID+1); return(0); } int biosig_get_gender(int handle) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(0); return(hdrlist[handle].hdr->Patient.Sex); } int biosig_set_gender(int handle, int gender) { if (gender<0 || gender>9) return (-1); if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); switch (gender) { case 1 : case 'm': case 'M': hdrlist[handle].hdr->Patient.Sex = 1; return(0); case 2 : case 'f': case 'F': hdrlist[handle].hdr->Patient.Sex = 2; return(0); default: return(0); } } int edf_set_birthdate(int handle, int birthdate_year, int birthdate_month, int birthdate_day) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; struct tm T; T.tm_year = birthdate_year; T.tm_mon = birthdate_month; T.tm_mday = birthdate_day; T.tm_hour = 12; T.tm_min = 0; T.tm_sec = 0; hdr->Patient.Birthday = tm_time2gdf_time(&T); return (0); } int biosig_set_patient_additional(int handle, const char *patient_additional) { fprintf(stderr,"Warning: biosig_set_patient_additional() not supported.\n"); return (-1); } int biosig_set_admincode(int handle, const char *admincode) { fprintf(stderr,"Warning: biosig_set_admincode() not supported.\n"); return (-1); } /* const char *biosig_get_technician(int handle) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(NULL); HDRTYPE *hdr = hdrlist[handle].hdr; return(hdr->ID.Technician); } int biosig_set_technician(int handle, const char *technician) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; hdr->ID.Technician = realloc(hdr->ID.Technician, strlen(technician)+1); strcpy(hdr->ID.Technician, technician); return(0); } */ // TODO: implement the following functions int biosig_set_equipment(int handle, const char *equipment) { return (-1); } int biosig_set_recording_additional(int handle, const char *recording_additional) { return (-1); } int biosig_write_physical_samples(int handle, double *buf) { return (-1); } int biosig_blockwrite_physical_samples(int handle, double *buf) { return (-1); } int biosig_write_digital_samples(int handle, int *buf) { return (-1); } int biosig_blockwrite_digital_samples(int handle, int *buf) { return (-1); } int biosig_write_annotation(int handle, size_t onset, size_t duration, const char *description) { /* onset and duration are in samples */ if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; size_t N = hdr->EVENT.N++; hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, hdr->EVENT.N*sizeof(*(hdr->EVENT.POS)) ); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, hdr->EVENT.N*sizeof(*(hdr->EVENT.TYP)) ); hdr->EVENT.DUR = (uint32_t*) realloc(hdr->EVENT.DUR, hdr->EVENT.N*sizeof(*(hdr->EVENT.DUR)) ); hdr->EVENT.CHN = (uint16_t*) realloc(hdr->EVENT.CHN, hdr->EVENT.N*sizeof(*(hdr->EVENT.CHN)) ); hdr->EVENT.POS[N] = onset; hdr->EVENT.DUR[N] = duration; hdr->EVENT.CHN[N] = 0; FreeTextEvent(hdr, N, description); return (hdr->AS.B4C_ERRNUM); } int biosig_write_annotation_utf8(int handle, size_t onset, size_t duration, const char *description) { fprintf(stdout,"biosig_write_annotation_latin1(): It's recommended to use biosig_write_annotation() instead.\n"); return ( biosig_write_annotation(handle, onset, duration, description) ); } int biosig_write_annotation_latin1(int handle, size_t onset, size_t duration, const char *description) { fprintf(stdout,"biosig_write_annotation_latin1(): It's recommended to use biosig_write_annotation() instead.\n"); return ( biosig_write_annotation(handle, onset, duration, description) ); } int biosig_set_datarecord_duration(int handle, double duration) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; double spr = hdr->SampleRate * duration; size_t rspr = round(spr); if (fabs(spr - rspr) > 1e-8*spr) { fprintf(stderr,"Warning biosig_set_datarecord_duration(): number of samples is not integer (%g) - rounded to integers (%i)\n",spr,(int)rspr); } hdr->SPR = (size_t)rspr; return 0; } /****************************************************************************************** biosig_unserialize_header: converts memory buffer into header structure HDR biosig_unserialize: converts memory buffer into header structure HDR, and if data != NULL, data samples will be read into a matrix, the starting address of this data matrix will be stored in *data point to *data input: mem : buffer len : length of buffer mem start: starting position to extract data length: number of samples for extracting data, flags: BIOSIG_FLAG_UCAL | BIOSIG_FLAG_OVERFLOWDETECTION | BIOSIG_FLAG_ROW_BASED_CHANNELS output: *data will contain start address to matrix data samples, of size hdr->NS * (hdr->SPR * hdr->NRec) or its transpose form depending on flags return value: header structure HDRTYPE* hdr. ******************************************************************************************/ HDRTYPE* biosig_unserialize(void *mem, size_t len, size_t start, size_t length, biosig_data_type **data, int flags) { fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); HDRTYPE *hdr = constructHDR(0,0); // decode header fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); hdr->AS.Header = mem; // in case of error, memory is deallocated through destructHDR(hdr); if (gdfbin2struct(hdr)) return(hdr); // in case of success, memory is managed by its own pointer *mem hdr->AS.Header = NULL; fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); // get data block biosig_set_flag(hdr, flags); if (data != NULL) { hdr->AS.rawdata = mem+hdr->HeadLen; size_t L = sread(*data, start, length, hdr); *data = hdr->data.block; hdr->data.block = NULL; } hdr->AS.rawdata = NULL; fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); // read eventtable hdr->AS.rawEventData = (hdr->NRec != -1) ? mem + hdr->HeadLen + hdr->NRec*hdr->AS.bpb : NULL; rawEVT2hdrEVT(hdr, len - hdr->HeadLen - hdr->NRec*hdr->AS.bpb); // in case of success, memory is managed by its own pointer *mem hdr->AS.rawEventData = NULL; fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); return(hdr); } /****************************************************************************************** biosig_serialize: converts header structure into memory buffer input: hdr: header structure, including event table. output: *mem will contain start address of buffer *len will contain length of buffer mem. ******************************************************************************************/ void* biosig_serialize(HDRTYPE *hdr, void **mem, size_t *len) { // encode header fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); hdr->TYPE=GDF; hdr->VERSION=3.0; struct2gdfbin(hdr); fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); // write event table size_t len3 = hdrEVT2rawEVT(hdr); fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); size_t len0 = hdr->HeadLen + hdr->NRec*hdr->AS.bpb + len3; char* M = (char*)realloc(*mem,len0); if (M == NULL) return(NULL); *mem = M; *len = len0; // write header into buffer memcpy(M, hdr->AS.Header, hdr->HeadLen); fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); // write data into buffer, and collapse unused channels size_t count = sread_raw(0, hdr->NRec, hdr, 1, M + hdr->HeadLen, hdr->NRec*hdr->AS.bpb); fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); // write event table into buffer memcpy(M + hdr->HeadLen + hdr->NRec*hdr->AS.bpb, hdr->AS.rawEventData, len3); fprintf(stdout,"%s (line %i) %s:\n",__FILE__,__LINE__,__func__); return(M); } #if defined(MAKE_EDFLIB) int edfopen_file_writeonly(const char *path, int filetype, int number_of_signals) { enum FileFormat fmt=unknown; switch (filetype) { case EDFLIB_FILETYPE_EDF: case EDFLIB_FILETYPE_EDFPLUS: fmt = EDF; break; case EDFLIB_FILETYPE_BDF: case EDFLIB_FILETYPE_BDFPLUS: fmt = EDF; break; default: return(-1); } return(biosig_open_file_writeonly(path, fmt, number_of_signals)); } int edf_set_gender(int handle, int gender) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; hdr->Patient.Sex = (gender==1) + (gender==0)*2 ; } int edfread_physical_samples(int handle, int edfsignal, int n, double *buf) { fprintf(stderr,"error: edfread_physical_samples - use biosig_read_physical_samples instead.\n"); return(-1); } int edfread_digital_samples(int handle, int edfsignal, int n, int *buf) { fprintf(stderr,"error: edfread_digital_samples - use biosig_read_digital_samples instead.\n"); return(-1); } long long edfseek(int handle, int channel, long long offset, int whence) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL || hdrlist[handle].NS<=channel ) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; switch (whence) { case SEEK_SET: hdrlist[handle].chanpos[channel] = offset; // update position pointer of channel chan break; case SEEK_CUR: hdrlist[handle].chanpos[channel] += offset; // update position pointer of channel chan break; case SEEK_END: { CHANNEL_TYPE *hc = getChannelHeader(hdr,channel); hdrlist[handle].chanpos[channel] = hdr->NRec*hc->SPR + offset; // update position pointer of channel chan break; } } return (hdrlist[handle].chanpos[channel]); } long long edftell(int handle, int channel) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL || hdrlist[handle].NS<=channel ) return(-1); return ( hdrlist[handle].chanpos[channel] ); } int edfrewind(int handle, int channel) { /* It is equivalent to: (void) edf_seek(int handle, int biosig_signal, 0LL, SEEK_SET) */ if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL || hdrlist[handle].NS<=channel ) return(-1); hdrlist[handle].chanpos[channel] = 0; return(0); } int edf_get_annotation(int handle, int n, struct edf_annotation_struct *annot) { if (handle<0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; annot->onset = hdr->EVENT.POS[n]*1e4/hdr->EVENT.SampleRate; annot->duration = hdr->EVENT.DUR[n]*1e4/hdr->EVENT.SampleRate; strncpy(annot->annotation,GetEventDescription(hdr, n),sizeof(annot->annotation)); return(0); } int edfwrite_annotation(int handle, size_t onset, size_t duration, const char *description) { /* onset and duration are multiples of 100 microseconds */ if (handle < 0 || handle >= hdrlistlen || hdrlist[handle].hdr==NULL) return(-1); HDRTYPE *hdr = hdrlist[handle].hdr; return (biosig_write_annotation(handle, onset*1e-4*hdr->EVENT.SampleRate, duration*1e-4*hdr->EVENT.SampleRate, description)); } /* TODO: the following functions neeed to be implemented */ int edf_set_recording_additional(int handle, const char *recording_additional) { return fprintf(stderr,"this function is not implemented, yet.\n"); } int edfwrite_physical_samples(int handle, double *buf) { return fprintf(stderr,"this function is not implemented, yet.\n"); } int edf_blockwrite_physical_samples(int handle, double *buf) { return fprintf(stderr,"this function is not implemented, yet.\n"); } /* int edfwrite_digital_samples(int handle, int *buf) { return fprintf(stderr,"this function is not implemented, yet.\n"); } */ int edf_blockwrite_digital_samples(int handle, int *buf) { return fprintf(stderr,"this function is not implemented, yet.\n"); } #endif stimfit-0.16.7/src/biosig/biosig4c++/biosig2.h0000664000175000017500000000160414752215315014360 /* Copyright (C) 2017 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ // #error Instead of biosig2.h use #include #include "biosig.h" stimfit-0.16.7/src/biosig/biosig4c++/mdc_ecg_codes.c0000664000175000017500000000454314752215315015560 /* Copyright (C) 2014 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "mdc_ecg_codes.h" /* physical units are defined in IEEE/ISO 11073-10102-Annex B */ const struct mdc_code_table { const uint16_t code10; const uint32_t cf_code10; const char* refid; } MDC_CODE_TABLE[] = { #include "11073-10102-AnnexB.i" {0xffff, 0xffffffff, "MDC_ECG_ERROR_CODE" } } ; /* Conversion between MDC Refid and CODE10 encoding Currently, a simple lookup table is used, Eventually, this can be made more efficient */ uint16_t encode_mdc_ecg_code10(const char *IDstr) { if ( !memcmp(IDstr,"MDC_ECG_", 8) ) return 0xffff; uint32_t k; for (k=0; MDC_CODE_TABLE[k].cf_code10 < 0xffffffff; k++) { if (! strcmp(IDstr+8, MDC_CODE_TABLE[k].refid+8) ) return MDC_CODE_TABLE[k].code10; } return 0xffff; } uint32_t encode_mdc_ecg_cfcode10(const char *IDstr) { if ( !memcmp(IDstr,"MDC_ECG_", 8) ) return 0xffffffff; size_t k; for (k=0; MDC_CODE_TABLE[k].cf_code10 < 0xffffffff; k++) { if ( !strcmp(IDstr+8, MDC_CODE_TABLE[k].refid+8) ) return MDC_CODE_TABLE[k].cf_code10; } return 0xffffffff; } const char* decode_mdc_ecg_code10(uint16_t code10) { uint32_t k; for (k=0; MDC_CODE_TABLE[k].cf_code10 < 0xffffffff; k++) { if ( code10 == MDC_CODE_TABLE[k].code10 ) return MDC_CODE_TABLE[k].refid; } return NULL; } const char* decode_mdc_ecg_cfcode10(uint32_t cf_code10) { uint32_t k; for (k=0; MDC_CODE_TABLE[k].cf_code10 < 0xffffffff; k++) { if ( cf_code10 == MDC_CODE_TABLE[k].cf_code10 ) return MDC_CODE_TABLE[k].refid; } return NULL; } stimfit-0.16.7/src/biosig/biosig4c++/XMLParser/0000775000175000017500000000000014764352501014547 5stimfit-0.16.7/src/biosig/biosig4c++/XMLParser/tinystr.cpp0000664000175000017500000000471314752215315016712 /* www.sourceforge.net/projects/tinyxml This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #ifndef TIXML_USE_STL #include "tinystr.h" // Error value for find primitive const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); // Null rep. TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; void TiXmlString::reserve (size_type cap) { if (cap > capacity()) { TiXmlString tmp; tmp.init(length(), cap); memcpy(tmp.start(), data(), length()); swap(tmp); } } TiXmlString& TiXmlString::assign(const char* str, size_type len) { size_type cap = capacity(); if (len > cap || cap > 3*(len + 8)) { TiXmlString tmp; tmp.init(len); memcpy(tmp.start(), str, len); swap(tmp); } else { memmove(start(), str, len); set_size(len); } return *this; } TiXmlString& TiXmlString::append(const char* str, size_type len) { size_type newsize = length() + len; if (newsize > capacity()) { reserve (newsize + capacity()); } memmove(finish(), str, len); set_size(newsize); return *this; } TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) { TiXmlString tmp; tmp.reserve(a.length() + b.length()); tmp += a; tmp += b; return tmp; } TiXmlString operator + (const TiXmlString & a, const char* b) { TiXmlString tmp; TiXmlString::size_type b_len = static_cast( strlen(b) ); tmp.reserve(a.length() + b_len); tmp += a; tmp.append(b, b_len); return tmp; } TiXmlString operator + (const char* a, const TiXmlString & b) { TiXmlString tmp; TiXmlString::size_type a_len = static_cast( strlen(a) ); tmp.reserve(a_len + b.length()); tmp.append(a, a_len); tmp += b; return tmp; } #endif // TIXML_USE_STL stimfit-0.16.7/src/biosig/biosig4c++/XMLParser/tinyxmlparser.cpp0000664000175000017500000011057214752215315020120 /* www.sourceforge.net/projects/tinyxml Original code by Lee Thomason (www.grinninglizard.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #include #include #include "tinyxml.h" //#define DEBUG_PARSER #if defined( DEBUG_PARSER ) # if defined( DEBUG ) && defined( _MSC_VER ) # include # define TIXML_LOG OutputDebugString # else # define TIXML_LOG printf # endif #endif // Note tha "PutString" hardcodes the same list. This // is less flexible than it appears. Changing the entries // or order will break putstring. TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] = { { "&", 5, '&' }, { "<", 4, '<' }, { ">", 4, '>' }, { """, 6, '\"' }, { "'", 6, '\'' } }; // Bunch of unicode info at: // http://www.unicode.org/faq/utf_bom.html // Including the basic of this table, which determines the #bytes in the // sequence from the lead byte. 1 placed for invalid sequences -- // although the result will be junk, pass it through as much as possible. // Beware of the non-characters in UTF-8: // ef bb bf (Microsoft "lead bytes") // ef bf be // ef bf bf const unsigned char TIXML_UTF_LEAD_0 = 0xefU; const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; const int TiXmlBase::utf8ByteTable[256] = { // 0 1 2 3 4 5 6 7 8 9 a b c d e f 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid }; void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) { const unsigned long BYTE_MASK = 0xBF; const unsigned long BYTE_MARK = 0x80; const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; if (input < 0x80) *length = 1; else if ( input < 0x800 ) *length = 2; else if ( input < 0x10000 ) *length = 3; else if ( input < 0x200000 ) *length = 4; else { *length = 0; return; } // This code won't covert this correctly anyway. output += *length; // Scary scary fall throughs. switch (*length) { case 4: --output; *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; case 3: --output; *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; case 2: --output; *output = (char)((input | BYTE_MARK) & BYTE_MASK); input >>= 6; case 1: --output; *output = (char)(input | FIRST_BYTE_MARK[*length]); } } /*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) { // This will only work for low-ascii, everything else is assumed to be a valid // letter. I'm not sure this is the best approach, but it is quite tricky trying // to figure out alhabetical vs. not across encoding. So take a very // conservative approach. // if ( encoding == TIXML_ENCODING_UTF8 ) // { if ( anyByte < 127 ) return isalpha( anyByte ); else return 1; // What else to do? The unicode set is huge...get the english ones right. // } // else // { // return isalpha( anyByte ); // } } /*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) { // This will only work for low-ascii, everything else is assumed to be a valid // letter. I'm not sure this is the best approach, but it is quite tricky trying // to figure out alhabetical vs. not across encoding. So take a very // conservative approach. // if ( encoding == TIXML_ENCODING_UTF8 ) // { if ( anyByte < 127 ) return isalnum( anyByte ); else return 1; // What else to do? The unicode set is huge...get the english ones right. // } // else // { // return isalnum( anyByte ); // } } class TiXmlParsingData { friend class TiXmlDocument; public: void Stamp( const char* now, TiXmlEncoding encoding ); const TiXmlCursor& Cursor() const { return cursor; } private: // Only used by the document! TiXmlParsingData( const char* start, int _tabsize, int row, int col ) { assert( start ); stamp = start; tabsize = _tabsize; cursor.row = row; cursor.col = col; } TiXmlCursor cursor; const char* stamp; int tabsize; }; void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) { assert( now ); // Do nothing if the tabsize is 0. if ( tabsize < 1 ) { return; } // Get the current row, column. int row = cursor.row; int col = cursor.col; const char* p = stamp; assert( p ); while ( p < now ) { // Treat p as unsigned, so we have a happy compiler. const unsigned char* pU = (const unsigned char*)p; // Code contributed by Fletcher Dunn: (modified by lee) switch (*pU) { case 0: // We *should* never get here, but in case we do, don't // advance past the terminating null character, ever return; case '\r': // bump down to the next line ++row; col = 0; // Eat the character ++p; // Check for \r\n sequence, and treat this as a single character if (*p == '\n') { ++p; } break; case '\n': // bump down to the next line ++row; col = 0; // Eat the character ++p; // Check for \n\r sequence, and treat this as a single // character. (Yes, this bizarre thing does occur still // on some arcane platforms...) if (*p == '\r') { ++p; } break; case '\t': // Eat the character ++p; // Skip to next tab stop col = (col / tabsize + 1) * tabsize; break; case TIXML_UTF_LEAD_0: if ( encoding == TIXML_ENCODING_UTF8 ) { if ( *(p+1) && *(p+2) ) { // In these cases, don't advance the column. These are // 0-width spaces. if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) p += 3; else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) p += 3; else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) p += 3; else { p +=3; ++col; } // A normal character. } } else { ++p; ++col; } break; default: if ( encoding == TIXML_ENCODING_UTF8 ) { // Eat the 1 to 4 byte utf8 character. int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; if ( step == 0 ) step = 1; // Error case from bad encoding, but handle gracefully. p += step; // Just advance one column, of course. ++col; } else { ++p; ++col; } break; } } cursor.row = row; cursor.col = col; assert( cursor.row >= -1 ); assert( cursor.col >= -1 ); stamp = p; assert( stamp ); } const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) { if ( !p || !*p ) { return 0; } if ( encoding == TIXML_ENCODING_UTF8 ) { while ( *p ) { const unsigned char* pU = (const unsigned char*)p; // Skip the stupid Microsoft UTF-8 Byte order marks if ( *(pU+0)==TIXML_UTF_LEAD_0 && *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) { p += 3; continue; } else if(*(pU+0)==TIXML_UTF_LEAD_0 && *(pU+1)==0xbfU && *(pU+2)==0xbeU ) { p += 3; continue; } else if(*(pU+0)==TIXML_UTF_LEAD_0 && *(pU+1)==0xbfU && *(pU+2)==0xbfU ) { p += 3; continue; } if ( IsWhiteSpace( *p ) ) // Still using old rules for white space. ++p; else break; } } else { while ( *p && IsWhiteSpace( *p ) ) ++p; } return p; } #ifdef TIXML_USE_STL /*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) { for( ;; ) { if ( !in->good() ) return false; int c = in->peek(); // At this scope, we can't get to a document. So fail silently. if ( !IsWhiteSpace( c ) || c <= 0 ) return true; *tag += (char) in->get(); } } /*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) { //assert( character > 0 && character < 128 ); // else it won't work in utf-8 while ( in->good() ) { int c = in->peek(); if ( c == character ) return true; if ( c <= 0 ) // Silent failure: can't get document at this scope return false; in->get(); *tag += (char) c; } return false; } #endif // One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The // "assign" optimization removes over 10% of the execution time. // const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) { // Oddly, not supported on some comilers, //name->clear(); // So use this: *name = ""; assert( p ); // Names start with letters or underscores. // Of course, in unicode, tinyxml has no idea what a letter *is*. The // algorithm is generous. // // After that, they can be letters, underscores, numbers, // hyphens, or colons. (Colons are valid ony for namespaces, // but tinyxml can't tell namespaces from names.) if ( p && *p && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) { const char* start = p; while( p && *p && ( IsAlphaNum( (unsigned char ) *p, encoding ) || *p == '_' || *p == '-' || *p == '.' || *p == ':' ) ) { //(*name) += *p; // expensive ++p; } if ( p-start > 0 ) { name->assign( start, p-start ); } return p; } return 0; } const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) { // Presume an entity, and pull it out. TIXML_STRING ent; int i; *length = 0; if ( *(p+1) && *(p+1) == '#' && *(p+2) ) { unsigned long ucs = 0; ptrdiff_t delta = 0; unsigned mult = 1; if ( *(p+2) == 'x' ) { // Hexadecimal. if ( !*(p+3) ) return 0; const char* q = p+3; q = strchr( q, ';' ); if ( !q || !*q ) return 0; delta = q-p; --q; while ( *q != 'x' ) { if ( *q >= '0' && *q <= '9' ) ucs += mult * (*q - '0'); else if ( *q >= 'a' && *q <= 'f' ) ucs += mult * (*q - 'a' + 10); else if ( *q >= 'A' && *q <= 'F' ) ucs += mult * (*q - 'A' + 10 ); else return 0; mult *= 16; --q; } } else { // Decimal. if ( !*(p+2) ) return 0; const char* q = p+2; q = strchr( q, ';' ); if ( !q || !*q ) return 0; delta = q-p; --q; while ( *q != '#' ) { if ( *q >= '0' && *q <= '9' ) ucs += mult * (*q - '0'); else return 0; mult *= 10; --q; } } if ( encoding == TIXML_ENCODING_UTF8 ) { // convert the UCS to UTF-8 ConvertUTF32ToUTF8( ucs, value, length ); } else { *value = (char)ucs; *length = 1; } return p + delta + 1; } // Now try to match it. for( i=0; iappend( cArr, len ); } } else { bool whitespace = false; // Remove leading white space: p = SkipWhiteSpace( p, encoding ); while ( p && *p && !StringEqual( p, endTag, caseInsensitive, encoding ) ) { if ( *p == '\r' || *p == '\n' ) { whitespace = true; ++p; } else if ( IsWhiteSpace( *p ) ) { whitespace = true; ++p; } else { // If we've found whitespace, add it before the // new character. Any whitespace just becomes a space. if ( whitespace ) { (*text) += ' '; whitespace = false; } int len; char cArr[4] = { 0, 0, 0, 0 }; p = GetChar( p, cArr, &len, encoding ); if ( len == 1 ) (*text) += cArr[0]; // more efficient else text->append( cArr, len ); } } } if ( p && *p ) p += strlen( endTag ); return ( p && *p ) ? p : 0; } #ifdef TIXML_USE_STL void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) { // The basic issue with a document is that we don't know what we're // streaming. Read something presumed to be a tag (and hope), then // identify it, and call the appropriate stream method on the tag. // // This "pre-streaming" will never read the closing ">" so the // sub-tag can orient itself. if ( !StreamTo( in, '<', tag ) ) { SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } while ( in->good() ) { int tagIndex = (int) tag->length(); while ( in->good() && in->peek() != '>' ) { int c = in->get(); if ( c <= 0 ) { SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); break; } (*tag) += (char) c; } if ( in->good() ) { // We now have something we presume to be a node of // some sort. Identify it, and call the node to // continue streaming. TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); if ( node ) { node->StreamIn( in, tag ); bool isElement = node->ToElement() != 0; delete node; node = 0; // If this is the root element, we're done. Parsing will be // done by the >> operator. if ( isElement ) { return; } } else { SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } } } // We should have returned sooner. SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); } #endif const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) { ClearError(); // Parse away, at the document level. Since a document // contains nothing but other tags, most of what happens // here is skipping white space. if ( !p || !*p ) { SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); return 0; } // Note that, for a document, this needs to come // before the while space skip, so that parsing // starts from the pointer we are given. location.Clear(); if ( prevData ) { location.row = prevData->cursor.row; location.col = prevData->cursor.col; } else { location.row = 0; location.col = 0; } TiXmlParsingData data( p, TabSize(), location.row, location.col ); location = data.Cursor(); if ( encoding == TIXML_ENCODING_UNKNOWN ) { // Check for the Microsoft UTF-8 lead bytes. const unsigned char* pU = (const unsigned char*)p; if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) { encoding = TIXML_ENCODING_UTF8; useMicrosoftBOM = true; } } p = SkipWhiteSpace( p, encoding ); if ( !p ) { SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); return 0; } while ( p && *p ) { TiXmlNode* node = Identify( p, encoding ); if ( node ) { p = node->Parse( p, &data, encoding ); LinkEndChild( node ); } else { break; } // Did we get encoding info? if ( encoding == TIXML_ENCODING_UNKNOWN && node->ToDeclaration() ) { TiXmlDeclaration* dec = node->ToDeclaration(); const char* enc = dec->Encoding(); assert( enc ); if ( *enc == 0 ) encoding = TIXML_ENCODING_UTF8; else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) encoding = TIXML_ENCODING_UTF8; else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice else encoding = TIXML_ENCODING_LEGACY; } p = SkipWhiteSpace( p, encoding ); } // Was this empty? if ( !firstChild ) { SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); return 0; } // All is well. return p; } void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) { // The first error in a chain is more accurate - don't set again! if ( error ) return; assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); error = true; errorId = err; errorDesc = errorString[ errorId ]; errorLocation.Clear(); if ( pError && data ) { data->Stamp( pError, encoding ); errorLocation = data->Cursor(); } } TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) { TiXmlNode* returnNode = 0; p = SkipWhiteSpace( p, encoding ); if( !p || !*p || *p != '<' ) { return 0; } p = SkipWhiteSpace( p, encoding ); if ( !p || !*p ) { return 0; } // What is this thing? // - Elements start with a letter or underscore, but xml is reserved. // - Comments: "; if ( !StringEqual( p, startTag, false, encoding ) ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); return 0; } p += strlen( startTag ); // [ 1475201 ] TinyXML parses entities in comments // Oops - ReadText doesn't work, because we don't want to parse the entities. // p = ReadText( p, &value, false, endTag, false, encoding ); // // from the XML spec: /* [Definition: Comments may appear anywhere in a document outside other markup; in addition, they may appear within the document type declaration at places allowed by the grammar. They are not part of the document's character data; an XML processor MAY, but need not, make it possible for an application to retrieve the text of comments. For compatibility, the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity references MUST NOT be recognized within comments. An example of a comment: */ value = ""; // Keep all the white space. while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) { value.append( p, 1 ); ++p; } if ( p && *p ) p += strlen( endTag ); return p; } const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) { p = SkipWhiteSpace( p, encoding ); if ( !p || !*p ) return 0; if ( data ) { data->Stamp( p, encoding ); location = data->Cursor(); } // Read the name, the '=' and the value. const char* pErr = p; p = ReadName( p, &name, encoding ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); return 0; } p = SkipWhiteSpace( p, encoding ); if ( !p || !*p || *p != '=' ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); return 0; } ++p; // skip '=' p = SkipWhiteSpace( p, encoding ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); return 0; } const char* end; const char SINGLE_QUOTE = '\''; const char DOUBLE_QUOTE = '\"'; if ( *p == SINGLE_QUOTE ) { ++p; end = "\'"; // single quote in string p = ReadText( p, &value, false, end, false, encoding ); } else if ( *p == DOUBLE_QUOTE ) { ++p; end = "\""; // double quote in string p = ReadText( p, &value, false, end, false, encoding ); } else { // All attribute values should be in single or double quotes. // But this is such a common error that the parser will try // its best, even without them. value = ""; while ( p && *p // existence && !IsWhiteSpace( *p ) // whitespace && *p != '/' && *p != '>' ) // tag end { if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { // [ 1451649 ] Attribute values with trailing quotes not handled correctly // We did not have an opening quote but seem to have a // closing one. Give up and throw an error. if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); return 0; } value += *p; ++p; } } return p; } #ifdef TIXML_USE_STL void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) { while ( in->good() ) { int c = in->peek(); if ( !cdata && (c == '<' ) ) { return; } if ( c <= 0 ) { TiXmlDocument* document = GetDocument(); if ( document ) document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } (*tag) += (char) c; in->get(); // "commits" the peek made above if ( cdata && c == '>' && tag->size() >= 3 ) { size_t len = tag->size(); if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { // terminator of cdata. return; } } } } #endif const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) { value = ""; TiXmlDocument* document = GetDocument(); if ( data ) { data->Stamp( p, encoding ); location = data->Cursor(); } const char* const startTag = ""; if ( cdata || StringEqual( p, startTag, false, encoding ) ) { cdata = true; if ( !StringEqual( p, startTag, false, encoding ) ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); return 0; } p += strlen( startTag ); // Keep all the white space, ignore the encoding, etc. while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) { value += *p; ++p; } TIXML_STRING dummy; p = ReadText( p, &dummy, false, endTag, false, encoding ); return p; } else { bool ignoreWhite = true; const char* end = "<"; p = ReadText( p, &value, ignoreWhite, end, false, encoding ); if ( p && *p ) return p-1; // don't truncate the '<' return 0; } } #ifdef TIXML_USE_STL void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) { while ( in->good() ) { int c = in->get(); if ( c <= 0 ) { TiXmlDocument* document = GetDocument(); if ( document ) document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); return; } (*tag) += (char) c; if ( c == '>' ) { // All is well. return; } } } #endif const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) { p = SkipWhiteSpace( p, _encoding ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument* document = GetDocument(); if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); return 0; } if ( data ) { data->Stamp( p, _encoding ); location = data->Cursor(); } p += 5; version = ""; encoding = ""; standalone = ""; while ( p && *p ) { if ( *p == '>' ) { ++p; return p; } p = SkipWhiteSpace( p, _encoding ); if ( StringEqual( p, "version", true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); version = attrib.Value(); } else if ( StringEqual( p, "encoding", true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); encoding = attrib.Value(); } else if ( StringEqual( p, "standalone", true, _encoding ) ) { TiXmlAttribute attrib; p = attrib.Parse( p, data, _encoding ); standalone = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) ++p; } } return 0; } bool TiXmlText::Blank() const { for ( unsigned i=0; i This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. */ #ifndef TINYXML_INCLUDED #define TINYXML_INCLUDED #ifndef TIXML_USE_STL #define TIXML_USE_STL #endif #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable : 4530 ) #pragma warning( disable : 4786 ) #endif #include #include #include #include #include #ifdef HAVE_ZLIB #include #ifndef ZLIB_H #if defined(__MINGW64__) #include "../win64/zlib/zlib.h" #elif defined(__MINGW32__) #include "../win32/zlib/include/zlib.h" #endif #endif #endif // Help out windows: #if defined( _DEBUG ) && !defined( DEBUG ) #define DEBUG #endif #ifdef TIXML_USE_STL #include #include #include #define TIXML_STRING std::string #else #include "tinystr.h" #define TIXML_STRING TiXmlString #endif // Deprecated library function hell. Compilers want to use the // new safe versions. This probably doesn't fully address the problem, // but it gets closer. There are too many compilers for me to fully // test. If you get compilation troubles, undefine TIXML_SAFE #define TIXML_SAFE #ifdef TIXML_SAFE #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) // Microsoft visual studio, version 2005 and higher. #define TIXML_SNPRINTF _snprintf_s #define TIXML_SSCANF sscanf_s #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) // Microsoft visual studio, version 6 and higher. //#pragma message( "Using _sn* functions." ) #define TIXML_SNPRINTF _snprintf /* Flawfinder: ignore *** Buffer size checked in each case */ #define TIXML_SSCANF sscanf /* Flawfinder: ignore *** Only %d and %lf are used */ #elif defined(__GNUC__) && (__GNUC__ >= 3 ) // GCC version 3 and higher.s //#warning( "Using sn* functions." ) #define TIXML_SNPRINTF snprintf /* Flawfinder: ignore *** Buffer size checked in each case */ #define TIXML_SSCANF sscanf /* Flawfinder: ignore *** Only %d and %lf are used */ #else #define TIXML_SNPRINTF snprintf /* Flawfinder: ignore *** Buffer size checked in each case */ #define TIXML_SSCANF sscanf /* Flawfinder: ignore *** Only %d and %lf are used */ #endif #endif class TiXmlDocument; class TiXmlElement; class TiXmlComment; class TiXmlUnknown; class TiXmlAttribute; class TiXmlText; class TiXmlDeclaration; class TiXmlParsingData; const int TIXML_MAJOR_VERSION = 2; const int TIXML_MINOR_VERSION = 6; const int TIXML_PATCH_VERSION = 2; /* Internal structure for tracking location of items in the XML file. */ struct TiXmlCursor { TiXmlCursor() { Clear(); } void Clear() { row = col = -1; } int row; // 0 based. int col; // 0 based. }; /** Implements the interface to the "Visitor pattern" (see the Accept() method.) If you call the Accept() method, it requires being passed a TiXmlVisitor class to handle callbacks. For nodes that contain other nodes (Document, Element) you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves are simply called with Visit(). If you return 'true' from a Visit method, recursive parsing will continue. If you return false, no children of this node or its sibilings will be Visited. All flavors of Visit methods have a default implementation that returns 'true' (continue visiting). You need to only override methods that are interesting to you. Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. You should never change the document from a callback. @sa TiXmlNode::Accept() */ class TiXmlVisitor { public: virtual ~TiXmlVisitor() {} /// Visit a document. virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } /// Visit a document. virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } /// Visit an element. virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } /// Visit an element. virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } /// Visit a declaration virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } /// Visit a text node virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } /// Visit a comment node virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } /// Visit an unknown node virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } }; // Only used by Attribute::Query functions enum { TIXML_SUCCESS, TIXML_NO_ATTRIBUTE, TIXML_WRONG_TYPE }; // Used by the parsing routines. enum TiXmlEncoding { TIXML_ENCODING_UNKNOWN, TIXML_ENCODING_UTF8, TIXML_ENCODING_LEGACY }; const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; /** TiXmlBase is a base class for every class in TinyXml. It does little except to establish that TinyXml classes can be printed and provide some utility functions. In XML, the document and elements can contain other elements and other types of nodes. @verbatim A Document can contain: Element (container or leaf) Comment (leaf) Unknown (leaf) Declaration( leaf ) An Element can contain: Element (container or leaf) Text (leaf) Attributes (not on tree) Comment (leaf) Unknown (leaf) A Decleration contains: Attributes (not on tree) @endverbatim */ class TiXmlBase { friend class TiXmlNode; friend class TiXmlElement; friend class TiXmlDocument; public: TiXmlBase() : userData(0) {} virtual ~TiXmlBase() {} /** All TinyXml classes can print themselves to a filestream or the string class (TiXmlString in non-STL mode, std::string in STL mode.) Either or both cfile and str can be null. This is a formatted print, and will insert tabs and newlines. (For an unformatted stream, use the << operator.) */ virtual void Print( FILE* cfile, int depth ) const = 0; #ifdef ZLIB_H virtual void gzPrint( gzFile cfile, int depth ) const = 0; #endif /** The world does not agree on whether white space should be kept or not. In order to make everyone happy, these global, static functions are provided to set whether or not TinyXml will condense all white space into a single space or not. The default is to condense. Note changing this value is not thread safe. */ static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } /// Return the current white space setting. static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } /** Return the position, in the original source file, of this node or attribute. The row and column are 1-based. (That is the first row and first column is 1,1). If the returns values are 0 or less, then the parser does not have a row and column value. Generally, the row and column value will be set when the TiXmlDocument::Load(), TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set when the DOM was created from operator>>. The values reflect the initial load. Once the DOM is modified programmatically (by adding or changing nodes and attributes) the new values will NOT update to reflect changes in the document. There is a minor performance cost to computing the row and column. Computation can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. @sa TiXmlDocument::SetTabSize() */ int Row() const { return location.row + 1; } int Column() const { return location.col + 1; } ///< See Row() void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. // Table that returs, for a given lead byte, the total number of bytes // in the UTF-8 sequence. static const int utf8ByteTable[256]; virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, or they will be transformed into entities! */ static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); enum { TIXML_NO_ERROR = 0, TIXML_ERROR, TIXML_ERROR_OPENING_FILE, TIXML_ERROR_PARSING_ELEMENT, TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, TIXML_ERROR_READING_ELEMENT_VALUE, TIXML_ERROR_READING_ATTRIBUTES, TIXML_ERROR_PARSING_EMPTY, TIXML_ERROR_READING_END_TAG, TIXML_ERROR_PARSING_UNKNOWN, TIXML_ERROR_PARSING_COMMENT, TIXML_ERROR_PARSING_DECLARATION, TIXML_ERROR_DOCUMENT_EMPTY, TIXML_ERROR_EMBEDDED_NULL, TIXML_ERROR_PARSING_CDATA, TIXML_ERROR_DOCUMENT_TOP_ONLY, TIXML_ERROR_STRING_COUNT }; protected: static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); inline static bool IsWhiteSpace( char c ) { return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); } inline static bool IsWhiteSpace( int c ) { if ( c < 256 ) return IsWhiteSpace( (char) c ); return false; // Again, only truly correct for English/Latin...but usually works. } #ifdef TIXML_USE_STL static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); #endif /* Reads an XML name into the string provided. Returns a pointer just past the last character of the name, or 0 if the function has an error. */ static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); /* Reads text. Returns a pointer past the given end tag. Wickedly complex options, but it keeps the (sensitive) code in one place. */ static const char* ReadText( const char* in, // where to start TIXML_STRING* text, // the string read bool ignoreWhiteSpace, // whether to keep the white space const char* endTag, // what ends this text bool ignoreCase, // whether to ignore case in the end tag TiXmlEncoding encoding ); // the current encoding // If an entity has been found, transform it into a character. static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); // Get a character, while interpreting entities. // The length can be from 0 to 4 bytes. inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) { assert( p ); if ( encoding == TIXML_ENCODING_UTF8 ) { *length = utf8ByteTable[ *((const unsigned char*)p) ]; assert( *length >= 0 && *length < 5 ); } else { *length = 1; } if ( *length == 1 ) { if ( *p == '&' ) return GetEntity( p, _value, length, encoding ); *_value = *p; return p+1; } else if ( *length ) { //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), // and the null terminator isn't needed for( int i=0; p[i] && i<*length; ++i ) { _value[i] = p[i]; } return p + (*length); } else { // Not valid text. return 0; } } // Return true if the next characters in the stream are any of the endTag sequences. // Ignore case only works for english, and should only be relied on when comparing // to English words: StringEqual( p, "version", true ) is fine. static bool StringEqual( const char* p, const char* endTag, bool ignoreCase, TiXmlEncoding encoding ); static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; TiXmlCursor location; /// Field containing a generic user pointer void* userData; // None of these methods are reliable for any language except English. // Good for approximation, not great for accuracy. static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); inline static int ToLower( int v, TiXmlEncoding encoding ) { if ( encoding == TIXML_ENCODING_UTF8 ) { if ( v < 128 ) return tolower( v ); return v; } else { return tolower( v ); } } static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); private: TiXmlBase( const TiXmlBase& ); // not implemented. void operator=( const TiXmlBase& base ); // not allowed. struct Entity { const char* str; unsigned int strLength; char chr; }; enum { NUM_ENTITY = 5, MAX_ENTITY_LENGTH = 6 }; static Entity entity[ NUM_ENTITY ]; static bool condenseWhiteSpace; }; /** The parent class for everything in the Document Object Model. (Except for attributes). Nodes have siblings, a parent, and children. A node can be in a document, or stand on its own. The type of a TiXmlNode can be queried, and it can be cast to its more defined type. */ class TiXmlNode : public TiXmlBase { friend class TiXmlDocument; friend class TiXmlElement; public: #ifdef TIXML_USE_STL /** An input stream operator, for every class. Tolerant of newlines and formatting, but doesn't expect them. */ friend std::istream& operator >> (std::istream& in, TiXmlNode& base); /** An output stream operator, for every class. Note that this outputs without any newlines or formatting, as opposed to Print(), which includes tabs and new lines. The operator<< and operator>> are not completely symmetric. Writing a node to a stream is very well defined. You'll get a nice stream of output, without any extra whitespace or newlines. But reading is not as well defined. (As it always is.) If you create a TiXmlElement (for example) and read that from an input stream, the text needs to define an element or junk will result. This is true of all input streams, but it's worth keeping in mind. A TiXmlDocument will read nodes until it reads a root element, and all the children of that root element. */ friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); /// Appends the XML node or attribute to a std::string. friend std::string& operator<< (std::string& out, const TiXmlNode& base ); #endif /** The types of XML nodes supported by TinyXml. (All the unsupported types are picked up by UNKNOWN.) */ enum NodeType { TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT, TINYXML_UNKNOWN, TINYXML_TEXT, TINYXML_DECLARATION, TINYXML_TYPECOUNT }; virtual ~TiXmlNode(); /** The meaning of 'value' changes for the specific type of TiXmlNode. @verbatim Document: filename of the xml file Element: name of the element Comment: the comment text Unknown: the tag contents Text: the text string @endverbatim The subclasses will wrap this function. */ const char *Value() const { return value.c_str (); } #ifdef TIXML_USE_STL /** Return Value() as a std::string. If you only use STL, this is more efficient than calling Value(). Only available in STL mode. */ const std::string& ValueStr() const { return value; } #endif const TIXML_STRING& ValueTStr() const { return value; } /** Changes the value of the node. Defined as: @verbatim Document: filename of the xml file Element: name of the element Comment: the comment text Unknown: the tag contents Text: the text string @endverbatim */ void SetValue(const char * _value) { value = _value;} #ifdef TIXML_USE_STL /// STL std::string form. void SetValue( const std::string& _value ) { value = _value; } #endif /// Delete all the children of this node. Does not affect 'this'. void Clear(); /// One step up the DOM. TiXmlNode* Parent() { return parent; } const TiXmlNode* Parent() const { return parent; } const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. TiXmlNode* FirstChild() { return firstChild; } const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. /// The first child of this node with the matching 'value'. Will be null if none found. TiXmlNode* FirstChild( const char * _value ) { // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) // call the method, cast the return back to non-const. return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); } const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. TiXmlNode* LastChild() { return lastChild; } const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. TiXmlNode* LastChild( const char * _value ) { return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); } #ifdef TIXML_USE_STL const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. #endif /** An alternate way to walk the children of a node. One way to iterate over nodes is: @verbatim for( child = parent->FirstChild(); child; child = child->NextSibling() ) @endverbatim IterateChildren does the same thing with the syntax: @verbatim child = 0; while( child = parent->IterateChildren( child ) ) @endverbatim IterateChildren takes the previous child as input and finds the next one. If the previous child is null, it returns the first. IterateChildren will return null when done. */ const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; TiXmlNode* IterateChildren( const TiXmlNode* previous ) { return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); } /// This flavor of IterateChildren searches for children with a particular 'value' const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); } #ifdef TIXML_USE_STL const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. #endif /** Add a new node related to this. Adds a child past the LastChild. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); /** Add a new node related to this. Adds a child past the LastChild. NOTE: the node to be added is passed by pointer, and will be henceforth owned (and deleted) by tinyXml. This method is efficient and avoids an extra copy, but should be used with care as it uses a different memory model than the other insert functions. @sa InsertEndChild */ TiXmlNode* LinkEndChild( TiXmlNode* addThis ); /** Add a new node related to this. Adds a child before the specified child. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); /** Add a new node related to this. Adds a child after the specified child. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); /** Replace a child of this node. Returns a pointer to the new object or NULL if an error occured. */ TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); /// Delete a child of this node. bool RemoveChild( TiXmlNode* removeThis ); /// Navigate to a sibling node. const TiXmlNode* PreviousSibling() const { return prev; } TiXmlNode* PreviousSibling() { return prev; } /// Navigate to a sibling node. const TiXmlNode* PreviousSibling( const char * ) const; TiXmlNode* PreviousSibling( const char *_prev ) { return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); } #ifdef TIXML_USE_STL const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. #endif /// Navigate to a sibling node. const TiXmlNode* NextSibling() const { return next; } TiXmlNode* NextSibling() { return next; } /// Navigate to a sibling node with the given 'value'. const TiXmlNode* NextSibling( const char * ) const; TiXmlNode* NextSibling( const char* _next ) { return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); } /** Convenience function to get through elements. Calls NextSibling and ToElement. Will skip all non-Element nodes. Returns 0 if there is not another element. */ const TiXmlElement* NextSiblingElement() const; TiXmlElement* NextSiblingElement() { return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); } /** Convenience function to get through elements. Calls NextSibling and ToElement. Will skip all non-Element nodes. Returns 0 if there is not another element. */ const TiXmlElement* NextSiblingElement( const char * ) const; TiXmlElement* NextSiblingElement( const char *_next ) { return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); } #ifdef TIXML_USE_STL const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. #endif /// Convenience function to get through elements. const TiXmlElement* FirstChildElement() const; TiXmlElement* FirstChildElement() { return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); } /// Convenience function to get through elements. const TiXmlElement* FirstChildElement( const char * _value ) const; TiXmlElement* FirstChildElement( const char * _value ) { return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); } #ifdef TIXML_USE_STL const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. #endif /** Query the type (as an enumerated value, above) of this node. The possible types are: TINYXML_DOCUMENT, TINYXML_ELEMENT, TINYXML_COMMENT, TINYXML_UNKNOWN, TINYXML_TEXT, and TINYXML_DECLARATION. */ int Type() const { return type; } /** Return a pointer to the Document this node lives in. Returns null if not in a document. */ const TiXmlDocument* GetDocument() const; TiXmlDocument* GetDocument() { return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); } /// Returns true if this node has no children. bool NoChildren() const { return !firstChild; } virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. /** Create an exact duplicate of this node and return it. The memory must be deleted by the caller. */ virtual TiXmlNode* Clone() const = 0; /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the XML tree will be conditionally visited and the host will be called back via the TiXmlVisitor interface. This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse the XML for the callbacks, so the performance of TinyXML is unchanged by using this interface versus any other.) The interface has been based on ideas from: - http://www.saxproject.org/ - http://c2.com/cgi/wiki?HierarchicalVisitorPattern Which are both good references for "visiting". An example of using Accept(): @verbatim TiXmlPrinter printer; tinyxmlDoc.Accept( &printer ); const char* xmlcstr = printer.CStr(); @endverbatim */ virtual bool Accept( TiXmlVisitor* visitor ) const = 0; protected: TiXmlNode( NodeType _type ); // Copy to the allocated object. Shared functionality between Clone, Copy constructor, // and the assignment operator. void CopyTo( TiXmlNode* target ) const; #ifdef TIXML_USE_STL // The real work of the input operator. virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; #endif // Figure out what is at *p, and parse it. Returns null if it is not an xml node. TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); TiXmlNode* parent; NodeType type; TiXmlNode* firstChild; TiXmlNode* lastChild; TIXML_STRING value; TiXmlNode* prev; TiXmlNode* next; private: TiXmlNode( const TiXmlNode& ); // not implemented. void operator=( const TiXmlNode& base ); // not allowed. }; /** An attribute is a name-value pair. Elements have an arbitrary number of attributes, each with a unique name. @note The attributes are not TiXmlNodes, since they are not part of the tinyXML document object model. There are other suggested ways to look at this problem. */ class TiXmlAttribute : public TiXmlBase { friend class TiXmlAttributeSet; public: /// Construct an empty attribute. TiXmlAttribute() : TiXmlBase() { document = 0; prev = next = 0; } #ifdef TIXML_USE_STL /// std::string constructor. TiXmlAttribute( const std::string& _name, const std::string& _value ) { name = _name; value = _value; document = 0; prev = next = 0; } #endif /// Construct an attribute with a name and value. TiXmlAttribute( const char * _name, const char * _value ) { name = _name; value = _value; document = 0; prev = next = 0; } const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. #ifdef TIXML_USE_STL const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. #endif int IntValue() const; ///< Return the value of this attribute, converted to an integer. double DoubleValue() const; ///< Return the value of this attribute, converted to a double. // Get the tinyxml string representation const TIXML_STRING& NameTStr() const { return name; } /** QueryIntValue examines the value string. It is an alternative to the IntValue() method with richer error checking. If the value is an integer, it is stored in 'value' and the call returns TIXML_SUCCESS. If it is not an integer, it returns TIXML_WRONG_TYPE. A specialized but useful call. Note that for success it returns 0, which is the opposite of almost all other TinyXml calls. */ int QueryIntValue( int* _value ) const; /// QueryDoubleValue examines the value string. See QueryIntValue(). int QueryDoubleValue( double* _value ) const; void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. void SetValue( const char* _value ) { value = _value; } ///< Set the value. void SetIntValue( int _value ); ///< Set the value from an integer. void SetDoubleValue( double _value ); ///< Set the value from a double. #ifdef TIXML_USE_STL /// STL std::string form. void SetName( const std::string& _name ) { name = _name; } /// STL std::string form. void SetValue( const std::string& _value ) { value = _value; } #endif /// Get the next sibling attribute in the DOM. Returns null at end. const TiXmlAttribute* Next() const; TiXmlAttribute* Next() { return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); } /// Get the previous sibling attribute in the DOM. Returns null at beginning. const TiXmlAttribute* Previous() const; TiXmlAttribute* Previous() { return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); } bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } /* Attribute parsing starts: first letter of the name returns: the next char after the value end quote */ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); // Prints this Attribute to a FILE stream. virtual void Print( FILE* cfile, int depth ) const { Print( cfile, depth, 0 ); } void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; #ifdef ZLIB_H // Print through zlib virtual void gzPrint( gzFile cfile, int depth ) const { gzPrint( cfile, depth, 0); } void gzPrint( gzFile cfile, int depth, TIXML_STRING* str ) const; #endif // [internal use] // Set the document pointer so the attribute can report errors. void SetDocument( TiXmlDocument* doc ) { document = doc; } private: TiXmlAttribute( const TiXmlAttribute& ); // not implemented. void operator=( const TiXmlAttribute& base ); // not allowed. TiXmlDocument* document; // A pointer back to a document, for error reporting. TIXML_STRING name; TIXML_STRING value; TiXmlAttribute* prev; TiXmlAttribute* next; }; /* A class used to manage a group of attributes. It is only used internally, both by the ELEMENT and the DECLARATION. The set can be changed transparent to the Element and Declaration classes that use it, but NOT transparent to the Attribute which has to implement a next() and previous() method. Which makes it a bit problematic and prevents the use of STL. This version is implemented with circular lists because: - I like circular lists - it demonstrates some independence from the (typical) doubly linked list. */ class TiXmlAttributeSet { public: TiXmlAttributeSet(); ~TiXmlAttributeSet(); void Add( TiXmlAttribute* attribute ); void Remove( TiXmlAttribute* attribute ); const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } TiXmlAttribute* Find( const char* _name ) const; TiXmlAttribute* FindOrCreate( const char* _name ); # ifdef TIXML_USE_STL TiXmlAttribute* Find( const std::string& _name ) const; TiXmlAttribute* FindOrCreate( const std::string& _name ); # endif private: //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), //*ME: this class must be also use a hidden/disabled copy-constructor !!! TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) TiXmlAttribute sentinel; }; /** The element is a container class. It has a value, the element name, and can contain other elements, text, comments, and unknowns. Elements also contain an arbitrary number of attributes. */ class TiXmlElement : public TiXmlNode { public: /// Construct an element. TiXmlElement (const char * in_value); #ifdef TIXML_USE_STL /// std::string constructor. TiXmlElement( const std::string& _value ); #endif TiXmlElement( const TiXmlElement& ); TiXmlElement& operator=( const TiXmlElement& base ); virtual ~TiXmlElement(); /** Given an attribute name, Attribute() returns the value for the attribute of that name, or null if none exists. */ const char* Attribute( const char* name ) const; /** Given an attribute name, Attribute() returns the value for the attribute of that name, or null if none exists. If the attribute exists and can be converted to an integer, the integer value will be put in the return 'i', if 'i' is non-null. */ const char* Attribute( const char* name, int* i ) const; /** Given an attribute name, Attribute() returns the value for the attribute of that name, or null if none exists. If the attribute exists and can be converted to an double, the double value will be put in the return 'd', if 'd' is non-null. */ const char* Attribute( const char* name, double* d ) const; /** QueryIntAttribute examines the attribute - it is an alternative to the Attribute() method with richer error checking. If the attribute is an integer, it is stored in 'value' and the call returns TIXML_SUCCESS. If it is not an integer, it returns TIXML_WRONG_TYPE. If the attribute does not exist, then TIXML_NO_ATTRIBUTE is returned. */ int QueryIntAttribute( const char* name, int* _value ) const; /// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute(). int QueryUnsignedAttribute( const char* name, unsigned* _value ) const; /** QueryBoolAttribute examines the attribute - see QueryIntAttribute(). Note that '1', 'true', or 'yes' are considered true, while '0', 'false' and 'no' are considered false. */ int QueryBoolAttribute( const char* name, bool* _value ) const; /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). int QueryDoubleAttribute( const char* name, double* _value ) const; /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). int QueryFloatAttribute( const char* name, float* _value ) const { double d; int result = QueryDoubleAttribute( name, &d ); if ( result == TIXML_SUCCESS ) { *_value = (float)d; } return result; } #ifdef TIXML_USE_STL /// QueryStringAttribute examines the attribute - see QueryIntAttribute(). int QueryStringAttribute( const char* name, std::string* _value ) const { const char* cstr = Attribute( name ); if ( cstr ) { *_value = std::string( cstr ); return TIXML_SUCCESS; } return TIXML_NO_ATTRIBUTE; } /** Template form of the attribute query which will try to read the attribute into the specified type. Very easy, very powerful, but be careful to make sure to call this with the correct type. NOTE: This method doesn't work correctly for 'string' types that contain spaces. @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE */ template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const { const TiXmlAttribute* node = attributeSet.Find( name ); if ( !node ) return TIXML_NO_ATTRIBUTE; std::stringstream sstream( node->ValueStr() ); sstream >> *outValue; if ( !sstream.fail() ) return TIXML_SUCCESS; return TIXML_WRONG_TYPE; } int QueryValueAttribute( const std::string& name, std::string* outValue ) const { const TiXmlAttribute* node = attributeSet.Find( name ); if ( !node ) return TIXML_NO_ATTRIBUTE; *outValue = node->ValueStr(); return TIXML_SUCCESS; } #endif /** Sets an attribute of name to a given value. The attribute will be created if it does not exist, or changed if it does. */ void SetAttribute( const char* name, const char * _value ); #ifdef TIXML_USE_STL const std::string* Attribute( const std::string& name ) const; const std::string* Attribute( const std::string& name, int* i ) const; const std::string* Attribute( const std::string& name, double* d ) const; int QueryIntAttribute( const std::string& name, int* _value ) const; int QueryDoubleAttribute( const std::string& name, double* _value ) const; /// STL std::string form. void SetAttribute( const std::string& name, const std::string& _value ); ///< STL std::string form. void SetAttribute( const std::string& name, int _value ); ///< STL std::string form. void SetDoubleAttribute( const std::string& name, double value ); #endif /** Sets an attribute of name to a given value. The attribute will be created if it does not exist, or changed if it does. */ void SetAttribute( const char * name, int value ); /** Sets an attribute of name to a given value. The attribute will be created if it does not exist, or changed if it does. */ void SetDoubleAttribute( const char * name, double value ); /** Deletes an attribute with the given name. */ void RemoveAttribute( const char * name ); #ifdef TIXML_USE_STL void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. #endif const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } /** Convenience function for easy access to the text inside an element. Although easy and concise, GetText() is limited compared to getting the TiXmlText child and accessing it directly. If the first child of 'this' is a TiXmlText, the GetText() returns the character string of the Text node, else null is returned. This is a convenient method for getting the text of simple contained text: @verbatim This is text const char* str = fooElement->GetText(); @endverbatim 'str' will be a pointer to "This is text". Note that this function can be misleading. If the element foo was created from this XML: @verbatim This is text @endverbatim then the value of str would be null. The first child node isn't a text node, it is another element. From this XML: @verbatim This is text @endverbatim GetText() will return "This is ". WARNING: GetText() accesses a child node - don't become confused with the similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are safe type casts on the referenced node. */ const char* GetText() const; /// Creates a new Element and returns it - the returned element is a copy. virtual TiXmlNode* Clone() const; // Print the Element to a FILE stream. virtual void Print( FILE* cfile, int depth ) const; #ifdef ZLIB_H virtual void gzPrint( gzFile cfile, int depth ) const; #endif /* Attribtue parsing starts: next char past '<' returns: next char past '>' */ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* visitor ) const; protected: void CopyTo( TiXmlElement* target ) const; void ClearThis(); // like clear, but initializes 'this' object as well // Used to be public [internal use] #ifdef TIXML_USE_STL virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); #endif /* [internal use] Reads the "value" of the element -- another element, or text. This should terminate with the current end tag. */ const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); private: TiXmlAttributeSet attributeSet; }; /** An XML comment. */ class TiXmlComment : public TiXmlNode { public: /// Constructs an empty comment. TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {} /// Construct a comment from text. TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) { SetValue( _value ); } TiXmlComment( const TiXmlComment& ); TiXmlComment& operator=( const TiXmlComment& base ); virtual ~TiXmlComment() {} /// Returns a copy of this Comment. virtual TiXmlNode* Clone() const; // Write this Comment to a FILE stream. virtual void Print( FILE* cfile, int depth ) const; #ifdef ZLIB_H virtual void gzPrint( gzFile cfile, int depth ) const; #endif /* Attribtue parsing starts: at the ! of the !-- returns: next char past '>' */ virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* visitor ) const; protected: void CopyTo( TiXmlComment* target ) const; // used to be public #ifdef TIXML_USE_STL virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); #endif // virtual void StreamOut( TIXML_OSTREAM * out ) const; private: }; /** XML text. A text node can have 2 ways to output the next. "normal" output and CDATA. It will default to the mode it was parsed from the XML file and you generally want to leave it alone, but you can change the output mode with SetCDATA() and query it with CDATA(). */ class TiXmlText : public TiXmlNode { friend class TiXmlElement; public: /** Constructor for text element. By default, it is treated as normal, encoded text. If you want it be output as a CDATA text element, set the parameter _cdata to 'true' */ TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) { SetValue( initValue ); cdata = false; } virtual ~TiXmlText() {} #ifdef TIXML_USE_STL /// Constructor. TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) { SetValue( initValue ); cdata = false; } #endif TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); } TiXmlText& operator=( const TiXmlText& base ) { base.CopyTo( this ); return *this; } // Write this text object to a FILE stream. virtual void Print( FILE* cfile, int depth ) const; #ifdef ZLIB_H virtual void gzPrint( gzFile cfile, int depth ) const; #endif /// Queries whether this represents text using a CDATA section. bool CDATA() const { return cdata; } /// Turns on or off a CDATA representation of text. void SetCDATA( bool _cdata ) { cdata = _cdata; } virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* content ) const; protected : /// [internal use] Creates a new Element and returns it. virtual TiXmlNode* Clone() const; void CopyTo( TiXmlText* target ) const; bool Blank() const; // returns true if all white space and new lines // [internal use] #ifdef TIXML_USE_STL virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); #endif private: bool cdata; // true if this should be input and output as a CDATA style text element }; /** In correct XML the declaration is the first entry in the file. @verbatim @endverbatim TinyXml will happily read or write files without a declaration, however. There are 3 possible attributes to the declaration: version, encoding, and standalone. Note: In this version of the code, the attributes are handled as special cases, not generic attributes, simply because there can only be at most 3 and they are always the same. */ class TiXmlDeclaration : public TiXmlNode { public: /// Construct an empty declaration. TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {} #ifdef TIXML_USE_STL /// Constructor. TiXmlDeclaration( const std::string& _version, const std::string& _encoding, const std::string& _standalone ); #endif /// Construct. TiXmlDeclaration( const char* _version, const char* _encoding, const char* _standalone ); TiXmlDeclaration( const TiXmlDeclaration& copy ); TiXmlDeclaration& operator=( const TiXmlDeclaration& copy ); virtual ~TiXmlDeclaration() {} /// Version. Will return an empty string if none was found. const char *Version() const { return version.c_str (); } /// Encoding. Will return an empty string if none was found. const char *Encoding() const { return encoding.c_str (); } /// Is this a standalone document? const char *Standalone() const { return standalone.c_str (); } /// Creates a copy of this Declaration and returns it. virtual TiXmlNode* Clone() const; // Print this declaration to a FILE stream. virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; virtual void Print( FILE* cfile, int depth ) const { Print( cfile, depth, 0 ); } #ifdef ZLIB_H virtual void gzPrint( gzFile cfile, int depth, TIXML_STRING* str ) const; virtual void gzPrint( gzFile cfile, int depth ) const { gzPrint( cfile, depth, 0 ); } #endif virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* visitor ) const; protected: void CopyTo( TiXmlDeclaration* target ) const; // used to be public #ifdef TIXML_USE_STL virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); #endif private: TIXML_STRING version; TIXML_STRING encoding; TIXML_STRING standalone; }; /** Any tag that tinyXml doesn't recognize is saved as an unknown. It is a tag of text, but should not be modified. It will be written back to the XML, unchanged, when the file is saved. DTD tags get thrown into TiXmlUnknowns. */ class TiXmlUnknown : public TiXmlNode { public: TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {} virtual ~TiXmlUnknown() {} TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); } TiXmlUnknown& operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); return *this; } /// Creates a copy of this Unknown and returns it. virtual TiXmlNode* Clone() const; // Print this Unknown to a FILE stream. virtual void Print( FILE* cfile, int depth ) const; #ifdef ZLIB_H virtual void gzPrint( gzFile cfile, int depth ) const; #endif virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* content ) const; protected: void CopyTo( TiXmlUnknown* target ) const; #ifdef TIXML_USE_STL virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); #endif private: }; /** Always the top level node. A document binds together all the XML pieces. It can be saved, loaded, and printed to the screen. The 'value' of a document node is the xml file name. */ class TiXmlDocument : public TiXmlNode { public: /// Create an empty document, that has no name. TiXmlDocument(); /// Create a document with a name. The name of the document is also the filename of the xml. TiXmlDocument( const char * documentName ); #ifdef TIXML_USE_STL /// Constructor. TiXmlDocument( const std::string& documentName ); #endif TiXmlDocument( const TiXmlDocument& copy ); TiXmlDocument& operator=( const TiXmlDocument& copy ); virtual ~TiXmlDocument() {} /** Load a file using the current document value. Returns true if successful. Will delete any existing document data before loading. */ bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); /// Save a file using the current document value. Returns true if successful. bool SaveFile() const; /// Load a file using the given filename. Returns true if successful. bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); /// Save a file using the given filename. Returns true if successful. bool SaveFile( const char * filename ) const; bool SaveFile( const char * filename, char compression ) const; /** Load a file using the given FILE*. Returns true if successful. Note that this method doesn't stream - the entire object pointed at by the FILE* will be interpreted as an XML file. TinyXML doesn't stream in XML from the current file location. Streaming may be added in the future. */ bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); /// Save a file using the given FILE*. Returns true if successful. bool SaveFile( FILE* ) const; #ifdef ZLIB_H bool LoadFile( gzFile, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); bool SaveFile( gzFile ) const; #endif #ifdef TIXML_USE_STL bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. { return LoadFile( filename.c_str(), encoding ); } bool SaveFile( const std::string& filename ) const ///< STL std::string version. { return SaveFile( filename.c_str() ); } #endif /** Parse the given null terminated block of xml data. Passing in an encoding to this method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml to use that encoding, regardless of what TinyXml might otherwise try to detect. */ virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); /** Get the root element -- the only top level element -- of the document. In well formed XML, there should only be one. TinyXml is tolerant of multiple elements at the document level. */ const TiXmlElement* RootElement() const { return FirstChildElement(); } TiXmlElement* RootElement() { return FirstChildElement(); } /** If an error occurs, Error will be set to true. Also, - The ErrorId() will contain the integer identifier of the error (not generally useful) - The ErrorDesc() method will return the name of the error. (very useful) - The ErrorRow() and ErrorCol() will return the location of the error (if known) */ bool Error() const { return error; } /// Contains a textual (english) description of the error if one occurs. const char * ErrorDesc() const { return errorDesc.c_str (); } /** Generally, you probably want the error string ( ErrorDesc() ). But if you prefer the ErrorId, this function will fetch it. */ int ErrorId() const { return errorId; } /** Returns the location (if known) of the error. The first column is column 1, and the first row is row 1. A value of 0 means the row and column wasn't applicable (memory errors, for example, have no row/column) or the parser lost the error. (An error in the error reporting, in that case.) @sa SetTabSize, Row, Column */ int ErrorRow() const { return errorLocation.row+1; } int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) to report the correct values for row and column. It does not change the output or input in any way. By calling this method, with a tab size greater than 0, the row and column of each node and attribute is stored when the file is loaded. Very useful for tracking the DOM back in to the source file. The tab size is required for calculating the location of nodes. If not set, the default of 4 is used. The tabsize is set per document. Setting the tabsize to 0 disables row/column tracking. Note that row and column tracking is not supported when using operator>>. The tab size needs to be enabled before the parse or load. Correct usage: @verbatim TiXmlDocument doc; doc.SetTabSize( 8 ); doc.Load( "myfile.xml" ); @endverbatim @sa Row, Column */ void SetTabSize( int _tabsize ) { tabsize = _tabsize; } int TabSize() const { return tabsize; } /** If you have handled the error, it can be reset with this call. The error state is automatically cleared if you Parse a new XML block. */ void ClearError() { error = false; errorId = 0; errorDesc = ""; errorLocation.row = errorLocation.col = 0; //errorLocation.last = 0; } /** Write the document to standard out using formatted printing ("pretty print"). */ void Print() const { Print( stdout, 0 ); } /* Write the document to a string using formatted printing ("pretty print"). This will allocate a character array (new char[]) and return it as a pointer. The calling code pust call delete[] on the return char* to avoid a memory leak. */ //char* PrintToMemory() const; /// Print this Document to a FILE stream. virtual void Print( FILE* cfile, int depth = 0 ) const; #ifdef ZLIB_H virtual void gzPrint( gzFile cfile, int depth = 0 ) const; #endif // [internal use] void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. /** Walk the XML tree visiting this node and all of its children. */ virtual bool Accept( TiXmlVisitor* content ) const; protected : // [internal use] virtual TiXmlNode* Clone() const; #ifdef TIXML_USE_STL virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); #endif private: void CopyTo( TiXmlDocument* target ) const; bool error; int errorId; TIXML_STRING errorDesc; int tabsize; TiXmlCursor errorLocation; bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. }; /** A TiXmlHandle is a class that wraps a node pointer with null checks; this is an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml DOM structure. It is a separate utility class. Take an example: @verbatim @endverbatim Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very easy to write a *lot* of code that looks like: @verbatim TiXmlElement* root = document.FirstChildElement( "Document" ); if ( root ) { TiXmlElement* element = root->FirstChildElement( "Element" ); if ( element ) { TiXmlElement* child = element->FirstChildElement( "Child" ); if ( child ) { TiXmlElement* child2 = child->NextSiblingElement( "Child" ); if ( child2 ) { // Finally do something useful. @endverbatim And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity of such code. A TiXmlHandle checks for null pointers so it is perfectly safe and correct to use: @verbatim TiXmlHandle docHandle( &document ); TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); if ( child2 ) { // do something useful @endverbatim Which is MUCH more concise and useful. It is also safe to copy handles - internally they are nothing more than node pointers. @verbatim TiXmlHandle handleCopy = handle; @endverbatim What they should not be used for is iteration: @verbatim int i=0; while ( true ) { TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); if ( !child ) break; // do something ++i; } @endverbatim It seems reasonable, but it is in fact two embedded while loops. The Child method is a linear walk to find the element, so this code would iterate much more than it needs to. Instead, prefer: @verbatim TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); for( child; child; child=child->NextSiblingElement() ) { // do something } @endverbatim */ class TiXmlHandle { public: /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } /// Copy constructor TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } TiXmlHandle operator=( const TiXmlHandle& ref ) { if ( &ref != this ) this->node = ref.node; return *this; } /// Return a handle to the first child node. TiXmlHandle FirstChild() const; /// Return a handle to the first child node with the given name. TiXmlHandle FirstChild( const char * value ) const; /// Return a handle to the first child element. TiXmlHandle FirstChildElement() const; /// Return a handle to the first child element with the given name. TiXmlHandle FirstChildElement( const char * value ) const; /** Return a handle to the "index" child with the given name. The first child is 0, the second 1, etc. */ TiXmlHandle Child( const char* value, int index ) const; /** Return a handle to the "index" child. The first child is 0, the second 1, etc. */ TiXmlHandle Child( int index ) const; /** Return a handle to the "index" child element with the given name. The first child element is 0, the second 1, etc. Note that only TiXmlElements are indexed: other types are not counted. */ TiXmlHandle ChildElement( const char* value, int index ) const; /** Return a handle to the "index" child element. The first child element is 0, the second 1, etc. Note that only TiXmlElements are indexed: other types are not counted. */ TiXmlHandle ChildElement( int index ) const; #ifdef TIXML_USE_STL TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } #endif /** Return the handle as a TiXmlNode. This may return null. */ TiXmlNode* ToNode() const { return node; } /** Return the handle as a TiXmlElement. This may return null. */ TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } /** Return the handle as a TiXmlText. This may return null. */ TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } /** Return the handle as a TiXmlUnknown. This may return null. */ TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } /** @deprecated use ToNode. Return the handle as a TiXmlNode. This may return null. */ TiXmlNode* Node() const { return ToNode(); } /** @deprecated use ToElement. Return the handle as a TiXmlElement. This may return null. */ TiXmlElement* Element() const { return ToElement(); } /** @deprecated use ToText() Return the handle as a TiXmlText. This may return null. */ TiXmlText* Text() const { return ToText(); } /** @deprecated use ToUnknown() Return the handle as a TiXmlUnknown. This may return null. */ TiXmlUnknown* Unknown() const { return ToUnknown(); } private: TiXmlNode* node; }; /** Print to memory functionality. The TiXmlPrinter is useful when you need to: -# Print to memory (especially in non-STL mode) -# Control formatting (line endings, etc.) When constructed, the TiXmlPrinter is in its default "pretty printing" mode. Before calling Accept() you can call methods to control the printing of the XML document. After TiXmlNode::Accept() is called, the printed document can be accessed via the CStr(), Str(), and Size() methods. TiXmlPrinter uses the Visitor API. @verbatim TiXmlPrinter printer; printer.SetIndent( "\t" ); doc.Accept( &printer ); fprintf( stdout, "%s", printer.CStr() ); @endverbatim */ class TiXmlPrinter : public TiXmlVisitor { public: TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), buffer(), indent( " " ), lineBreak( "\n" ) {} virtual bool VisitEnter( const TiXmlDocument& doc ); virtual bool VisitExit( const TiXmlDocument& doc ); virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); virtual bool VisitExit( const TiXmlElement& element ); virtual bool Visit( const TiXmlDeclaration& declaration ); virtual bool Visit( const TiXmlText& text ); virtual bool Visit( const TiXmlComment& comment ); virtual bool Visit( const TiXmlUnknown& unknown ); /** Set the indent characters for printing. By default 4 spaces but tab (\t) is also useful, or null/empty string for no indentation. */ void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } /// Query the indention string. const char* Indent() { return indent.c_str(); } /** Set the line breaking string. By default set to newline (\n). Some operating systems prefer other characters, or can be set to the null/empty string for no indenation. */ void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } /// Query the current line breaking string. const char* LineBreak() { return lineBreak.c_str(); } /** Switch over to "stream printing" which is the most dense formatting without linebreaks. Common when the XML is needed for network transmission. */ void SetStreamPrinting() { indent = ""; lineBreak = ""; } /// Return the result. const char* CStr() { return buffer.c_str(); } /// Return the length of the result string. size_t Size() { return buffer.size(); } #ifdef TIXML_USE_STL /// Return the result. const std::string& Str() { return buffer; } #endif private: void DoIndent() { for( int i=0; i #include /* The support for explicit isn't that universal, and it isn't really required - it is used to check that the TiXmlString class isn't incorrectly used. Be nice to old compilers and macro it here: */ #if defined(_MSC_VER) && (_MSC_VER >= 1200 ) // Microsoft visual studio, version 6 and higher. #define TIXML_EXPLICIT explicit #elif defined(__GNUC__) && (__GNUC__ >= 3 ) // GCC version 3 and higher.s #define TIXML_EXPLICIT explicit #else #define TIXML_EXPLICIT #endif /* TiXmlString is an emulation of a subset of the std::string template. Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. Only the member functions relevant to the TinyXML project have been implemented. The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase a string and there's no more room, we allocate a buffer twice as big as we need. */ class TiXmlString { public : // The size type used typedef size_t size_type; // Error value for find primitive static const size_type npos; // = -1; // TiXmlString empty constructor TiXmlString () : rep_(&nullrep_) { } // TiXmlString copy constructor TiXmlString ( const TiXmlString & copy) : rep_(0) { init(copy.length()); memcpy(start(), copy.data(), length()); } // TiXmlString constructor, based on a string TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) { init( static_cast( strlen(copy) )); memcpy(start(), copy, length()); } // TiXmlString constructor, based on a string TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) { init(len); memcpy(start(), str, len); } // TiXmlString destructor ~TiXmlString () { quit(); } TiXmlString& operator = (const char * copy) { return assign( copy, (size_type)strlen(copy)); } TiXmlString& operator = (const TiXmlString & copy) { return assign(copy.start(), copy.length()); } // += operator. Maps to append TiXmlString& operator += (const char * suffix) { return append(suffix, static_cast( strlen(suffix) )); } // += operator. Maps to append TiXmlString& operator += (char single) { return append(&single, 1); } // += operator. Maps to append TiXmlString& operator += (const TiXmlString & suffix) { return append(suffix.data(), suffix.length()); } // Convert a TiXmlString into a null-terminated char * const char * c_str () const { return rep_->str; } // Convert a TiXmlString into a char * (need not be null terminated). const char * data () const { return rep_->str; } // Return the length of a TiXmlString size_type length () const { return rep_->size; } // Alias for length() size_type size () const { return rep_->size; } // Checks if a TiXmlString is empty bool empty () const { return rep_->size == 0; } // Return capacity of string size_type capacity () const { return rep_->capacity; } // single char extraction const char& at (size_type index) const { assert( index < length() ); return rep_->str[ index ]; } // [] operator char& operator [] (size_type index) const { assert( index < length() ); return rep_->str[ index ]; } // find a char in a string. Return TiXmlString::npos if not found size_type find (char lookup) const { return find(lookup, 0); } // find a char in a string from an offset. Return TiXmlString::npos if not found size_type find (char tofind, size_type offset) const { if (offset >= length()) return npos; for (const char* p = c_str() + offset; *p != '\0'; ++p) { if (*p == tofind) return static_cast< size_type >( p - c_str() ); } return npos; } void clear () { //Lee: //The original was just too strange, though correct: // TiXmlString().swap(*this); //Instead use the quit & re-init: quit(); init(0,0); } /* Function to reserve a big amount of data when we know we'll need it. Be aware that this function DOES NOT clear the content of the TiXmlString if any exists. */ void reserve (size_type cap); TiXmlString& assign (const char* str, size_type len); TiXmlString& append (const char* str, size_type len); void swap (TiXmlString& other) { Rep* r = rep_; rep_ = other.rep_; other.rep_ = r; } private: void init(size_type sz) { init(sz, sz); } void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } char* start() const { return rep_->str; } char* finish() const { return rep_->str + rep_->size; } struct Rep { size_type size, capacity; char str[1]; }; void init(size_type sz, size_type cap) { if (cap) { // Lee: the original form: // rep_ = static_cast(operator new(sizeof(Rep) + cap)); // doesn't work in some cases of new being overloaded. Switching // to the normal allocation, although use an 'int' for systems // that are overly picky about structure alignment. const size_type bytesNeeded = sizeof(Rep) + cap; const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); rep_ = reinterpret_cast( new int[ intsNeeded ] ); rep_->str[ rep_->size = sz ] = '\0'; rep_->capacity = cap; } else { rep_ = &nullrep_; } } void quit() { if (rep_ != &nullrep_) { // The rep_ is really an array of ints. (see the allocator, above). // Cast it back before delete, so the compiler won't incorrectly call destructors. delete [] ( reinterpret_cast( rep_ ) ); } } Rep * rep_; static Rep nullrep_; } ; inline bool operator == (const TiXmlString & a, const TiXmlString & b) { return ( a.length() == b.length() ) // optimization on some platforms && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare } inline bool operator < (const TiXmlString & a, const TiXmlString & b) { return strcmp(a.c_str(), b.c_str()) < 0; } inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); TiXmlString operator + (const TiXmlString & a, const char* b); TiXmlString operator + (const char* a, const TiXmlString & b); /* TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. Only the operators that we need for TinyXML have been developped. */ class TiXmlOutStream : public TiXmlString { public : // TiXmlOutStream << operator. TiXmlOutStream & operator << (const TiXmlString & in) { *this += in; return *this; } // TiXmlOutStream << operator. TiXmlOutStream & operator << (const char * in) { *this += in; return *this; } } ; #endif // TIXML_STRING_INCLUDED #endif // TIXML_USE_STL stimfit-0.16.7/src/biosig/biosig4c++/XMLParser/tinyxml.cpp0000664000175000017500000013237714752215315016712 /* www.sourceforge.net/projects/tinyxml Original code by Lee Thomason (www.grinninglizard.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Modified: Copyright (C) 2009 Alois Schloegl add support for zlib-compressed (gzipped) XML data $Id: tinyxml.h,v 1.5 2009/04/09 09:12:09 schloegl Exp $ Copyright (C) 2009,2011 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. */ #include #include #ifdef TIXML_USE_STL #include #include #endif #include "tinyxml.h" FILE* TiXmlFOpen( const char* filename, const char* mode ); bool TiXmlBase::condenseWhiteSpace = true; // Microsoft compiler security FILE* TiXmlFOpen( const char* filename, const char* mode ) { #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) FILE* fp = 0; errno_t err = fopen_s( &fp, filename, mode ); if ( !err && fp ) return fp; return 0; #else return fopen( filename, mode ); #endif } void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) { int i=0; while( i<(int)str.length() ) { unsigned char c = (unsigned char) str[i]; if ( c == '&' && i < ( (int)str.length() - 2 ) && str[i+1] == '#' && str[i+2] == 'x' ) { // Hexadecimal character reference. // Pass through unchanged. // © -- copyright symbol, for example. // // The -1 is a bug fix from Rob Laveaux. It keeps // an overflow from happening if there is no ';'. // There are actually 2 ways to exit this loop - // while fails (error case) and break (semicolon found). // However, there is no mechanism (currently) for // this function to return an error. while ( i<(int)str.length()-1 ) { outString->append( str.c_str() + i, 1 ); ++i; if ( str[i] == ';' ) break; } } else if ( c == '&' ) { outString->append( entity[0].str, entity[0].strLength ); ++i; } else if ( c == '<' ) { outString->append( entity[1].str, entity[1].strLength ); ++i; } else if ( c == '>' ) { outString->append( entity[2].str, entity[2].strLength ); ++i; } else if ( c == '\"' ) { outString->append( entity[3].str, entity[3].strLength ); ++i; } else if ( c == '\'' ) { outString->append( entity[4].str, entity[4].strLength ); ++i; } else if ( c < 32 ) { // Easy pass at non-alpha/numeric/symbol // Below 32 is symbolic. char buf[ 32 ]; #if defined(TIXML_SNPRINTF) TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); #else sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); #endif //*ME: warning C4267: convert 'size_t' to 'int' //*ME: Int-Cast to make compiler happy ... outString->append( buf, (int)strlen( buf ) ); ++i; } else { //char realc = (char) c; //outString->append( &realc, 1 ); *outString += (char) c; // somewhat more efficient function call. ++i; } } } TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() { parent = 0; type = _type; firstChild = 0; lastChild = 0; prev = 0; next = 0; } TiXmlNode::~TiXmlNode() { TiXmlNode* node = firstChild; TiXmlNode* temp = 0; while ( node ) { temp = node; node = node->next; delete temp; } } void TiXmlNode::CopyTo( TiXmlNode* target ) const { target->SetValue (value.c_str() ); target->userData = userData; target->location = location; } void TiXmlNode::Clear() { TiXmlNode* node = firstChild; TiXmlNode* temp = 0; while ( node ) { temp = node; node = node->next; delete temp; } firstChild = 0; lastChild = 0; } TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) { assert( node->parent == 0 || node->parent == this ); assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT ) { delete node; if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); return 0; } node->parent = this; node->prev = lastChild; node->next = 0; if ( lastChild ) lastChild->next = node; else firstChild = node; // it was an empty list. lastChild = node; return node; } TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) { if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) { if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); return 0; } TiXmlNode* node = addThis.Clone(); if ( !node ) return 0; return LinkEndChild( node ); } TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) { if ( !beforeThis || beforeThis->parent != this ) { return 0; } if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) { if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); return 0; } TiXmlNode* node = addThis.Clone(); if ( !node ) return 0; node->parent = this; node->next = beforeThis; node->prev = beforeThis->prev; if ( beforeThis->prev ) { beforeThis->prev->next = node; } else { assert( firstChild == beforeThis ); firstChild = node; } beforeThis->prev = node; return node; } TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) { if ( !afterThis || afterThis->parent != this ) { return 0; } if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT ) { if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); return 0; } TiXmlNode* node = addThis.Clone(); if ( !node ) return 0; node->parent = this; node->prev = afterThis; node->next = afterThis->next; if ( afterThis->next ) { afterThis->next->prev = node; } else { assert( lastChild == afterThis ); lastChild = node; } afterThis->next = node; return node; } TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) { if ( !replaceThis ) return 0; if ( replaceThis->parent != this ) return 0; if ( withThis.ToDocument() ) { // A document can never be a child. Thanks to Noam. TiXmlDocument* document = GetDocument(); if ( document ) document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); return 0; } TiXmlNode* node = withThis.Clone(); if ( !node ) return 0; node->next = replaceThis->next; node->prev = replaceThis->prev; if ( replaceThis->next ) replaceThis->next->prev = node; else lastChild = node; if ( replaceThis->prev ) replaceThis->prev->next = node; else firstChild = node; delete replaceThis; node->parent = this; return node; } bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) { if ( !removeThis ) { return false; } if ( removeThis->parent != this ) { assert( 0 ); return false; } if ( removeThis->next ) removeThis->next->prev = removeThis->prev; else lastChild = removeThis->prev; if ( removeThis->prev ) removeThis->prev->next = removeThis->next; else firstChild = removeThis->next; delete removeThis; return true; } const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const { const TiXmlNode* node; for ( node = firstChild; node; node = node->next ) { if ( strcmp( node->Value(), _value ) == 0 ) return node; } return 0; } const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const { const TiXmlNode* node; for ( node = lastChild; node; node = node->prev ) { if ( strcmp( node->Value(), _value ) == 0 ) return node; } return 0; } const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const { if ( !previous ) { return FirstChild(); } else { assert( previous->parent == this ); return previous->NextSibling(); } } const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const { if ( !previous ) { return FirstChild( val ); } else { assert( previous->parent == this ); return previous->NextSibling( val ); } } const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const { const TiXmlNode* node; for ( node = next; node; node = node->next ) { if ( strcmp( node->Value(), _value ) == 0 ) return node; } return 0; } const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const { const TiXmlNode* node; for ( node = prev; node; node = node->prev ) { if ( strcmp( node->Value(), _value ) == 0 ) return node; } return 0; } void TiXmlElement::RemoveAttribute( const char * name ) { #ifdef TIXML_USE_STL TIXML_STRING str( name ); TiXmlAttribute* node = attributeSet.Find( str ); #else TiXmlAttribute* node = attributeSet.Find( name ); #endif if ( node ) { attributeSet.Remove( node ); delete node; } } const TiXmlElement* TiXmlNode::FirstChildElement() const { const TiXmlNode* node; for ( node = FirstChild(); node; node = node->NextSibling() ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const { const TiXmlNode* node; for ( node = FirstChild( _value ); node; node = node->NextSibling( _value ) ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } const TiXmlElement* TiXmlNode::NextSiblingElement() const { const TiXmlNode* node; for ( node = NextSibling(); node; node = node->NextSibling() ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const { const TiXmlNode* node; for ( node = NextSibling( _value ); node; node = node->NextSibling( _value ) ) { if ( node->ToElement() ) return node->ToElement(); } return 0; } const TiXmlDocument* TiXmlNode::GetDocument() const { const TiXmlNode* node; for( node = this; node; node = node->parent ) { if ( node->ToDocument() ) return node->ToDocument(); } return 0; } TiXmlElement::TiXmlElement (const char * _value) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) { firstChild = lastChild = 0; value = _value; } #ifdef TIXML_USE_STL TiXmlElement::TiXmlElement( const std::string& _value ) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) { firstChild = lastChild = 0; value = _value; } #endif TiXmlElement::TiXmlElement( const TiXmlElement& copy) : TiXmlNode( TiXmlNode::TINYXML_ELEMENT ) { firstChild = lastChild = 0; copy.CopyTo( this ); } TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base ) { ClearThis(); base.CopyTo( this ); return *this; } TiXmlElement::~TiXmlElement() { ClearThis(); } void TiXmlElement::ClearThis() { Clear(); while( attributeSet.First() ) { TiXmlAttribute* node = attributeSet.First(); attributeSet.Remove( node ); delete node; } } const char* TiXmlElement::Attribute( const char* name ) const { const TiXmlAttribute* node = attributeSet.Find( name ); if ( node ) return node->Value(); return 0; } #ifdef TIXML_USE_STL const std::string* TiXmlElement::Attribute( const std::string& name ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); if ( attrib ) return &attrib->ValueStr(); return 0; } #endif const char* TiXmlElement::Attribute( const char* name, int* i ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); const char* result = 0; if ( attrib ) { result = attrib->Value(); if ( i ) { attrib->QueryIntValue( i ); } } return result; } #ifdef TIXML_USE_STL const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); const std::string* result = 0; if ( attrib ) { result = &attrib->ValueStr(); if ( i ) { attrib->QueryIntValue( i ); } } return result; } #endif const char* TiXmlElement::Attribute( const char* name, double* d ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); const char* result = 0; if ( attrib ) { result = attrib->Value(); if ( d ) { attrib->QueryDoubleValue( d ); } } return result; } #ifdef TIXML_USE_STL const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); const std::string* result = 0; if ( attrib ) { result = &attrib->ValueStr(); if ( d ) { attrib->QueryDoubleValue( d ); } } return result; } #endif int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); if ( !attrib ) return TIXML_NO_ATTRIBUTE; return attrib->QueryIntValue( ival ); } int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const { const TiXmlAttribute* node = attributeSet.Find( name ); if ( !node ) return TIXML_NO_ATTRIBUTE; int ival = 0; int result = node->QueryIntValue( &ival ); *value = (unsigned)ival; return result; } int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const { const TiXmlAttribute* node = attributeSet.Find( name ); if ( !node ) return TIXML_NO_ATTRIBUTE; int result = TIXML_WRONG_TYPE; if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN ) || StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN ) || StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) ) { *bval = true; result = TIXML_SUCCESS; } else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN ) || StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN ) || StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) ) { *bval = false; result = TIXML_SUCCESS; } return result; } #ifdef TIXML_USE_STL int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); if ( !attrib ) return TIXML_NO_ATTRIBUTE; return attrib->QueryIntValue( ival ); } #endif int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); if ( !attrib ) return TIXML_NO_ATTRIBUTE; return attrib->QueryDoubleValue( dval ); } #ifdef TIXML_USE_STL int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const { const TiXmlAttribute* attrib = attributeSet.Find( name ); if ( !attrib ) return TIXML_NO_ATTRIBUTE; return attrib->QueryDoubleValue( dval ); } #endif void TiXmlElement::SetAttribute( const char * name, int val ) { TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); if ( attrib ) { attrib->SetIntValue( val ); } } #ifdef TIXML_USE_STL void TiXmlElement::SetAttribute( const std::string& name, int val ) { TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); if ( attrib ) { attrib->SetIntValue( val ); } } #endif void TiXmlElement::SetDoubleAttribute( const char * name, double val ) { TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); if ( attrib ) { attrib->SetDoubleValue( val ); } } #ifdef TIXML_USE_STL void TiXmlElement::SetDoubleAttribute( const std::string& name, double val ) { TiXmlAttribute* attrib = attributeSet.FindOrCreate( name ); if ( attrib ) { attrib->SetDoubleValue( val ); } } #endif void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) { TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname ); if ( attrib ) { attrib->SetValue( cvalue ); } } #ifdef TIXML_USE_STL void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value ) { TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name ); if ( attrib ) { attrib->SetValue( _value ); } } #endif void TiXmlElement::Print( FILE* cfile, int depth ) const { int i; assert( cfile ); for ( i=0; iNext() ) { fprintf( cfile, " " ); attrib->Print( cfile, depth ); } // There are 3 different formatting approaches: // 1) An element without children is printed as a node // 2) An element with only a text child is printed as text // 3) An element with children is printed on multiple lines. TiXmlNode* node; if ( !firstChild ) { fprintf( cfile, " />" ); } else if ( firstChild == lastChild && firstChild->ToText() ) { fprintf( cfile, ">" ); firstChild->Print( cfile, depth + 1 ); fprintf( cfile, "", value.c_str() ); } else { fprintf( cfile, ">" ); for ( node = firstChild; node; node=node->NextSibling() ) { if ( !node->ToText() ) { fprintf( cfile, "\n" ); } node->Print( cfile, depth+1 ); } fprintf( cfile, "\n" ); for( i=0; i", value.c_str() ); } } #ifdef ZLIB_H void TiXmlElement::gzPrint( gzFile cfile, int depth ) const { int i; assert( cfile ); for ( i=0; iNext() ) { gzprintf( cfile, " " ); attrib->gzPrint( cfile, depth ); } // There are 3 different formatting approaches: // 1) An element without children is printed as a node // 2) An element with only a text child is printed as text // 3) An element with children is printed on multiple lines. TiXmlNode* node; if ( !firstChild ) { gzprintf( cfile, " />" ); } else if ( firstChild == lastChild && firstChild->ToText() ) { gzprintf( cfile, ">" ); firstChild->gzPrint( cfile, depth + 1 ); gzprintf( cfile, "", value.c_str() ); } else { gzprintf( cfile, ">" ); for ( node = firstChild; node; node=node->NextSibling() ) { if ( !node->ToText() ) { gzprintf( cfile, "\n" ); } node->gzPrint( cfile, depth+1 ); } gzprintf( cfile, "\n" ); for( i=0; i", value.c_str() ); } } #endif void TiXmlElement::CopyTo( TiXmlElement* target ) const { // superclass: TiXmlNode::CopyTo( target ); // Element class: // Clone the attributes, then clone the children. const TiXmlAttribute* attribute = 0; for( attribute = attributeSet.First(); attribute; attribute = attribute->Next() ) { target->SetAttribute( attribute->Name(), attribute->Value() ); } TiXmlNode* node = 0; for ( node = firstChild; node; node = node->NextSibling() ) { target->LinkEndChild( node->Clone() ); } } bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const { if ( visitor->VisitEnter( *this, attributeSet.First() ) ) { for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) { if ( !node->Accept( visitor ) ) break; } } return visitor->VisitExit( *this ); } TiXmlNode* TiXmlElement::Clone() const { TiXmlElement* clone = new TiXmlElement( Value() ); if ( !clone ) return 0; CopyTo( clone ); return clone; } const char* TiXmlElement::GetText() const { const TiXmlNode* child = this->FirstChild(); if ( child ) { const TiXmlText* childText = child->ToText(); if ( childText ) { return childText->Value(); } } return 0; } TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) { tabsize = 4; useMicrosoftBOM = false; ClearError(); } TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) { tabsize = 4; useMicrosoftBOM = false; value = documentName; ClearError(); } #ifdef TIXML_USE_STL TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) { tabsize = 4; useMicrosoftBOM = false; value = documentName; ClearError(); } #endif TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT ) { copy.CopyTo( this ); } TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy ) { Clear(); copy.CopyTo( this ); return *this; } bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) { return LoadFile( Value(), encoding ); } bool TiXmlDocument::SaveFile() const { return SaveFile( Value() ); } bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) { TIXML_STRING filename( _filename ); value = filename; // reading in binary mode so that tinyxml can normalize the EOL #ifdef ZLIB_H gzFile file; file = gzopen( value.c_str(), "rb" ); if ( file ) { bool result = LoadFile( file, encoding ); gzclose( file ); return result; } #else FILE* file = TiXmlFOpen( value.c_str (), "rb" ); if ( file ) { bool result = LoadFile( file, encoding ); fclose( file ); return result; } #endif else { SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); return false; } } bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) { if ( !file ) { SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); return false; } // Delete the existing data: Clear(); location.Clear(); // Get the file size, so we can pre-allocate the string. HUGE speed impact. size_t length = 0; fseek( file, 0, SEEK_END ); length = ftell( file ); fseek( file, 0, SEEK_SET ); // Strange case, but good to handle up front. if ( length <= 0 ) { SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); return false; } // Subtle bug here. TinyXml did use fgets. But from the XML spec: // 2.11 End-of-Line Handling // // // ...the XML processor MUST behave as if it normalized all line breaks in external // parsed entities (including the document entity) on input, before parsing, by translating // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to // a single #xA character. // // // It is not clear fgets does that, and certainly isn't clear it works cross platform. // Generally, you expect fgets to translate from the convention of the OS to the c/unix // convention, and not work generally. /* while( fgets( buf, sizeof(buf), file ) ) { data += buf; } */ char* buf = new char[ length+1 ]; buf[0] = 0; if ( fread( buf, length, 1, file ) != 1 ) { delete [] buf; SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); return false; } #if defined(_ICONV_H) || defined (_LIBICONV_H) || defined(_ICONV_H_) // convert utf-16 to utf-8 if needed const char XML_UTF16LE[] = "\xff\xfe<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0\"\0001\0.\0000\0\"\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0\"\0U\0T\0F\0-\0001\0006\0\"\0?\0>\0"; if (!memcmp(buf, XML_UTF16LE, sizeof(XML_UTF16LE)-1 ) ) { char *buf2 = (char*)malloc(length); size_t outlen = length; char *inbuf = buf; char *outbuf = buf2; iconv_t CD = iconv_open ("UTF-8","UTF-16LE"); size_t iconv_res = iconv (CD, &inbuf, &length, &outbuf, &outlen); iconv_close (CD); if (iconv_res != (size_t)(-1)) { free(buf); outbuf[0] = 0; buf = buf2; length = strlen(buf); } else { free(buf2); fprintf(stderr,"SOPEN_HL7aECG: attempt to convert UTF-16 to UTF-8 failed\n"); } } #else fprintf(stderr,"SOPEN_HL7aECG: conversion of UTF-16 to UTF-8 is not supported\n"); #endif // Process the buffer in place to normalize new lines. (See comment above.) // Copies from the 'p' to 'q' pointer, where p can advance faster if // a newline-carriage return is hit. // // Wikipedia: // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 const char* p = buf; // the read head char* q = buf; // the write head const char CR = 0x0d; const char LF = 0x0a; buf[length] = 0; while( *p ) { assert( p < (buf+length) ); assert( q <= (buf+length) ); assert( q <= p ); if ( *p == CR ) { *q++ = LF; p++; if ( *p == LF ) { // check for CR+LF (and skip LF) p++; } } else { *q++ = *p++; } } assert( q <= (buf+length) ); *q = 0; Parse( buf, 0, encoding ); delete [] buf; return !Error(); } #ifdef ZLIB_H bool TiXmlDocument::LoadFile(gzFile file, TiXmlEncoding encoding ) { char *buf = NULL; size_t length = 0; // file is loaded in hdr->AS.Header; size_t buflen = 1l<<18; while (!gzeof(file)) { buf = (char*)realloc(buf, buflen); length += gzread(file, buf+length, buflen-length-1); buflen *= 2; } buf[length] = 0; buf = (char*)realloc(buf,length+1); #ifdef _ICONV_H // convert utf-16 to utf-8 if needed const char XML_UTF16LE[] = "\xff\xfe<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0\"\0001\0.\0000\0\"\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0\"\0U\0T\0F\0-\0001\0006\0\"\0?\0>\0"; if (!memcmp(buf, XML_UTF16LE, sizeof(XML_UTF16LE)-1 ) ) { char *buf2 = (char*)malloc(length); size_t outlen = length; char *inbuf = buf; char *outbuf = buf2; iconv_t CD = iconv_open ("UTF-8","UTF-16LE"); size_t iconv_res = iconv (CD, &inbuf, &length, &outbuf, &outlen); iconv_close (CD); if (iconv_res != (size_t)(-1)) { free(buf); outbuf[0] = 0; buf = buf2; length = strlen(buf); } else { free(buf2); fprintf(stderr,"SOPEN_HL7aECG: attempt to convert UTF-16 to UTF-8 failed\n"); } } #endif // Process the buffer in place to normalize new lines. (See comment above.) // Copies from the 'p' to 'q' pointer, where p can advance faster if // a newline-carriage return is hit. // // Wikipedia: // Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or // CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)... // * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others // * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS // * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9 const char* p = buf; // the read head char* q = buf; // the write head const char CR = 0x0d; const char LF = 0x0a; while( *p ) { assert( p < (buf+length) ); assert( q <= (buf+length) ); assert( q <= p ); if ( *p == CR ) { *q++ = LF; p++; if ( *p == LF ) { // check for CR+LF (and skip LF) p++; } } else { *q++ = *p++; } } assert( q <= (buf+length) ); *q = 0; Parse( buf, 0, encoding ); delete [] buf; return !Error(); } #endif bool TiXmlDocument::SaveFile( const char * filename, char compression ) const { // The old c stuff lives on... if (compression) { #ifdef ZLIB_H gzFile fid = gzopen(filename, "wb" ); if (fid) { bool result = SaveFile(fid); gzclose(fid); return result; } #else fprintf(stdout,"warning: zlib compression not supported\n"); #endif } else { FILE *fid = fopen(filename, "wb" ); if (fid) { bool result = SaveFile(fid); fclose(fid); return result; } } return false; } bool TiXmlDocument::SaveFile( const char * filename ) const { // The old c stuff lives on... FILE* fp = TiXmlFOpen( filename, "w" ); if ( fp ) { bool result = SaveFile( fp ); fclose( fp ); return result; } return false; } bool TiXmlDocument::SaveFile( FILE* fp ) const { if ( useMicrosoftBOM ) { const unsigned char TIXML_UTF_LEAD_0 = 0xefU; const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; fputc( TIXML_UTF_LEAD_0, fp ); fputc( TIXML_UTF_LEAD_1, fp ); fputc( TIXML_UTF_LEAD_2, fp ); } Print( fp, 0 ); return (ferror(fp) == 0); } #ifdef ZLIB_H bool TiXmlDocument::SaveFile( gzFile fp ) const { if ( useMicrosoftBOM ) { const unsigned char TIXML_UTF_LEAD_0 = 0xefU; const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; gzputc( fp, TIXML_UTF_LEAD_0 ); gzputc( fp, TIXML_UTF_LEAD_1 ); gzputc( fp, TIXML_UTF_LEAD_2 ); } gzPrint( fp, 0 ); int err; gzerror(fp,&err); return (err!=0); } #endif void TiXmlDocument::CopyTo( TiXmlDocument* target ) const { TiXmlNode::CopyTo( target ); target->error = error; target->errorId = errorId; target->errorDesc = errorDesc; target->tabsize = tabsize; target->errorLocation = errorLocation; target->useMicrosoftBOM = useMicrosoftBOM; TiXmlNode* node = 0; for ( node = firstChild; node; node = node->NextSibling() ) { target->LinkEndChild( node->Clone() ); } } TiXmlNode* TiXmlDocument::Clone() const { TiXmlDocument* clone = new TiXmlDocument(); if ( !clone ) return 0; CopyTo( clone ); return clone; } void TiXmlDocument::Print( FILE* cfile, int depth ) const { assert( cfile ); for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) { node->Print( cfile, depth ); fprintf( cfile, "\n" ); } } #ifdef ZLIB_H void TiXmlDocument::gzPrint( gzFile cfile, int depth ) const { assert( cfile ); for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) { node->gzPrint( cfile, depth ); gzprintf( cfile, "\n" ); } } #endif bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const { if ( visitor->VisitEnter( *this ) ) { for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) { if ( !node->Accept( visitor ) ) break; } } return visitor->VisitExit( *this ); } const TiXmlAttribute* TiXmlAttribute::Next() const { // We are using knowledge of the sentinel. The sentinel // have a value or name. if ( next->value.empty() && next->name.empty() ) return 0; return next; } /* TiXmlAttribute* TiXmlAttribute::Next() { // We are using knowledge of the sentinel. The sentinel // have a value or name. if ( next->value.empty() && next->name.empty() ) return 0; return next; } */ const TiXmlAttribute* TiXmlAttribute::Previous() const { // We are using knowledge of the sentinel. The sentinel // have a value or name. if ( prev->value.empty() && prev->name.empty() ) return 0; return prev; } /* TiXmlAttribute* TiXmlAttribute::Previous() { // We are using knowledge of the sentinel. The sentinel // have a value or name. if ( prev->value.empty() && prev->name.empty() ) return 0; return prev; } */ void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const { TIXML_STRING n, v; EncodeString( name, &n ); EncodeString( value, &v ); if (value.find ('\"') == TIXML_STRING::npos) { if ( cfile ) { fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); } if ( str ) { (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; } } else { if ( cfile ) { fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); } if ( str ) { (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; } } } #ifdef ZLIB_H void TiXmlAttribute::gzPrint( gzFile cfile, int /*depth*/, TIXML_STRING* str ) const { TIXML_STRING n, v; EncodeString( name, &n ); EncodeString( value, &v ); if (value.find ('\"') == TIXML_STRING::npos) { if ( cfile ) { gzprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); } if ( str ) { (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; } } else { if ( cfile ) { gzprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); } if ( str ) { (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; } } } #endif int TiXmlAttribute::QueryIntValue( int* ival ) const { if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) return TIXML_SUCCESS; return TIXML_WRONG_TYPE; } int TiXmlAttribute::QueryDoubleValue( double* dval ) const { if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) return TIXML_SUCCESS; return TIXML_WRONG_TYPE; } void TiXmlAttribute::SetIntValue( int _value ) { char buf [64]; #if defined(TIXML_SNPRINTF) TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); #else sprintf (buf, "%d", _value); #endif SetValue (buf); } void TiXmlAttribute::SetDoubleValue( double _value ) { char buf [256]; #if defined(TIXML_SNPRINTF) TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value); #else sprintf (buf, "%g", _value); #endif SetValue (buf); } int TiXmlAttribute::IntValue() const { return atoi (value.c_str ()); } double TiXmlAttribute::DoubleValue() const { return atof (value.c_str ()); } TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) { copy.CopyTo( this ); } TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base ) { Clear(); base.CopyTo( this ); return *this; } void TiXmlComment::Print( FILE* cfile, int depth ) const { assert( cfile ); for ( int i=0; i", value.c_str() ); } #ifdef ZLIB_H void TiXmlComment::gzPrint( gzFile cfile, int depth ) const { assert( cfile ); for ( int i=0; i", value.c_str() ); } #endif void TiXmlComment::CopyTo( TiXmlComment* target ) const { TiXmlNode::CopyTo( target ); } bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const { return visitor->Visit( *this ); } TiXmlNode* TiXmlComment::Clone() const { TiXmlComment* clone = new TiXmlComment(); if ( !clone ) return 0; CopyTo( clone ); return clone; } void TiXmlText::Print( FILE* cfile, int depth ) const { assert( cfile ); if ( cdata ) { int i; fprintf( cfile, "\n" ); for ( i=0; i\n", value.c_str() ); // unformatted output } else { TIXML_STRING buffer; EncodeString( value, &buffer ); fprintf( cfile, "%s", buffer.c_str() ); } } #ifdef ZLIB_H void TiXmlText::gzPrint( gzFile cfile, int depth ) const { assert( cfile ); if ( cdata ) { int i; gzprintf( cfile, "\n" ); for ( i=0; i\n", value.c_str() ); // unformatted output } else { TIXML_STRING buffer; EncodeString( value, &buffer ); gzprintf( cfile, "%s", buffer.c_str() ); } } #endif void TiXmlText::CopyTo( TiXmlText* target ) const { TiXmlNode::CopyTo( target ); target->cdata = cdata; } bool TiXmlText::Accept( TiXmlVisitor* visitor ) const { return visitor->Visit( *this ); } TiXmlNode* TiXmlText::Clone() const { TiXmlText* clone = 0; clone = new TiXmlText( "" ); if ( !clone ) return 0; CopyTo( clone ); return clone; } TiXmlDeclaration::TiXmlDeclaration( const char * _version, const char * _encoding, const char * _standalone ) : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) { version = _version; encoding = _encoding; standalone = _standalone; } #ifdef TIXML_USE_STL TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, const std::string& _encoding, const std::string& _standalone ) : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) { version = _version; encoding = _encoding; standalone = _standalone; } #endif TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) { copy.CopyTo( this ); } TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) { Clear(); copy.CopyTo( this ); return *this; } void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const { if ( cfile ) fprintf( cfile, "" ); if ( str ) (*str) += "?>"; } #ifdef ZLIB_H void TiXmlDeclaration::gzPrint( gzFile cfile, int /*depth*/, TIXML_STRING* str ) const { if ( cfile ) gzprintf( cfile, "" ); if ( str ) (*str) += "?>"; } #endif void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const { TiXmlNode::CopyTo( target ); target->version = version; target->encoding = encoding; target->standalone = standalone; } bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const { return visitor->Visit( *this ); } TiXmlNode* TiXmlDeclaration::Clone() const { TiXmlDeclaration* clone = new TiXmlDeclaration(); if ( !clone ) return 0; CopyTo( clone ); return clone; } void TiXmlUnknown::Print( FILE* cfile, int depth ) const { for ( int i=0; i", value.c_str() ); } #ifdef ZLIB_H void TiXmlUnknown::gzPrint( gzFile cfile, int depth ) const { for ( int i=0; i", value.c_str() ); } #endif void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const { TiXmlNode::CopyTo( target ); } bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const { return visitor->Visit( *this ); } TiXmlNode* TiXmlUnknown::Clone() const { TiXmlUnknown* clone = new TiXmlUnknown(); if ( !clone ) return 0; CopyTo( clone ); return clone; } TiXmlAttributeSet::TiXmlAttributeSet() { sentinel.next = &sentinel; sentinel.prev = &sentinel; } TiXmlAttributeSet::~TiXmlAttributeSet() { assert( sentinel.next == &sentinel ); assert( sentinel.prev == &sentinel ); } void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) { #ifdef TIXML_USE_STL assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. #else assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. #endif addMe->next = &sentinel; addMe->prev = sentinel.prev; sentinel.prev->next = addMe; sentinel.prev = addMe; } void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) { TiXmlAttribute* node; for( node = sentinel.next; node != &sentinel; node = node->next ) { if ( node == removeMe ) { node->prev->next = node->next; node->next->prev = node->prev; node->next = 0; node->prev = 0; return; } } assert( 0 ); // we tried to remove a non-linked attribute. } #ifdef TIXML_USE_STL TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const { for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) { if ( node->name == name ) return node; } return 0; } TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name ) { TiXmlAttribute* attrib = Find( _name ); if ( !attrib ) { attrib = new TiXmlAttribute(); Add( attrib ); attrib->SetName( _name ); } return attrib; } #endif TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const { for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) { if ( strcmp( node->name.c_str(), name ) == 0 ) return node; } return 0; } TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name ) { TiXmlAttribute* attrib = Find( _name ); if ( !attrib ) { attrib = new TiXmlAttribute(); Add( attrib ); attrib->SetName( _name ); } return attrib; } #ifdef TIXML_USE_STL std::istream& operator>> (std::istream & in, TiXmlNode & base) { TIXML_STRING tag; tag.reserve( 8 * 1000 ); base.StreamIn( &in, &tag ); base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); return in; } #endif #ifdef TIXML_USE_STL std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) { TiXmlPrinter printer; printer.SetStreamPrinting(); base.Accept( &printer ); out << printer.Str(); return out; } std::string& operator<< (std::string& out, const TiXmlNode& base ) { TiXmlPrinter printer; printer.SetStreamPrinting(); base.Accept( &printer ); out.append( printer.Str() ); return out; } #endif TiXmlHandle TiXmlHandle::FirstChild() const { if ( node ) { TiXmlNode* child = node->FirstChild(); if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const { if ( node ) { TiXmlNode* child = node->FirstChild( value ); if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::FirstChildElement() const { if ( node ) { TiXmlElement* child = node->FirstChildElement(); if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const { if ( node ) { TiXmlElement* child = node->FirstChildElement( value ); if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::Child( int count ) const { if ( node ) { int i; TiXmlNode* child = node->FirstChild(); for ( i=0; child && iNextSibling(), ++i ) { // nothing } if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const { if ( node ) { int i; TiXmlNode* child = node->FirstChild( value ); for ( i=0; child && iNextSibling( value ), ++i ) { // nothing } if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::ChildElement( int count ) const { if ( node ) { int i; TiXmlElement* child = node->FirstChildElement(); for ( i=0; child && iNextSiblingElement(), ++i ) { // nothing } if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const { if ( node ) { int i; TiXmlElement* child = node->FirstChildElement( value ); for ( i=0; child && iNextSiblingElement( value ), ++i ) { // nothing } if ( child ) return TiXmlHandle( child ); } return TiXmlHandle( 0 ); } bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) { return true; } bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) { return true; } bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) { DoIndent(); buffer += "<"; buffer += element.Value(); for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) { buffer += " "; attrib->Print( 0, 0, &buffer ); } if ( !element.FirstChild() ) { buffer += " />"; DoLineBreak(); } else { buffer += ">"; if ( element.FirstChild()->ToText() && element.LastChild() == element.FirstChild() && element.FirstChild()->ToText()->CDATA() == false ) { simpleTextPrint = true; // no DoLineBreak()! } else { DoLineBreak(); } } ++depth; return true; } bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) { --depth; if ( !element.FirstChild() ) { // nothing. } else { if ( simpleTextPrint ) { simpleTextPrint = false; } else { DoIndent(); } buffer += ""; DoLineBreak(); } return true; } bool TiXmlPrinter::Visit( const TiXmlText& text ) { if ( text.CDATA() ) { DoIndent(); buffer += ""; DoLineBreak(); } else if ( simpleTextPrint ) { TIXML_STRING str; TiXmlBase::EncodeString( text.ValueTStr(), &str ); buffer += str; } else { DoIndent(); TIXML_STRING str; TiXmlBase::EncodeString( text.ValueTStr(), &str ); buffer += str; DoLineBreak(); } return true; } bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) { DoIndent(); declaration.Print( 0, 0, &buffer ); DoLineBreak(); return true; } bool TiXmlPrinter::Visit( const TiXmlComment& comment ) { DoIndent(); buffer += ""; DoLineBreak(); return true; } bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) { DoIndent(); buffer += "<"; buffer += unknown.Value(); buffer += ">"; DoLineBreak(); return true; } stimfit-0.16.7/src/biosig/biosig4c++/XMLParser/tinyxmlerror.cpp0000664000175000017500000000337714752215315017761 /* www.sourceforge.net/projects/tinyxml Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #include "tinyxml.h" // The goal of the seperate error file is to make the first // step towards localization. tinyxml (currently) only supports // english error messages, but the could now be translated. // // It also cleans up the code a bit. // const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] = { "No error", "Error", "Failed to open file", "Error parsing Element.", "Failed to read Element name", "Error reading Element value.", "Error reading Attributes.", "Error: empty tag.", "Error reading end tag.", "Error parsing Unknown.", "Error parsing Comment.", "Error parsing Declaration.", "Error document empty.", "Error null (0) or unexpected EOF found in input stream.", "Error parsing CDATA.", "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", }; stimfit-0.16.7/src/biosig/biosig4c++/test0/0000775000175000017500000000000014764352501013771 5stimfit-0.16.7/src/biosig/biosig4c++/test0/sandbox.c0000664000175000017500000005466614752215315015532 /* sandbox is used for development and under constraction work The functions here are either under construction or experimental. The functions will be either fixed, then they are moved to another place; or the functions are discarded. Do not rely on the interface in this function Copyright (C) 2008-2014 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "../biosig.h" #ifdef _WIN32 // Can't include sys/stat.h or sopen is declared twice. #include struct stat { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; _dev_t st_rdev; _off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; }; int __cdecl stat(const char *_Filename,struct stat *_Stat); #else #include #endif #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) /************************************************************************* use DCMTK for reading DICOM files *************************************************************************/ #ifdef WITH_DCMTK #undef WITH_DICOM // disable internal DICOM implementation #undef WITH_GDCM // disable interface to GDCM #ifdef __cplusplus extern "C" { #endif int sopen_dcmtk_read(HDRTYPE* hdr); int sopen_dicom_read(HDRTYPE* hdr) { return sopen_dcmtk_read(hdr); } #ifdef __cplusplus } #endif #endif // DCMTK /************************************************************************* use GDCM for reading DICOM files *************************************************************************/ #ifdef WITH_GDCM #undef WITH_DICOM #include "gdcmReader.h" //#include "gdcmImageReader.h" //#include "gdcmWriter.h" #include "gdcmDataSet.h" #include "gdcmAttribute.h" //#include "gdcmCommon.h" //#include "gdcmPreamble.h" #include "gdcmFile.h" #include "gdcmFileMetaInformation.h" #include "gdcmWaveform.h" /* This is the list from gdcmconv.cxx #include "gdcmReader.h" #include "gdcmFileDerivation.h" #include "gdcmAnonymizer.h" #include "gdcmVersion.h" #include "gdcmPixmapReader.h" #include "gdcmPixmapWriter.h" #include "gdcmWriter.h" #include "gdcmSystem.h" #include "gdcmFileMetaInformation.h" #include "gdcmDataSet.h" #include "gdcmIconImageGenerator.h" #include "gdcmAttribute.h" #include "gdcmSequenceOfItems.h" #include "gdcmUIDGenerator.h" #include "gdcmImage.h" #include "gdcmImageChangeTransferSyntax.h" #include "gdcmImageApplyLookupTable.h" #include "gdcmImageFragmentSplitter.h" #include "gdcmImageChangePlanarConfiguration.h" #include "gdcmImageChangePhotometricInterpretation.h" #include "gdcmFileExplicitFilter.h" #include "gdcmJPEG2000Codec.h" #include "gdcmJPEGCodec.h" #include "gdcmJPEGLSCodec.h" #include "gdcmSequenceOfFragments.h" */ int sopen_dicom_read(HDRTYPE* hdr) { fprintf(stdout,"%s ( line %d): GDCM is used to read dicom files.\n",__func__,__LINE__); gdcm::Reader reader; const gdcm::DataElement *de; reader.SetFileName( hdr->FileName ); if ( !reader.Read() ) { fprintf(stdout,"%s (line %i) \n",__FILE__,__LINE__); return 1; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__FILE__,__LINE__); gdcm::File &file = reader.GetFile(); gdcm::FileMetaInformation &header = file.GetHeader(); if ( header.FindDataElement( gdcm::Tag(0x0002, 0x0013 ) ) ) const gdcm::DataElement &de = header.GetDataElement( gdcm::Tag(0x0002, 0x0013) ); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__FILE__,__LINE__); gdcm::DataSet &ds = file.GetDataSet(); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__FILE__,__LINE__); if ( header.FindDataElement( gdcm::Tag(0x0002, 0x0010 ) ) ) de = &header.GetDataElement( gdcm::Tag(0x0002, 0x0010) ); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x0002,0x0010> len=%i\n",__FILE__,__LINE__,de->GetByteValue() ); if (0) { gdcm::Attribute<0x28,0x100> at; at.SetFromDataElement( ds.GetDataElement( at.GetTag() ) ); if( at.GetValue() != 8 ) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x0002,0x0010> GetValue\n",__FILE__,__LINE__ ); return 1; } at.SetValue( 32 ); ds.Replace( at.GetAsDataElement() ); } { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x0008,0x002a>\n",__FILE__,__LINE__); gdcm::Attribute<0x0008,0x002a> at; ds.GetDataElement( at.GetTag() ); at.SetFromDataElement( ds.GetDataElement( at.GetTag() ) ); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x0008,0x002a>\n",__FILE__,__LINE__); // fprintf(stdout,"DCM: [0008,002a]: %i %p\n", at.GetNumberOfValues(), at.GetValue()); } { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x0008,0x0023>\n",__FILE__,__LINE__); gdcm::Attribute<0x0008,0x0023> at; ds.GetDataElement( at.GetTag() ); at.SetFromDataElement( ds.GetDataElement( at.GetTag() ) ); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x0008,0x0023>\n",__FILE__,__LINE__); } if (1) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x003a,0x0005>\n",__FILE__,__LINE__); gdcm::Attribute<0x003a,0x0005> NumberOfWaveformChannels; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x003a,0x0005> %i\n",__FILE__,__LINE__, NumberOfWaveformChannels.GetValue()); // ds.GetDataElement( NumberOfWaveformChannels.GetTag() ); // NumberOfWaveformChannels.SetFromDataElement( ds.GetDataElement( NumberOfWaveformChannels.GetTag() ) ); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x003a,0x0005> %i\n",__FILE__,__LINE__, NumberOfWaveformChannels.GetValue()); } { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x003a,0x0010>\n",__FILE__,__LINE__); gdcm::Attribute<0x003a,0x0010> NumberOfWaveformSamples; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x003a,0x0010> %i\n",__FILE__,__LINE__, NumberOfWaveformSamples.GetValue()); // fprintf(stdout,"DCM: [0008,0023]: %i %p\n",at.GetNumberOfValues(), at.GetValue()); } gdcm::Attribute<0x003a,0x001a> SamplingFrequency; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): attr <0x003a,0x001a> %f\n",__FILE__,__LINE__, SamplingFrequency.GetValue()); return 0; } #endif #ifdef __cplusplus extern "C" { #endif uint16_t fiff_physdimcode(int32_t unit) { switch (unit) { case 0: return 0; case 1: return PhysDimCode("m"); case 2: return PhysDimCode("kg"); case 3: return PhysDimCode("s"); case 4: return PhysDimCode("A"); case 5: return PhysDimCode("K"); case 6: return PhysDimCode("mol"); case 7: return PhysDimCode("rad"); case 8: return PhysDimCode("sr"); case 9: return PhysDimCode("cd"); case 101: return PhysDimCode("Hz"); case 102: return PhysDimCode("N"); case 103: return PhysDimCode("Pa"); case 104: return PhysDimCode("J"); case 105: return PhysDimCode("W"); case 106: return PhysDimCode("C"); case 107: return PhysDimCode("V"); case 108: return PhysDimCode("F"); case 109: return PhysDimCode("Ohm"); case 110: return PhysDimCode("S"); case 111: return PhysDimCode("Vs"); case 112: return PhysDimCode("T"); case 113: return PhysDimCode("H"); case 114: return PhysDimCode("°C"); case 115: return PhysDimCode("lm"); case 116: return PhysDimCode("Lx"); case 201: return PhysDimCode("T/m"); case 202: return PhysDimCode("Am"); } return 0; } gdftime_t julian2gdftype(void* val) { // https://github.com/mne-tools/mne-python/blob/main/mne/utils/numerics.py return floor(ldexp(beu32p(val)-2440588+719529.5, 32)); } int sopen_fiff_read(HDRTYPE* hdr) { /* TODO: implement FIFF support define all fields in hdr->.... currently only the first hdr->HeadLen bytes are stored in hdr->AS.Header, all other fields still need to be defined. */ size_t count = hdr->HeadLen; #if defined(_WIN32) || !defined(_SYS_STAT_H) || defined(ZLIB_H) // stat(...) can not be used in windows because including causes a namespace conflict with sopen while (!feof(hdr->FILE.FID)) { void *ptr = realloc(hdr->AS.Header, count*2); if (ptr==NULL) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "FIFF: memory allocation"); return -1; } hdr->AS.Header = (uint8_t*)ptr; count += ifread(hdr->AS.Header+count, 1, count, hdr); } fclose(hdr->FILE.FID); hdr->HeadLen = count; hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, count+1); #else struct stat FileBuf; stat(hdr->FileName,&FileBuf); void *ptr = realloc(hdr->AS.Header, FileBuf.st_size); if (ptr==NULL) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "FIFF: memory allocation"); return -1; } hdr->AS.Header = (uint8_t*)ptr; if (!feof(hdr->FILE.FID) ) count += ifread(hdr->AS.Header+count, 1, FileBuf.st_size-count, hdr); fclose(hdr->FILE.FID); hdr->HeadLen = count; if (count != FileBuf.st_size) biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "FIFF: read error"); #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"# %s line %d: %s(....) \n", __FILE__, __LINE__, __func__); char* firstname=NULL; char* middlename=NULL; char* surname=NULL; int nn1=0, nn2=0, nn3=0; float lowpass=0.0, highpass=0.0; uint32_t pos = 0, NumTags=0; while (1) { // fifftag_t* ct = (fifftag_t*)(hdr->AS.Header+pos); NumTags++; int32_t kind = bei32p(hdr->AS.Header+pos); int32_t type = bei32p(hdr->AS.Header+pos+4); int32_t size = bei32p(hdr->AS.Header+pos+8); int32_t next = bei32p(hdr->AS.Header+pos+12); uint8_t *val = hdr->AS.Header+(pos+16); if (VERBOSE_LEVEL>8) fprintf(stdout,"# FIFFTAG %d: %d, %08x, %d, %08x :\t%08x %9d %s \n", NumTags, kind, type, size, next, be32toh(*(uint32_t*)val), be32toh(*(uint32_t*)val), (char*)val); switch (kind) { case 107: // unused case 108: // nop break; case 200: hdr->NS = beu32p(val); hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); break; case 201: hdr->SampleRate = bef32p(val); break; case 203: { int32_t scanNo = bei32p(val); int32_t logNo = bei32p(val+4); int32_t chankind = bei32p(val+8); float range = bef32p(val+12); double cal = bef32p(val+16); uint32_t unit = beu32p(val+72); uint32_t unitm = beu32p(val+76); CHANNEL_TYPE* hc = hdr->CHANNEL + scanNo; hc->Cal = range * cal * pow(10.0, unitm); hc->Off = 0.0; hc->PhysDimCode = fiff_physdimcode(unit); hc->SPR = hdr->SPR; hc->GDFTYP = 3; hc->LowPass = lowpass; hc->HighPass = highpass; break; } case 204: hdr->T0 = julian2gdftype(val); break; case 219: lowpass = bef32p(val); break; case 223: highpass = bef32p(val); break; case 228: hdr->SPR = beu32p(val); break; case 401: nn1=size; firstname=(char*)val; break; case 402: nn2=size; middlename=(char*)val; break; case 403: nn3=size; surname=(char*)val; break; case 404: hdr->Patient.Birthday = julian2gdftype(val); break; case 405: hdr->Patient.Sex = beu32p(val); break; case 406: hdr->Patient.Handedness = beu32p(val); break; case 407: hdr->Patient.Weight = lef32p(val); break; case 408: hdr->Patient.Height = lef32p(val); break; // case 409: break; case 410: strncpy(hdr->Patient.Id, (char*)val, MAX_LENGTH_PID+1); break; default: if (VERBOSE_LEVEL>4) fprintf(stdout,"# FIFFTAG %d ignored: %d, %08x, %d, %08x :\t%08x %9d %s \n", NumTags, kind, type, size, next, be32toh(*(uint32_t*)val), be32toh(*(uint32_t*)val), (char*)val); ; } // if (next==0) pos += size+16; else if (next == -1) break; else pos = next; } if (!hdr->FLAG.ANONYMOUS) { strncpy(hdr->Patient.Name, surname, min(nn3,MAX_LENGTH_NAME)); if (nn3 < MAX_LENGTH_NAME) { hdr->Patient.Name[nn3] = 0x1f; strncpy(hdr->Patient.Name+nn3+1, firstname, min(nn1,MAX_LENGTH_NAME-nn3-1)); } if (nn3+nn1+1 < MAX_LENGTH_NAME) { hdr->Patient.Name[nn3+1+nn1] = 0x1f; strncpy(hdr->Patient.Name+nn3+nn1+2, middlename, min(nn2,MAX_LENGTH_NAME-nn3-2-nn1)); } hdr->Patient.Name[min(nn1+nn2+nn3+2,MAX_LENGTH_NAME)]=0; } fflush(stdout); /* define channel headers */ hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (int k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; } /* define event table */ hdr->EVENT.N = 0; //reallocEventTable(hdr, 0); /* report status header and return */ hdr2ascii(hdr,stdout,4); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "FIFF support not completed"); return 0; } int sopen_unipro_read(HDRTYPE* hdr) { hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); char *Header1 = (char*)hdr->AS.Header; struct tm t0; char tmp[5]; memset(tmp,0,5); strncpy(tmp,Header1+0x9c,2); t0.tm_mon = atoi(tmp)-1; strncpy(tmp,Header1+0x9e,2); t0.tm_mday = atoi(tmp); strncpy(tmp,Header1+0xa1,2); t0.tm_hour = atoi(tmp); strncpy(tmp,Header1+0xa3,2); t0.tm_min = atoi(tmp); strncpy(tmp,Header1+0xa5,2); t0.tm_sec = atoi(tmp); strncpy(tmp,Header1+0x98,4); t0.tm_year = atoi(tmp)-1900; hdr->T0 = tm_time2gdf_time(&t0); memset(tmp,0,5); strncpy(tmp,Header1+0x85,2); t0.tm_mday = atoi(tmp); strncpy(tmp,Header1+0x83,2); t0.tm_mon = atoi(tmp)-1; strncpy(tmp,Header1+0x7f,4); t0.tm_year = atoi(tmp)-1900; hdr->Patient.Birthday = tm_time2gdf_time(&t0); // filesize = leu32p(hdr->AS.Header + 0x24); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "UNIPRO not supported"); return(0); } /************************************************************************* use internal implementation for reading DICOM files *************************************************************************/ #ifdef WITH_DICOM int sopen_dicom_read(HDRTYPE* hdr) { fprintf(stdout,"home-made parser is used to read dicom files.\n"); char FLAG_implicite_VR = 0; int EndOfGroup2=-1; if (hdr->HeadLen<132) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, 132); hdr->HeadLen += ifread(hdr->AS.Header+hdr->HeadLen, 1, 132-hdr->HeadLen, hdr); } size_t count = hdr->HeadLen; size_t pos = 128; while (!hdr->AS.Header[pos] && (pos<128)) pos++; if ((pos==128) && !memcmp(hdr->AS.Header+128,"DICM",4)) { // FLAG_implicite_VR = 0; pos = 132; } else pos = 0; size_t bufsiz = 16384; while (!ifeof(hdr)) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, count+bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz, hdr); bufsiz *= 2; } ifclose(hdr); hdr->AS.Header[count] = 0; uint16_t nextTag[2]; struct tm T0; char flag_t0=0; char flag_ignored; uint32_t Tag; uint32_t Len; nextTag[0] = *(uint16_t*)(hdr->AS.Header+pos); nextTag[1] = *(uint16_t*)(hdr->AS.Header+pos+2); while (pos < count) { if ((__BYTE_ORDER == __BIG_ENDIAN) ^ !hdr->FILE.LittleEndian) { // swapping required Tag = (((uint32_t)bswap_16(nextTag[0])) << 16) + bswap_16(nextTag[1]); pos += 4; if (FLAG_implicite_VR) { Len = bswap_32(*(uint32_t*)(hdr->AS.Header+pos)); pos += 4; } else { // explicite_VR if (pos+4 > count) break; if (memcmp(hdr->AS.Header+pos,"OB",2) && memcmp(hdr->AS.Header+pos,"OW",2) && memcmp(hdr->AS.Header+pos,"OF",2) && memcmp(hdr->AS.Header+pos,"SQ",2) && memcmp(hdr->AS.Header+pos,"UT",2) && memcmp(hdr->AS.Header+pos,"UN",2) ) { Len = bswap_16(*(uint16_t*)(hdr->AS.Header+pos+2)); pos += 4; } else { Len = bswap_32(*(uint32_t*)(hdr->AS.Header+pos+4)); pos += 8; } } } else { // no swapping Tag = (((uint32_t)nextTag[0]) << 16) + nextTag[1]; pos += 4; if (FLAG_implicite_VR) { Len = *(uint32_t*)(hdr->AS.Header+pos); pos += 4; } else { // explicite_VR if (pos+4 > count) break; if (memcmp(hdr->AS.Header+pos,"OB",2) && memcmp(hdr->AS.Header+pos,"OW",2) && memcmp(hdr->AS.Header+pos,"OF",2) && memcmp(hdr->AS.Header+pos,"SQ",2) && memcmp(hdr->AS.Header+pos,"UT",2) && memcmp(hdr->AS.Header+pos,"UN",2) ) { Len = *(uint16_t*)(hdr->AS.Header+pos+2); pos += 4; } else { Len = *(uint32_t*)(hdr->AS.Header+pos+4); pos += 8; } } } /* backup next tag, this allows setting of terminating 0 */ if (pos+Len < count) { nextTag[0] = *(uint16_t*)(hdr->AS.Header+pos+Len); nextTag[1] = *(uint16_t*)(hdr->AS.Header+pos+Len+2); hdr->AS.Header[pos+Len] = 0; } flag_ignored = 0; if (VERBOSE_LEVEL>8) fprintf(stdout," %6x: (%04x,%04x) %8d\t%s\n",pos,Tag>>16,Tag&0x0ffff,Len,(char*)hdr->AS.Header+pos); switch (Tag) { /* elements of group 0x0002 use always Explicite VR little Endian encoding */ case 0x00020000: { int c = 0; if (!memcmp(hdr->AS.Header+pos-4,"UL",2)) c = leu32p(hdr->AS.Header+pos); else if (!memcmp(hdr->AS.Header+pos-4,"SL",2)) c = lei32p(hdr->AS.Header+pos); else if (!memcmp(hdr->AS.Header+pos-4,"US",2)) c = leu16p(hdr->AS.Header+pos); else if (!memcmp(hdr->AS.Header+pos-4,"SS",2)) c = lei16p(hdr->AS.Header+pos); else { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i<%i %i>\n",__FILE__,__LINE__,pos,hdr->AS.Header[pos-8],hdr->AS.Header[pos-7]); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "DICOM (0002,0000): unsupported"); } EndOfGroup2 = c + pos; break; } case 0x00020001: break; case 0x00020002: { hdr->NS = 1; char *t = (char*)hdr->AS.Header+pos; while (isspace(*t)) t++; // deblank char *ct[] = { "1.2.840.10008.5.1.4.1.1.9.1.1", "1.2.840.10008.5.1.4.1.1.9.1.2", "1.2.840.10008.5.1.4.1.1.9.1.3", "1.2.840.10008.5.1.4.1.1.9.2.1", "1.2.840.10008.5.1.4.1.1.9.3.1", "1.2.840.10008.5.1.4.1.1.9.4.1" }; if (!strcmp(t,*ct)) hdr->NS = 12; break; } case 0x00020003: break; case 0x00020010: { char *t = (char*)hdr->AS.Header+pos; while (isspace(*t)) t++; // deblank char *ct[] = { "1.2.840.10008.1.2", "1.2.840.10008.1.2.1", "1.2.840.10008.1.2.1.99", "1.2.840.10008.1.2.2" }; if (!strcmp(t,*ct)) FLAG_implicite_VR = 1; else if (!strcmp(t,*ct+1)) FLAG_implicite_VR = 0; else if (!strcmp(t,*ct+3)) FLAG_implicite_VR = 1; break; } case 0x00080020: // StudyDate case 0x00080023: // ContentDate { hdr->AS.Header[pos+8]=0; T0.tm_mday = atoi((char*)hdr->AS.Header+pos+6); hdr->AS.Header[pos+6]=0; T0.tm_mon = atoi((char*)hdr->AS.Header+pos+4)-1; hdr->AS.Header[pos+4]=0; T0.tm_year = atoi((char*)hdr->AS.Header+pos)-1900; flag_t0 |= 1; break; } case 0x0008002a: // AcquisitionDateTime { struct tm t0; hdr->AS.Header[pos+14]=0; t0.tm_sec = atoi((char*)hdr->AS.Header+pos+12); hdr->AS.Header[pos+12]=0; t0.tm_min = atoi((char*)hdr->AS.Header+pos+10); hdr->AS.Header[pos+10]=0; t0.tm_hour = atoi((char*)hdr->AS.Header+pos+8); hdr->AS.Header[pos+8]=0; t0.tm_mday = atoi((char*)hdr->AS.Header+pos+6); hdr->AS.Header[pos+6]=0; t0.tm_mon = atoi((char*)hdr->AS.Header+pos+4)-1; hdr->AS.Header[pos+4]=0; t0.tm_year = atoi((char*)hdr->AS.Header+pos)-1900; hdr->T0 = tm_time2gdf_time(&t0); break; } case 0x00080030: // StudyTime case 0x00080033: // ContentTime { hdr->AS.Header[pos+6]=0; T0.tm_sec = atoi((char*)hdr->AS.Header+pos+4); hdr->AS.Header[pos+4]=0; T0.tm_min = atoi((char*)hdr->AS.Header+pos+2); hdr->AS.Header[pos+2]=0; T0.tm_hour = atoi((char*)hdr->AS.Header+pos); flag_t0 |= 2; break; } case 0x00080070: // Manufacturer { strncpy(hdr->ID.Manufacturer._field,(char*)hdr->AS.Header+pos,MAX_LENGTH_MANUF); hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field; break; } case 0x00081050: // Performing Physician { strncpy(hdr->ID.Technician,(char*)hdr->AS.Header+pos,MAX_LENGTH_TECHNICIAN); break; } case 0x00081090: // Manufacturer Model { const size_t nn = strlen(hdr->ID.Manufacturer.Name)+1; strncpy(hdr->ID.Manufacturer._field+nn,(char*)hdr->AS.Header+pos,MAX_LENGTH_MANUF-nn-1); hdr->ID.Manufacturer.Model = hdr->ID.Manufacturer._field+nn; break; } case 0x00100010: // Name if (!hdr->FLAG.ANONYMOUS) { strncpy(hdr->Patient.Name,(char*)hdr->AS.Header+pos,MAX_LENGTH_NAME); hdr->Patient.Name[MAX_LENGTH_NAME]=0; } break; case 0x00100020: // ID strncpy(hdr->Patient.Id,(char*)hdr->AS.Header+pos,MAX_LENGTH_PID); hdr->Patient.Id[MAX_LENGTH_PID]=0; break; case 0x00100030: // Birthday { struct tm t0; t0.tm_sec = 0; t0.tm_min = 0; t0.tm_hour = 12; hdr->AS.Header[pos+8]=0; t0.tm_mday = atoi((char*)hdr->AS.Header+pos+6); hdr->AS.Header[pos+6]=0; t0.tm_mon = atoi((char*)hdr->AS.Header+pos+4)-1; hdr->AS.Header[pos+4]=0; t0.tm_year = atoi((char*)hdr->AS.Header+pos)-1900; hdr->Patient.Birthday = tm_time2gdf_time(&t0); break; } case 0x00100040: hdr->Patient.Sex = (toupper(hdr->AS.Header[pos])=='M') + 2*(toupper(hdr->AS.Header[pos])=='F'); break; case 0x00101010: //Age break; case 0x00101020: hdr->Patient.Height = (uint8_t)(atof((char*)hdr->AS.Header+pos)*100.0); break; case 0x00101030: hdr->Patient.Weight = (uint8_t)atoi((char*)hdr->AS.Header+pos); break; default: flag_ignored = 1; if (VERBOSE_LEVEL<7) fprintf(stdout,"ignored %6x: (%04x,%04x) %8d\t%s\n",pos,Tag>>16,Tag&0x0ffff,Len,(char*)hdr->AS.Header+pos); } if (VERBOSE_LEVEL>6) { if (!FLAG_implicite_VR || (Tag < 0x00030000)) fprintf(stdout,"%s %6x: (%04x,%04x) %8d %c%c \t%s\n",(flag_ignored?"ignored":" "),pos,Tag>>16,Tag&0x0ffff,Len,hdr->AS.Header[pos-8],hdr->AS.Header[pos-7],(char*)hdr->AS.Header+pos); else fprintf(stdout,"%s %6x: (%04x,%04x) %8d\t%s\n",(flag_ignored?"ignored":" "),pos,Tag>>16,Tag&0x0ffff,Len,(char*)hdr->AS.Header+pos); } pos += Len + (Len & 0x01 ? 1 : 0); // even number of bytes } if (flag_t0 == 3) hdr->T0 = tm_time2gdf_time(&T0); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__FILE__,__LINE__); return(0); } #endif #ifdef WITH_PDP #include "../NONFREE/sopen_pdp_read.c" #endif #ifdef WITH_TRC #include "../NONFREE/sopen_trc_read.c" #endif #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/mdc_ecg_codes.h0000664000175000017500000000341414752215315015561 /* % Copyright (C) 2014 Alois Schloegl % This file is part of the "BioSig for C/C++" repository % (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /**************************************************************************** ** ** ** Conversion functions for encoded physical units according to ** ** ISO/IEEE 11073-10102 Annex B ** ** ** ****************************************************************************/ #ifndef __MDC_ECG_CODES_H__ #define __MDC_ECG_CODES_H__ #if defined(_MSC_VER) && (_MSC_VER < 1600) typedef unsigned __int16 uint16_t; #else #include #endif #ifdef __cplusplus extern "C" { #endif uint16_t encode_mdc_ecg_code10 (const char *IDstr); uint32_t encode_mdc_ecg_cfcode10 (const char *IDstr); const char* decode_mdc_ecg_code10 (uint16_t code10); const char* decode_mdc_ecg_cfcode10 (uint32_t cf_code10); #ifdef __cplusplus } #endif #endif /* __PHYSICALUNITS_H__ */ stimfit-0.16.7/src/biosig/biosig4c++/gdftime.c0000664000175000017500000002374214752215315014443 /* Copyright (C) 2005-2013,2020 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Library function for conversion of gdf_time into other datetime formats. gdf_time is used in [1] and in Octave and Matlab. Also Python seems to use this format but with an offset of 366 days. References: [1] GDF - A general data format for biomedical signals. available online http://arxiv.org/abs/cs.DB/0608052 */ #define _GNU_SOURCE #include "gdftime.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Conversion of time formats between Unix and GDF format. The default time format in BIOSIG uses a 64-bit fixed point format with reference date 01-Jan-0000 00h00m00s (value=0). One unit indicates the 2^(-32) part of 1 day (ca 20 us). Accordingly, the higher 32 bits count the number of days, the lower 32 bits describe the fraction of a day. 01-Jan-1970 is the day 719529. time_t t0; t0 = time(NULL); T0 = (double)t0/86400.0; // convert seconds in days since 1970-Jan-01 floor(T0) + 719529; // number of days since 01-Jan-0000 floor(ldexp(T0-floor(T0),32)); // fraction x/2^32; one day is 2^32 The following macros define the conversions between the unix time and the GDF format. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define fix(m) (m<0 ? ceil(m) : floor(m)) gdf_time tm_time2gdf_time(struct tm *t){ /* based on Octave's datevec.m it referes Peter Baum's algorithm at http://vsg.cape.com/~pbaum/date/date0.htm but the link is not working anymore as of 2008-12-03. Other links to Peter Baum's algorithm are http://www.rexswain.com/b2mmddyy.rex http://www.dpwr.net/forums/index.php?s=ecfa72e38be61327403126e23aeea7e5&showtopic=4309 */ if (t == NULL) return(0); int Y,M,s; // h,m, double D; gdf_time o; const int monthstart[] = {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275}; D = (double)t->tm_mday; M = t->tm_mon+1; Y = t->tm_year+1900; // Set start of year to March by moving Jan. and Feb. to previous year. // Correct for months > 12 by moving to subsequent years. Y += fix ((M-14.0)/12); // Lookup number of days since start of the current year. D += monthstart[t->tm_mon % 12] + 60; // Add number of days to the start of the current year. Correct // for leap year every 4 years except centuries not divisible by 400. D += 365*Y + floor (Y/4.0) - floor (Y/100.0) + floor (Y/400.0); // Add fraction representing current second of the day. s = t->tm_hour*3600 + t->tm_min*60 + t->tm_sec; // s -= timezone; o = (((uint64_t)D) << 32) + (((uint64_t)s) << 32)/86400; return(o); } struct tm *gdf_time2tm_time(gdf_time t) { // this is not re-entrant, use gdf_time2tm_time_r instead /* based Octave's datevec.m it referes Peter Baum's algorithm at http://vsg.cape.com/~pbaum/date/date0.htm but the link is not working anymore as of 2008-12-03. Other links to Peter Baum's algorithm are http://www.rexswain.com/b2mmddyy.rex http://www.dpwr.net/forums/index.php?s=ecfa72e38be61327403126e23aeea7e5&showtopic=4309 */ static struct tm tt; // allocate memory for t3; gdf_time2tm_time_r(t,&tt); return(&tt); } struct gdf_time_tm_t { int YEAR; int MONTH; int MDAY; int HOUR; int MINUTE; double SECOND; }; int split_gdf_time(gdftime_t t, struct gdf_time_tm_t *gte) { /* based Octave's datevec.m it referes Peter Baum's algorithm at http://vsg.cape.com/~pbaum/date/date0.htm but the link is not working anymore as of 2008-12-03. Other links to Peter Baum's algorithm are http://www.rexswain.com/b2mmddyy.rex http://www.dpwr.net/forums/index.php?s=ecfa72e38be61327403126e23aeea7e5&showtopic=4309 */ int32_t rd = (int32_t)floor(ldexp((double)t,-32)); // days since 0001-01-01 double s = ldexp((t & 0x00000000ffffffff)*86400,-32); // seconds of the day // int32_t sec = round (s); // s += timezone; /* derived from datenum.m from Octave 3.0.0 */ // Move day 0 from midnight -0001-12-31 to midnight 0000-3-1 double z = floor (rd) - 60; // Calculate number of centuries; K1 = 0.25 is to avoid rounding problems. double a = floor ((z - 0.25) / 36524.25); // Days within century; K2 = 0.25 is to avoid rounding problems. double b = z - 0.25 + a - floor (a / 4); // Calculate the year (year starts on March 1). int y = (int)floor (b / 365.25); // Calculate day in year. double c = fix (b - floor (365.25 * y)) + 1; // Calculate month in year. double m = fix ((5 * c + 456) / 153); double d = c - fix ((153 * m - 457) / 5); // Move to Jan 1 as start of year. if (m>12) {y++; m-=12;} gte->YEAR = y; gte->MONTH = (int)m; gte->MDAY = (int)d; int h = (int) s / 3600; s = s - (3600 * h); m = s / 60; // !! reuse of m: is now minutes instead of month gte->HOUR = h; gte->MINUTE = (int) m; gte->SECOND = s - (60 * gte->MINUTE); //t3->tm_gmtoff = 3600; return(0); } int gdf_time2tm_time_r(gdftime_t t, struct tm *t3) { struct gdf_time_tm_t gte; split_gdf_time(t, >e); t3->tm_year = gte.YEAR-1900; t3->tm_mon = gte.MONTH-1; t3->tm_mday = gte.MDAY; t3->tm_hour = gte.HOUR; t3->tm_min = gte.MINUTE; t3->tm_sec = (int)gte.SECOND; } #if 0 gdftime_t string2gdftime(const char* str) { struct tm t; strptime(str,"%d %b %Y",&t); t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; return tm_time2gdf_time(&t); } gdftime_t string2gdfdate(const char* str) { struct tm t; strptime(str,"%d %b %Y",&t); t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; return tm_time2gdf_time(&t); } gdftime_t string2gdfdatetime(const char* str) { struct tm t; return tm_time2gdf_time(getdate(str)); } #endif size_t snprintf_gdftime(char *out, size_t outbytesleft, gdftime_t T) { struct gdf_time_tm_t gte; size_t len; split_gdf_time(T, >e); len = snprintf(out, outbytesleft, "%02d:%02d:", gte.HOUR, gte.MINUTE); outbytesleft -= len; out += len; double intSec; double fracSec=modf(gte.SECOND, &intSec); if (fracSec == 0.0) len = snprintf(out, outbytesleft, "%02d", (int)gte.SECOND); else len = snprintf(out, outbytesleft, "%09.6f", gte.SECOND); outbytesleft -= len; out += len; return len; } size_t snprintf_gdfdate(char *out, size_t outbytesleft, gdftime_t T) { struct gdf_time_tm_t gte; size_t len; split_gdf_time(T, >e); len = snprintf(out, outbytesleft, "%04d-%02d-%02d", gte.YEAR, gte.MONTH, gte.MDAY); outbytesleft -= len; out += len; return len; } size_t snprintf_gdfdatetime(char *out, size_t outbytesleft, gdftime_t T) { struct gdf_time_tm_t gte; size_t len; split_gdf_time(T, >e); len = snprintf(out, outbytesleft, "%04d-%02d-%02d %02d:%02d:", gte.YEAR, gte.MONTH, gte.MDAY, gte.HOUR, gte.MINUTE); outbytesleft -= len; out += len; double intSec; double fracSec=modf(gte.SECOND, &intSec); if (fracSec == 0.0) len = snprintf(out, outbytesleft, "%02d", (int)gte.SECOND); else len = snprintf(out, outbytesleft, "%09.6f", gte.SECOND); outbytesleft -= len; out += len; return len; } size_t strfgdftime(char *out, size_t outbytesleft, const char *FMT, gdftime_t T) { struct gdf_time_tm_t gte; struct tm tm; size_t len; int cin=0; int cout=0; char FMT2[4]="%%\0\0"; split_gdf_time(T, >e); gdf_time2tm_time_r(T, &tm); while ( cout < outbytesleft && cin 7) fprintf(stdout, "%s (line %i) %s\n", __FILE__, __LINE__, line); if (VERBOSE_LEVEL > 7) { char tmp[30]; strftime(tmp,30,"%F %T",&t); fprintf(stdout, "%s (line %i) %s\n", __FILE__, __LINE__, tmp); } } else if (!strncmp(line,"Date",p)) { strptime(line+p+1,"%d %b %Y",&t); t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; if (VERBOSE_LEVEL > 7) { char tmp[30]; strftime(tmp,30,"%F %T",&t); fprintf(stdout, "%s (line %i) %s\n", __FILE__, __LINE__, tmp); } } else if (!strncmp(line,"Time Stamp",p)) { hdr->SampleRate *= hdr->SPR*hdr->NRec/strtod(line+p+1,NULL); } line = strtok(NULL, "\n\r\0"); */ /****************************************************************************/ /** **/ /** EOF **/ /** **/ /****************************************************************************/ stimfit-0.16.7/src/biosig/biosig4c++/biosig-network.h0000664000175000017500000002302214752215315015763 /* Copyright (C) 2005,2006,2007,2008,2009,2016 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define IPv4 #ifndef __BIOSIG_NETWORK_H__ #define __BIOSIG_NETWORK_H__ #include "biosig-dev.h" #define SERVER_PORT 54321 #if defined(__MINGW32__) #include #include #ifndef socklen_t #define socklen_t int #endif /* mingw/include/errno.h */ #ifndef _INC_ERRNO #define EALREADY WSAEALREADY #define ECONNABORTED WSAECONNABORTED #define ECONNREFUSED WSAECONNREFUSED #define ECONNRESET WSAECONNRESET #define EHOSTDOWN WSAEHOSTDOWN #define EHOSTUNREACH WSAEHOSTUNREACH #define EINPROGRESS WSAEINPROGRESS #define EISCONN WSAEISCONN #define ENETDOWN WSAENETDOWN #define ENETRESET WSAENETRESET #define ENETUNREACH WSAENETUNREACH #define EWOULDBLOCK WSAEWOULDBLOCK #define EADDRINUSE WSAEADDRINUSE #define ENOTSUP ENOSYS #define ETIMEDOUT WSAETIMEDOUT #define ENOTSOCK WSAENOTSOCK #define ENOBUFS WSAENOBUFS #define EMSGSIZE WSAEMSGSIZE #define EADDRNOTAVAIL WSAEADDRNOTAVAIL #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #endif #if 0 //!__linux__ // needed by MinGW on Windows #define creat(a, c) OpenFile(a, O_WRONLY|O_CREAT|O_TRUNC, c) #define write(a,b,c) WriteFile(a,b,c,0,0) #define close(a) CloseFile(a) #endif #else #include #include #include #include #include #include #endif /* External API definitions */ /****************************************************************************/ /** **/ /** DEFINITIONS, TYPEDEFS AND MACROS **/ /** **/ /****************************************************************************/ /* client server commands*/ #define BSCS_ID_BITLEN 64 #define BSCS_MAX_BUFSIZ_LOG2 14 #define BSCS_MAX_BUFSIZ (1< (b)) ? (a) : (b)) typedef struct { uint32_t STATE; uint32_t LEN; uint8_t LOAD[max(8,BSCS_ID_BITLEN>>3)] __attribute__ ((aligned (8))); // must fit at least ID length } mesg_t __attribute__ ((aligned (8))); extern uint32_t SERVER_STATE; /****************************************************************************/ /** **/ /** EXPORTED FUNCTIONS **/ /** **/ /****************************************************************************/ #ifdef __cplusplus extern "C" { #endif int c64ta(uint64_t ID, char* txt); // convert 64bit to ascii int cat64(char* txt, uint64_t *ID); // convert ascii to 64bit void *get_in_addr(struct sockaddr *sa); /* biosig client-server functions */ int bscs_connect(const char* hostname); /* opens a connection to the server on success, the socket file descriptor (a positive integer) is returned in case of failure, a negative integer is returned -------------------------------------------------------------- */ int bscs_disconnect(int sd); /* disconnects the socket file descriptor -------------------------------------------------------------- */ int send_packet(int sd, uint32_t state, uint32_t len, void* load); /* send a single packet including header and load -------------------------------------------------------------- */ int bscs_open(int sd, uint64_t *ID); // read-open /* ID = 0 : write access, new identifier is returned in ID ID > 0 : read access to the file with known ID -------------------------------------------------------------- */ int bscs_close(int sd); /* close current connection -------------------------------------------------------------- */ int bscs_send_hdr(int sd, HDRTYPE *hdr); /* hdr->AS.Header must contain GDF header information hdr->HeadLen must contain header length -------------------------------------------------------------- */ int bscs_send_dat(int sd, void* buf, size_t len ); /* buf must contain the data block as in hdr->AS.rawdata -------------------------------------------------------------- */ int bscs_send_evt(int sd, HDRTYPE *hdr); /* hdr->EVENT defines the event table -------------------------------------------------------------- */ int bscs_send_msg(int sd, char* msg); /* msg is string -------------------------------------------------------------- */ int bscs_error(int sd, int ERRNUM, char* ERRMSG); /* ERRNUM contains the error number ERRMSG is string -------------------------------------------------------------- */ int bscs_requ_hdr(int sd, HDRTYPE *hdr); /* request header information -------------------------------------------------------------- */ ssize_t bscs_requ_dat(int sd, size_t start, size_t nblocks, HDRTYPE *hdr); /* request data blocks bufsiz is maximum number of bytes, typically it must be nblocks*hdr->AS.bpb -------------------------------------------------------------- */ int bscs_requ_evt(int sd, HDRTYPE *hdr); /* request event information -------------------------------------------------------------- */ int bscs_put_file(int sd, char *filename); /* put raw data file on server -------------------------------------------------------------- */ int bscs_get_file(int sd, uint64_t ID, char *filename); /* put raw data file on server -------------------------------------------------------------- */ int bscs_nop(int sd); /* no operation -------------------------------------------------------------- */ #ifdef __cplusplus } #endif /****************************************************************************/ /** **/ /** EOF **/ /** **/ /****************************************************************************/ #endif /* __BIOSIG_NETWORK_H__ */ stimfit-0.16.7/src/biosig/biosig4c++/physicalunits.h0000664000175000017500000000447014752215315015725 /* Copyright (C) 2005-2019 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /**************************************************************************** ** ** ** Conversion functions for encoded physical units according to ** ** ISO/IEEE 11073-10101:2004 Vital Signs Units of Measurement ** ** ** ****************************************************************************/ #ifndef __PHYSICALUNITS_H__ #define __PHYSICALUNITS_H__ #if defined(_MSC_VER) && (_MSC_VER < 1600) typedef unsigned __int64 uint16_t; #else #include #endif #pragma GCC visibility push(default) #ifdef __cplusplus extern "C" { #endif uint16_t PhysDimCode(const char* PhysDim); /* Encodes Physical Dimension as 16bit integer according to ISO/IEEE 11073-10101:2004 Vital Signs Units of Measurement Leading and trailing whitespace are skipped. --------------------------------------------------------------- */ const char* PhysDim3(uint16_t PhysDimCode); /* converts PhysDimCode into a readable Physical Dimension --------------------------------------------------------------- */ double PhysDimScale(uint16_t PhysDimCode); /* returns scaling factor of physical dimension e.g. 0.001 for milli, 1000 for kilo etc. for undefined codes, not-a-number (NAN) is returned --------------------------------------------------------------- */ #pragma GCC visibility pop #ifdef __cplusplus } #endif #endif /* __PHYSICALUNITS_H__ */ stimfit-0.16.7/src/biosig/biosig4c++/biosig.h0000664000175000017500000007103514752215315014303 /* Copyright (C) 2012-2018 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBBIOSIG2_H__ #define __LIBBIOSIG2_H__ #include "biosig-dev.h" #define BIOSIG_FLAG_COMPRESSION 0x0001 #define BIOSIG_FLAG_UCAL 0x0002 #define BIOSIG_FLAG_OVERFLOWDETECTION 0x0004 #define BIOSIG_FLAG_ROW_BASED_CHANNELS 0x0008 #pragma GCC visibility push(default) #ifdef __cplusplus extern "C" { #endif /****************************************************************************/ /** **/ /** EXPORTED FUNCTIONS : Level 1 **/ /** **/ /****************************************************************************/ uint32_t get_biosig_version (void); /* returns the version number in hex-decimal representation get_biosig_version() & 0x00ff0000 : major version number get_biosig_version() & 0x0000ff00 : minor version number get_biosig_version() & 0x000000ff : patch level --------------------------------------------------------------- */ HDRTYPE* constructHDR(const unsigned NS, const unsigned N_EVENT); /* allocates memory initializes header HDR of type HDRTYPE with NS channels an N_EVENT event elements --------------------------------------------------------------- */ void destructHDR(HDRTYPE* hdr); /* destroys the header *hdr and frees allocated memory --------------------------------------------------------------- */ HDRTYPE* sopen(const char* FileName, const char* MODE, HDRTYPE* hdr); /* FileName: name of file Mode: "r" is reading mode, requires FileName Mode: "w" is writing mode, hdr contains the header information If the number of records is not known, set hdr->NRec=-1 and sclose will fill in the correct number. Mode: "a" is append mode, if file exists, header and eventtable is read, position pointer is set to end of data in order to add more data. If file is successfully opened, the header structure of the existing file is used, and any different specification in hdr is discarded. If file is not compressed, it can be used for read and write, for compressed files, only appending at the end of file is possible. Currently, append mode is supported only for the GDF format. hdr should be generated with constructHDR, and the necessary fields must be defined. In read-mode, hdr can be NULL; however, hdr->FLAG... can be used to turn off spurious warnings. In write-mode, the whole header information must be defined. In append mode, it is recommended to provide whole header information, which must be equivalent to the header info of an existing file. After calling sopen, the file header is read or written, and the position pointer points to the beginning of the data section in append mode, the position pointer points to the end of the data section. --------------------------------------------------------------- */ int sclose(HDRTYPE* hdr); /* closes the file corresponding to hdr file handles are closed, the position pointer becomes meaningless Note: hdr is not destroyed; use destructHDR() to free the memory of hdr if hdr was opened in writing mode, the event table is added to the file and if hdr->NRec=-1, the number of records is obtained from the position pointer and written into the header, --------------------------------------------------------------- */ size_t sread(biosig_data_type* DATA, size_t START, size_t LEN, HDRTYPE* hdr); /* LEN data segments are read from file associated with hdr, starting from segment START. The data is copied into DATA; if DATA == NULL, a sufficient amount of memory is allocated, and the pointer to the data is available in hdr->data.block. In total, LEN*hdr->SPR*NS samples are read and stored in data type of biosig_data_type (currently double). NS is the number of channels with non-zero hdr->CHANNEL[].OnOff. The number of successfully read data blocks is returned. A pointer to the data block is also available from hdr->data.block, the number of columns and rows is available from hdr->data.size[0] and hdr->data.size[1] respectively. Channels k with (hdr->CHANNEL[k].SPR==0) are interpreted as sparsely sampled channels [for details see specification ofGDF v2 or larger]. The sample values are also returned in DATA the corresponding sampling time, the values in between the sparse sampling times are set to DigMin. (Applying the flags UCAL and OVERFLOWDETECTION will convert this into PhysMin and NaN, resp. see below). The following flags will influence the result. hdr->FLAG.UCAL = 0 scales the data to its physical values hdr->FLAG.UCAL = 1 does not apply the scaling factors hdr->FLAG.OVERFLOWDETECTION = 0 does not apply overflow detection hdr->FLAG.OVERFLOWDETECTION = 1: replaces all values that exceed the dynamic range (defined by Phys/Dig/Min/Max) hdr->FLAG.ROW_BASED_CHANNELS = 0 each channel is in one column hdr->FLAG.ROW_BASED_CHANNELS = 1 each channel is in one row --------------------------------------------------------------- */ #ifdef __GSL_MATRIX_DOUBLE_H__ size_t gsl_sread(gsl_matrix* DATA, size_t START, size_t LEN, HDRTYPE* hdr); /* same as sread but return data is of type gsl_matrix --------------------------------------------------------------- */ #endif size_t swrite(const biosig_data_type *DATA, size_t NELEM, HDRTYPE* hdr); /* DATA contains the next NELEM data segment(s) for writing. * hdr contains the definition of the header information and was generated by sopen * the number of successfully written segments is returned; --------------------------------------------------------------- */ int seof(HDRTYPE* hdr); /* returns 1 if end of file is reached. --------------------------------------------------------------- */ void srewind(HDRTYPE* hdr); /* postions file pointer to the beginning * * Currently, this function is meaning less because sread requires always the start value --------------------------------------------------------------- */ int sseek(HDRTYPE* hdr, ssize_t offset, int whence); /* positions file pointer * * Currently, this function is meaning less because sread requires always the start value --------------------------------------------------------------- */ ssize_t stell(HDRTYPE* hdr); /* returns position of file point in segments --------------------------------------------------------------- */ #ifndef ONLYGDF ATT_DEPREC int serror(void); /* handles errors; it reports whether an error has occured. * if yes, an error message is displayed, and the error status is reset. * the return value is 0 if no error has occured, otherwise the error code * is returned. * IMPORTANT NOTE: * serror() uses the global error variables B4C_ERRNUM and B4C_ERRMSG, * which is not re-entrant, because two opened files share the same * error variables. --------------------------------------------------------------- */ #endif //ONLYGDF int serror2(HDRTYPE* hdr); /* handles errors; it reports whether an error has occured. * if yes, an error message is displayed, and the error status is reset. * the return value is 0 if no error has occured, otherwise the error code * is returned. --------------------------------------------------------------- */ int biosig_check_error(HDRTYPE *hdr); /* returns error status but does not handle/reset it. * it can be used for checking whether some error status has been set --------------------------------------------------------------- */ char* biosig_get_errormsg(HDRTYPE *hdr); /* returns error message but does not reset it. * memory for the error message is allocated and need to be freed * by the calling application --------------------------------------------------------------- */ int sflush_gdf_event_table(HDRTYPE* hdr); /* writes the event table of file hdr. hdr must define a file in GDF format * and can be opened as read or write. * In case of success, the return value is 0. --------------------------------------------------------------- */ int cachingWholeFile(HDRTYPE* hdr); /* caching: load data of whole file into buffer * this will speed up data access, especially in interactive mode --------------------------------------------------------------- */ int RerefCHANNEL(HDRTYPE *hdr, void *ReRef, char rrtype); /* rerefCHAN defines rereferencing of channels, hdr->Calib defines the rereferencing matrix hdr->rerefCHANNEL is defined. hdr->rerefCHANNEL[.].Label is by some heuristics from hdr->CHANNEL either the maximum scaling factor if ReRef is NULL, rereferencing is turned off (hdr->Calib and hdr->rerefCHANNEL are reset to NULL). if rrtype==1, Reref is a filename pointing to a MatrixMarket file if rrtype==2, Reref must be a pointer to a cholmod sparse matrix (cholmod_sparse*) In case of an error (mismatch of dimensions), a non-zero is returned, and serror() is set. rr is a pointer to a rereferencing matrix rrtype determines the type of pointer rrtype=0: no rereferencing, RR is ignored (NULL) 1: pointer to MarketMatrix file (char*) 2: pointer to a sparse cholmod matrix (cholmod_sparse*) ------------------------------------------------------------------------*/ /* ============================================================= utility functions for handling of event table ============================================================= */ void sort_eventtable(HDRTYPE *hdr); /* sort event table with respect to hdr->EVENT.POS --------------------------------------------------------------*/ size_t reallocEventTable(HDRTYPE *hdr, size_t EventN); /*------------------------------------------------------------------------ re-allocates memory for Eventtable. hdr->EVENT.N contains actual number of events EventN determines the size of the allocated memory return value: in case of success, EVENT_N is returned in case of failure SIZE_MAX is returned; ------------------------------------------------------------------------*/ void convert2to4_eventtable(HDRTYPE *hdr); /* converts event table from {TYP,POS} to [TYP,POS,CHN,DUR} format -------------------------------------------------------------- */ void convert4to2_eventtable(HDRTYPE *hdr); /* converts event table from [TYP,POS,CHN,DUR} to {TYP,POS} format all CHN[k] must be 0 -------------------------------------------------------------- */ const char* GetEventDescription(HDRTYPE *hdr, size_t n); /* returns clear text description of n-th event, considers also user-defined events. -------------------------------------------------------------- */ void FreeTextEvent(HDRTYPE* hdr, size_t N, const char* annotation); /* adds free text annotation to event table for the N-th event. the EVENT.TYP[N] is identified from the table EVENT.CodeDesc if annotations is not listed in CodeDesc, it is added to CodeDesc The table is limited to 256 entries, because the table EventCodes allows only codes 0-255 as user specific entry. If the description table contains more than 255 entries, an error is set. ------------------------------------------------------------------------*/ /* ============================================================= utility functions for handling of physical dimensons ============================================================= */ #ifndef __PHYSICALUNITS_H__ uint16_t PhysDimCode(const char* PhysDim); /* Encodes Physical Dimension as 16bit integer according to ISO/IEEE 11073-10101:2004 Vital Signs Units of Measurement --------------------------------------------------------------- */ char* PhysDim(uint16_t PhysDimCode, char *PhysDimText); /* DEPRECATED: USE INSTEAD PhysDim3(uint16_t PhysDimCode) It's included just for backwards compatibility converts HDR.CHANNEL[k].PhysDimCode into a readable Physical Dimension the memory for PhysDim must be preallocated, its maximum length is defined by (MAX_LENGTH_PHYSDIM+1) --------------------------------------------------------------- */ const char* PhysDim3(uint16_t PhysDimCode); /* converts PhysDimCode into a readable Physical Dimension --------------------------------------------------------------- */ double PhysDimScale(uint16_t PhysDimCode); /* returns scaling factor of physical dimension e.g. 0.001 for milli, 1000 for kilo etc. --------------------------------------------------------------- */ #endif int biosig_set_hdr_ipaddr(HDRTYPE *hdr, const char *hostname); /* set the field HDR.IPaddr based on the IP address of hostname Return value: 0: hdr->IPaddr is set otherwise hdr->IPaddr is not set ---------------------------------------------------------------*/ /* ============================================================= printing of header information ============================================================= */ int hdr2ascii(HDRTYPE* hdr, FILE *fid, int VERBOSITY); /* writes the header information is ascii format the stream defined by fid * Typically fid is stdout. VERBOSITY defines how detailed the information is. * VERBOSITY=0 or 1 report just some basic information, * VERBOSITY=2 reports als the channel information * VERBOSITY=3 provides in addition the event table. * VERBOSITY=8 for debugging * VERBOSITY=9 for debugging * VERBOSITY=-1 header and event table is shown in JSON format --------------------------------------------------------------- */ ATT_DEPREC int hdr2json (HDRTYPE *hdr, FILE *fid); int fprintf_hdr2json(FILE *stream, HDRTYPE* hdr); /* prints header in json format into stream; hdr2json is the old form and deprecated, use fprintf_hdr2json instead --------------------------------------------------------------- */ int asprintf_hdr2json(char **str, HDRTYPE* hdr); /* prints header in json format into *str; memory for str is automatically allocated and must be freed after usage. --------------------------------------------------------------- */ HDRTYPE* constructHDR(const unsigned NS, const unsigned N_EVENT); /* allocates memory initializes header HDR of type HDRTYPE with NS channels an N_EVENT event elements --------------------------------------------------------------- */ void destructHDR(HDRTYPE* hdr); /* destroys the header *hdr and frees allocated memory --------------------------------------------------------------- */ /****************************************************************************/ /** **/ /** EXPORTED FUNCTIONS : Level 2 **/ /** **/ /****************************************************************************/ /* ============================================================= setter and getter functions for accessing fields of HDRTYPE these functions are currently experimential and are likely to change ============================================================= */ /* get, set and check function of filetype */ enum FileFormat biosig_get_filetype(HDRTYPE *hdr); int biosig_set_filetype(HDRTYPE *hdr, enum FileFormat format); #define biosig_check_filetype(a,b) (biosig_get_filetype(a)==b) ATT_DEPREC int biosig_set_flags(HDRTYPE *hdr, char compression, char ucal, char overflowdetection); int biosig_get_flag(HDRTYPE *hdr, unsigned flags); int biosig_set_flag(HDRTYPE *hdr, unsigned flags); int biosig_reset_flag(HDRTYPE *hdr, unsigned flags); int biosig_set_targetsegment(HDRTYPE *hdr, unsigned targetsegment); int biosig_get_targetsegment(HDRTYPE *hdr); const char* biosig_get_filename(HDRTYPE *hdr); float biosig_get_version(HDRTYPE *hdr); int biosig_set_segment_selection(HDRTYPE *hdr, int k, uint32_t argSweepSel); uint32_t* biosig_get_segment_selection(HDRTYPE *hdr); // returns error message in memory allocated with strdup int biosig_check_error(HDRTYPE *hdr); char *biosig_get_errormsg(HDRTYPE *hdr); long biosig_get_number_of_channels(HDRTYPE *hdr); size_t biosig_get_number_of_samples(HDRTYPE *hdr); ATT_DEPREC size_t biosig_get_number_of_samples_per_record(HDRTYPE *hdr); size_t biosig_get_number_of_records(HDRTYPE *hdr); size_t biosig_get_number_of_segments(HDRTYPE *hdr); int biosig_set_number_of_channels(HDRTYPE *hdr, int ns); int biosig_set_number_of_samples(HDRTYPE *hdr, ssize_t nrec, ssize_t spr); #define biosig_set_number_of_samples_per_record(h,n) biosig_set_number_of_samples(h,-1,n) #define biosig_set_number_of_records(h,n) biosig_set_number_of_samples(h,n,-1) // ATT_DEPREC int biosig_set_number_of_segments(HDRTYPE *hdr, ); int biosig_get_datablock(HDRTYPE *hdr, biosig_data_type **data, size_t *rows, size_t *columns); biosig_data_type* biosig_get_data(HDRTYPE *hdr, char flag); double biosig_get_samplerate(HDRTYPE *hdr); int biosig_set_samplerate(HDRTYPE *hdr, double fs); size_t biosig_get_number_of_events(HDRTYPE *hdr); size_t biosig_set_number_of_events(HDRTYPE *hdr, size_t N); // get n-th event, variables pointing to NULL are ignored int biosig_get_nth_event(HDRTYPE *hdr, size_t n, uint16_t *typ, uint32_t *pos, uint16_t *chn, uint32_t *dur, gdf_time *timestamp, const char **desc); /* set n-th event, variables pointing to NULL are ignored typ or Desc can be used to determine the type of the event. if both, typ and Desc, are not NULL, the result is undefined */ int biosig_set_nth_event(HDRTYPE *hdr, size_t n, uint16_t* typ, uint32_t *pos, uint16_t *chn, uint32_t *dur, gdf_time *timestamp, char *Desc); double biosig_get_eventtable_samplerate(HDRTYPE *hdr); int biosig_set_eventtable_samplerate(HDRTYPE *hdr, double fs); int biosig_change_eventtable_samplerate(HDRTYPE *hdr, double fs); int biosig_get_startdatetime(HDRTYPE *hdr, struct tm *T); int biosig_set_startdatetime(HDRTYPE *hdr, struct tm T); gdf_time biosig_get_startdatetime_gdf(HDRTYPE *hdr); int biosig_set_startdatetime_gdf(HDRTYPE *hdr, gdf_time T); int biosig_get_birthdate(HDRTYPE *hdr, struct tm *T); int biosig_set_birthdate(HDRTYPE *hdr, struct tm T); const char* biosig_get_patient_name(HDRTYPE *hdr); const char* biosig_get_patient_id(HDRTYPE *hdr); const char* biosig_get_recording_id(HDRTYPE *hdr); const char* biosig_get_technician(HDRTYPE *hdr); const char* biosig_get_manufacturer_name(HDRTYPE *hdr); const char* biosig_get_manufacturer_model(HDRTYPE *hdr); const char* biosig_get_manufacturer_version(HDRTYPE *hdr); const char* biosig_get_manufacturer_serial_number(HDRTYPE *hdr); const char* biosig_get_application_specific_information(HDRTYPE *hdr); int biosig_set_patient_name(HDRTYPE *hdr, const char* rid); int biosig_set_patient_name_structured(HDRTYPE *hdr, const char* LastName, const char* FirstName, const char* SecondLastName); int biosig_set_patient_id(HDRTYPE *hdr, const char* rid); int biosig_set_recording_id(HDRTYPE *hdr, const char* rid); int biosig_set_technician(HDRTYPE *hdr, const char* rid); int biosig_set_manufacturer_name(HDRTYPE *hdr, const char* rid); int biosig_set_manufacturer_model(HDRTYPE *hdr, const char* rid); int biosig_set_manufacturer_version(HDRTYPE *hdr, const char* rid); int biosig_set_manufacturer_serial_number(HDRTYPE *hdr, const char* rid); int biosig_set_application_specific_information(HDRTYPE *hdr, const char* appinfo); double biosig_get_channel_samplerate(HDRTYPE *hdr, int chan); int biosig_set_channel_samplerate_and_samples_per_record(HDRTYPE *hdr, int chan, ssize_t spr, double fs); /* ============================================================= setter and getter functions for accessing fields of CHANNEL_TYPE these functions are currently experimential and are likely to change ============================================================= */ // returns M-th channel, M is zero-based CHANNEL_TYPE* biosig_get_channel(HDRTYPE *hdr, int M); const char* biosig_channel_get_label(CHANNEL_TYPE *chan); int biosig_channel_set_label(CHANNEL_TYPE *chan, const char* label); uint16_t biosig_channel_get_physdimcode(CHANNEL_TYPE *chan); const char* biosig_channel_get_physdim(CHANNEL_TYPE *chan); #define biosig_channel_get_unit(h) biosig_channel_get_physdim(h) int biosig_channel_set_physdimcode(CHANNEL_TYPE *chan, uint16_t physdimcode); #define biosig_channel_set_physdim(a,b) biosig_channel_set_physdimcode(a, PhysDimCode(b)) #define biosig_channel_set_unit(a,b) biosig_channel_set_physdimcode(a, PhysDimCode(b)) // this will affect result of next SREAD when flag.ucal==0 int biosig_channel_change_scale_to_physdimcode(CHANNEL_TYPE *chan, uint16_t physdimcode); #define biosig_channel_change_scale_to_unitcode(a,b) biosig_channel_set_scale_to_physdimcode(a, b) #define biosig_channel_change_scale_to_physdim(a,b) biosig_channel_set_scale_to_physdimcode(a, PhysDimCode(b)) #define biosig_channel_change_scale_to_unit(a,b) biosig_channel_set_scale_to_physdimcode(a, PhysDimCode(b)) int biosig_channel_get_scaling(CHANNEL_TYPE *chan, double *PhysMax, double *PhysMin, double *DigMax, double *DigMin); int biosig_channel_set_scaling(CHANNEL_TYPE *chan, double PhysMax, double PhysMin, double DigMax, double DigMin); double biosig_channel_get_cal(CHANNEL_TYPE *chan); double biosig_channel_get_off(CHANNEL_TYPE *chan); ATT_DEPREC int biosig_channel_set_cal(CHANNEL_TYPE *chan, double cal); ATT_DEPREC int biosig_channel_set_off(CHANNEL_TYPE *chan, double off); int biosig_channel_get_filter(CHANNEL_TYPE *chan, double *LowPass, double *HighPass, double *Notch); int biosig_channel_set_filter(CHANNEL_TYPE *chan, double LowPass, double HighPass, double Notch); double biosig_channel_get_timing_offset(CHANNEL_TYPE *hc); int biosig_channel_set_timing_offset(CHANNEL_TYPE *hc, double off); double biosig_channel_get_impedance(CHANNEL_TYPE *hc); int biosig_channel_set_impedance(CHANNEL_TYPE *hc, double val); /* double biosig_channel_get_samplerate(CHANNEL_TYPE *hc); int biosig_channel_set_samplerate_and_samples_per_record(CHANNEL_TYPE *hc, size_t spr, double val); */ size_t biosig_channel_get_samples_per_record(CHANNEL_TYPE *hc); int biosig_channel_set_samples_per_record(CHANNEL_TYPE *hc, size_t spr); uint16_t biosig_channel_get_datatype(CHANNEL_TYPE *hc); int biosig_channel_set_datatype(CHANNEL_TYPE *hc, uint16_t gdftyp); #define biosig_channel_set_datatype_to_int8(h) biosig_channel_set_datatype(h,1) #define biosig_channel_set_datatype_to_uint8(h) biosig_channel_set_datatype(h,2) #define biosig_channel_set_datatype_to_int16(h) biosig_channel_set_datatype(h,3) #define biosig_channel_set_datatype_to_uint16(h) biosig_channel_set_datatype(h,4) #define biosig_channel_set_datatype_to_int32(h) biosig_channel_set_datatype(h,5) #define biosig_channel_set_datatype_to_uint32(h) biosig_channel_set_datatype(h,6) #define biosig_channel_set_datatype_to_int64(h) biosig_channel_set_datatype(h,7) #define biosig_channel_set_datatype_to_uint64(h) biosig_channel_set_datatype(h,8) #define biosig_channel_set_datatype_to_float(h) biosig_channel_set_datatype(h,16) #define biosig_channel_set_datatype_to_single(h) biosig_channel_set_datatype(h,16) #define biosig_channel_set_datatype_to_double(h) biosig_channel_set_datatype(h,17) const char *biosig_channel_get_transducer(CHANNEL_TYPE *hc); int biosig_channel_set_transducer(CHANNEL_TYPE *hc, const char *transducer); #pragma GCC visibility pop typedef HDRTYPE *biosig_handle_t ; #if defined(MAKE_EDFLIB) // definitions according to edflib v1.09 #define edflib_version() (109) #define EDFLIB_MAX_ANNOTATION_LEN 512 #define EDFLIB_FILETYPE_EDF 0 #define EDFLIB_FILETYPE_EDFPLUS 1 #define EDFLIB_FILETYPE_BDF 2 #define EDFLIB_FILETYPE_BDFPLUS 3 #define EDFLIB_MALLOC_ERROR -1 #define EDFLIB_NO_SUCH_FILE_OR_DIRECTORY -2 #define EDFLIB_FILE_CONTAINS_FORMAT_ERRORS -3 #define EDFLIB_MAXFILES_REACHED -4 #define EDFLIB_FILE_READ_ERROR -5 #define EDFLIB_FILE_ALREADY_OPENED -6 #define EDFLIB_FILETYPE_ERROR -7 #define EDFLIB_FILE_WRITE_ERROR -8 #define EDFLIB_NUMBER_OF_SIGNALS_INVALID -9 #define EDFLIB_FILE_IS_DISCONTINUOUS -10 #define EDFLIB_INVALID_READ_ANNOTS_VALUE -11 /* values for annotations */ #define EDFLIB_DO_NOT_READ_ANNOTATIONS 0 #define EDFLIB_READ_ANNOTATIONS 1 #define EDFLIB_READ_ALL_ANNOTATIONS 2 /* the following defines are possible errors returned by edfopen_file_writeonly() */ #define EDFLIB_NO_SIGNALS -20 #define EDFLIB_TOO_MANY_SIGNALS -21 #define EDFLIB_NO_SAMPLES_IN_RECORD -22 #define EDFLIB_DIGMIN_IS_DIGMAX -23 #define EDFLIB_DIGMAX_LOWER_THAN_DIGMIN -24 #define EDFLIB_PHYSMIN_IS_PHYSMAX -25 #define EDFLIB_TIME_DIMENSION (10000000LL) #define EDFLIB_MAXSIGNALS 256 #define EDFLIB_MAX_ANNOTATION_LEN 512 #define EDFSEEK_SET 0 #define EDFSEEK_CUR 1 #define EDFSEEK_END 2 struct edf_annotation_struct { /* this structure is used for annotations */ size_t onset; /* onset time of the event, expressed in units of 100 nanoSeconds and relative to the starttime in the header */ size_t duration; /* duration time, this is a null-terminated ASCII text-string */ char annotation[EDFLIB_MAX_ANNOTATION_LEN + 1]; /* description of the event in UTF-8, this is a null terminated string */ }; int edfopen_file_writeonly(const char *path, int filetype, int number_of_signals); #define edfopen_file_readonly(a,c) biosig_open_file_readonly(a,c) #define edfclose_file(handle) biosig_close_file(handle) int edfread_physical_samples(int handle, int edfsignal, int n, double *buf); int edfread_digital_samples(int handle, int edfsignal, int n, int *buf); long long edfseek(int handle, int biosig_signal, long long offset, int whence); long long edftell(int handle, int biosig_signal); int edfrewind(int handle, int edfsignal); //#define edf_get_annotation(a,b,c) biosig_get_annotation(a,b,c) int edf_get_annotation(int handle, int n, struct edf_annotation_struct *annot); //#define edfopen_file_writeonly(a,b,c) biosig_open_file_writeonly(a,b,c) int biosig_open_file_writeonly(const char *path, enum FileFormat filetype, int number_of_signals); #define edf_set_samplefrequency(a,b,c) biosig_set_samplefrequency(a,b,c) #define edf_set_physical_maximum(a,b,c) biosig_set_physical_maximum(a,b,c) #define edf_set_physical_minimum(a,b,c) biosig_set_physical_minimum(a,b,c) #define edf_set_digital_maximum(a,b,c) biosig_set_digital_maximum(a,b,(double)(c)) #define edf_set_digital_minimum(a,b,c) biosig_set_digital_minimum(a,b,(double)(c)) #define edf_set_label(a,b,c) biosig_set_label(a,b,c) #define edf_set_prefilter(a,b,c) biosig_set_prefilter(a,b,c) #define edf_set_transducer(a,b,c) biosig_set_transducer(a,b,c) #define edf_set_physical_dimension(a,b,c) biosig_set_physical_dimension(a,b,c) int edf_set_startdatetime(int handle, int startdate_year, int startdate_month, int startdate_day, int starttime_hour, int starttime_minute, int starttime_second); #define edf_set_patientname(a,b) biosig_set_patientname(a,b) #define edf_set_patientcode(a,b) biosig_set_patientcode(a,b) //#define edf_set_gender(a,b) biosig_set_gender(a,b) int edf_set_gender(int handle, int gender); int edf_set_birthdate(int handle, int birthdate_year, int birthdate_month, int birthdate_day); #define edf_set_patient_additional(a,b) biosig_set_patient_additional(a,b) #define edf_set_admincode(a,b) biosig_set_admincode(a,b) #define edf_set_technician(a,b) biosig_set_technician(a,b) #define edf_set_equipment(a,b) biosig_set_equipment(a,b) int edf_set_recording_additional(int handle, const char *recording_additional); int edfwrite_physical_samples(int handle, double *buf); int edf_blockwrite_physical_samples(int handle, double *buf); int edfwrite_digital_samples(int handle, int *buf); int edf_blockwrite_digital_samples(int handle, int *buf); #define edfwrite_annotation_utf8(a,b,c,d) biosig_write_annotation_utf8(a,b,c,d) #define edfwrite_annotation_latin1(a,b,c,d) biosig_write_annotation_latin1(a,b,c,d) #define edf_set_datarecord_duration(a,b) biosig_set_datarecord_duration(a,b) #endif #ifdef __cplusplus } /* extern "C" */ #endif #endif stimfit-0.16.7/src/biosig/biosig4c++/t220/0000775000175000017500000000000014764352501013421 5stimfit-0.16.7/src/biosig/biosig4c++/t220/crc4scp.c0000664000175000017500000000667414752215315015061 /* --------------------------------------------------------------------------- Copyright (C) 2005-2006 Franco Chiarugi Developed at the Foundation for Research and Technology - Hellas, Heraklion, Crete Copyright (C) 2009 Alois Schloegl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id$ --------------------------------------------------------------------------- */ #if defined(_MSC_VER) && (_MSC_VER < 1600) typedef unsigned __int64 uint64_t; typedef __int64 int64_t; typedef unsigned __int32 uint32_t; typedef __int32 int32_t; typedef unsigned __int16 uint16_t; typedef __int16 int16_t; typedef unsigned __int8 uint8_t; typedef __int8 int8_t; #else #include #endif #ifdef __cplusplus extern "C" { #endif /******************************************************************** * CRCEvaluate * * * * Parameters: datablock is the buffer on which to evaluate the CRC. * * datalength is the length of the whole buffer * * * * Description: Evaluate the SCP-ECG CRC on a data block * * (all file or a section) * * * ********************************************************************/ uint16_t CRCEvaluate(uint8_t* datablock, uint32_t datalength) { uint32_t i; uint16_t crc_tot; uint8_t crchi, crclo; uint8_t a, b; uint8_t tmp1, tmp2; crchi = 0xFF; crclo = 0xFF; for (i = 0; i < datalength; i++) { a = datablock[i]; a ^= crchi; crchi = a; a >>= 4; a &= 0x0F; a ^= crchi; crchi = crclo; crclo = a; tmp1 = ((a & 0x0F) << 4) & 0xF0; tmp2 = ((a & 0xF0) >> 4) & 0x0F; a = tmp1 | tmp2; b = a; tmp1 = ((a & 0x7F) << 1) & 0xFE; tmp2 = ((a & 0x80) >> 7) & 0x01; a = tmp1 | tmp2; a &= 0x1F; crchi ^= a; a = b & 0xF0; crchi ^= a; tmp1 = ((b & 0x7F) << 1) & 0xFE; tmp2 = ((b & 0x80) >> 7) & 0x01; b = tmp1 | tmp2; b &= 0xE0; crclo ^= b; } crc_tot = ((0x00FF & (uint16_t) crchi) << 8) & 0xFF00; crc_tot |= (0x00FF & (uint16_t) crclo); return (crc_tot); } /******************************************************************** * CRCCheck * * * * Parameters: datablock is the buffer on which to verify the CRC. * * It starts with the two CRC-CCITT bytes. * * datalength is the length of the whole buffer * * (including the two CRC bytes) * * * * Description: Check the SCP-ECG CRC on a data block * * (all file or a section) * * * ********************************************************************/ int16_t CRCCheck(uint8_t* datablock, uint32_t datalength) { uint16_t crc; crc = 0; if (datalength <= 2) return (-1); // Evaluate CRC crc = CRCEvaluate((uint8_t*) (datablock + 2), (uint32_t) (datalength - 2)); if (((uint8_t) ((crc & 0xFF00) >> 8) != (uint8_t) datablock[1]) || ((uint8_t) (crc & 0x00FF) != (uint8_t) datablock[0])) return (0); else return (1); } #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/t220/sopen_scp_write.c0000664000175000017500000007047014752215315016716 /* Copyright (C) 2005-2018 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. */ #include #include #include #include #include "../biosig-dev.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) #ifdef __cplusplus extern "C" { #endif int sopen_SCP_write(HDRTYPE* hdr) { /* This function is an auxillary function and is only called by the function SOPEN in "biosig.c" Input: HDRTYPE *hdr // defines the HDR structure according to "biosig.h" hdr->VERSION specifies the target version */ uint8_t* ptr; // pointer to memory mapping of the file layout uint8_t* PtrCurSect; // point to current section int curSect; uint32_t len; uint16_t crc; uint32_t i; uint32_t sectionStart; struct tm* T0_tm; double AVM, avm; uint16_t avm16; struct aecg* aECG; assert(hdr != NULL); assert(hdr->TYPE == SCP_ECG); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) : V%f\n",__FILE__,__LINE__,hdr->VERSION); if ((fabs(hdr->VERSION - 1.3)<0.01) && (fabs(hdr->VERSION-2.0)<0.01) && (fabs(hdr->VERSION-3.0)<0.01)) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Version %f not supported\n",hdr->VERSION); uint8_t versionSection = (hdr->VERSION < 3.0) ? 20 : 29; // (uint8_t)round(hdr->VERSION*10); // implemented version number uint8_t versionProtocol = versionSection; if (hdr->aECG==NULL) { fprintf(stderr,"Warning SOPEN_SCP_WRITE: No aECG info defined\n"); hdr->aECG = malloc(sizeof(struct aecg)); aECG = (struct aecg*)hdr->aECG; aECG->diastolicBloodPressure=0.0; aECG->systolicBloodPressure=0.0; aECG->MedicationDrugs="/0"; aECG->ReferringPhysician="/0"; aECG->LatestConfirmingPhysician="/0"; aECG->Diagnosis="/0"; aECG->EmergencyLevel=0; #if (BIOSIG_VERSION > 10500) aECG->Section8.NumberOfStatements = 0; aECG->Section8.Statements = NULL; aECG->Section11.NumberOfStatements = 0; aECG->Section11.Statements = NULL; #endif } else aECG = (struct aecg*)hdr->aECG; //fprintf(stdout,"SCP-Write: IIb %s\n",hdr->aECG->ReferringPhysician); /* predefined values */ aECG->Section1.Tag14.INST_NUMBER = 0; // tag 14, byte 1-2 aECG->Section1.Tag14.DEPT_NUMBER = 0; // tag 14, byte 3-4 aECG->Section1.Tag14.DEVICE_ID = 0; // tag 14, byte 5-6 aECG->Section1.Tag14.DeviceType = 0; // tag 14, byte 7: 0: Cart, 1: System (or Host) aECG->Section1.Tag14.MANUF_CODE = 255; // tag 14, byte 8 (MANUF_CODE has to be 255) aECG->Section1.Tag14.MOD_DESC = "Cart1"; // tag 14, byte 9 (MOD_DESC has to be "Cart1") aECG->Section1.Tag14.VERSION = versionSection; // tag 14, byte 15 (VERSION * 10) aECG->Section1.Tag14.PROT_COMP_LEVEL = 0xA0; // tag 14, byte 16 (PROT_COMP_LEVEL has to be 0xA0 => level II) // tag 14, byte 17 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code, 0x37: UTF-8) aECG->Section1.Tag14.LANG_SUPP_CODE = (versionSection < 25) ? 0x00 : 0x37; aECG->Section1.Tag14.ECG_CAP_DEV = 0xD0; // tag 14, byte 18 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) aECG->Section1.Tag14.MAINS_FREQ = 0; // tag 14, byte 19 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) aECG->Section1.Tag14.ANAL_PROG_REV_NUM = ""; aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV = ""; aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID = ""; aECG->Section1.Tag14.ACQ_DEV_SCP_SW = "OpenECG XML-SCP 1.00"; // tag 14, byte 38 (SCP_IMPL_SW has to be "OpenECG XML-SCP 1.00") aECG->Section1.Tag14.ACQ_DEV_MANUF = "Manufacturer"; // tag 14, byte 38 (ACQ_DEV_MANUF has to be "Manufacturer") aECG->Section5.Length = 0; aECG->Section6.Length = 0; aECG->Section7.Length = 0; /* */ aECG->FLAG.HUFFMAN = 0; aECG->FLAG.REF_BEAT= 0; aECG->FLAG.DIFF = 0; aECG->FLAG.BIMODAL = 0; /* check channels: disable channels that do not have a known ECG LeadId disable channels with physical units other than Voltage. The number of channels for conversion is stored in NS. */ typeof(hdr->NS) NS = 0, k; for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE *CH=hdr->CHANNEL+k; if ( CH->LeadIdCode > 255) CH->OnOff = 0; if ( (CH->PhysDimCode & 0xffe0) != PhysDimCode("V")) CH->OnOff = 0; if (CH->OnOff != 1) continue; NS++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) : v%f VERSION=%i\n",__FILE__,__LINE__, hdr->VERSION, versionSection); ptr = (uint8_t*)hdr->AS.Header; int NSections = (versionSection < 25) ? 12 : 19; // initialize section 0 sectionStart = 6+16+NSections*10; ptr = (uint8_t*)realloc(ptr,sectionStart); memset(ptr,0,sectionStart); uint32_t curSectLen; // current section length for (curSect=NSections-1; curSect>=0; curSect--) { curSectLen = 0; // current section length //ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) : Section %i/%i %i %p\n",__FILE__,__LINE__,curSect,NSections,sectionStart,ptr); if (curSect==0) // SECTION 0 { hdr->HeadLen = sectionStart; // length of all other blocks together ptr = (uint8_t*)realloc(ptr,hdr->HeadLen); // total file length curSectLen = 16; // current section length sectionStart = 6; curSectLen += NSections*10; } else if (curSect==1) // SECTION 1 { ptr = (uint8_t*)realloc(ptr,sectionStart+10000); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length char *nextPartOfPatientName=hdr->Patient.Name; if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 0 \n"); // Tag 0 (max len = 64) if (!hdr->FLAG.ANONYMOUS && (nextPartOfPatientName != NULL) && strlen(nextPartOfPatientName)) { *(ptr+sectionStart+curSectLen) = 0; // tag len = strcspn(nextPartOfPatientName, "\x1f"); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)ptr+sectionStart+curSectLen+3,nextPartOfPatientName,len); // field nextPartOfPatientName += len+1; curSectLen += len+3; } if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 1 \n"); // Tag 1 (max len = 64) Firstname if (!hdr->FLAG.ANONYMOUS && (nextPartOfPatientName != NULL) && strlen(nextPartOfPatientName)) { *(ptr+sectionStart+curSectLen) = 1; // tag len = strcspn(nextPartOfPatientName, "\x1f"); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)ptr+sectionStart+curSectLen+3,nextPartOfPatientName,len); // field nextPartOfPatientName += len+1; curSectLen += len+3; } // Tag 2 (max len = 64) Patient ID if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 2 \n"); // if (hdr->Patient.Id != NULL) { if (strlen(hdr->Patient.Id)>0) { *(ptr+sectionStart+curSectLen) = 2; // tag len = strlen(hdr->Patient.Id) + 1; leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)ptr+sectionStart+curSectLen+3,hdr->Patient.Id,len); // field curSectLen += len+3; } // Tag 3 (max len = 64) Second Last Name if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 3 \n"); if (!hdr->FLAG.ANONYMOUS && (nextPartOfPatientName != NULL) && strlen(nextPartOfPatientName)) { *(ptr+sectionStart+curSectLen) = 3; // tag len = strcspn(nextPartOfPatientName, "\x1f"); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)ptr+sectionStart+curSectLen+3,nextPartOfPatientName,len); // field nextPartOfPatientName += len+1; curSectLen += len+3; } // Tag 5 (len = 4) if ((hdr->Patient.Birthday) > 0) { T0_tm = gdf_time2tm_time(hdr->Patient.Birthday); *(ptr+sectionStart+curSectLen) = 5; // tag leu16a(4, ptr+sectionStart+curSectLen+1); // length leu16a(T0_tm->tm_year+1900, ptr+sectionStart+curSectLen+3);// year *(ptr+sectionStart+curSectLen+5) = (uint8_t)(T0_tm->tm_mon + 1); // month *(ptr+sectionStart+curSectLen+6) = (uint8_t)(T0_tm->tm_mday); // day curSectLen += 7; } // Tag 6 (len = 3) Height if (hdr->Patient.Height>0.0) { *(ptr+sectionStart+curSectLen) = 6; // tag leu16a(3, ptr+sectionStart+curSectLen+1); // length leu16a(hdr->Patient.Height, ptr+sectionStart+curSectLen+3); // value *(ptr+sectionStart+curSectLen+5) = 1; // cm curSectLen += 6; } // Tag 7 (len = 3) Weight if (hdr->Patient.Weight>0.0) { *(ptr+sectionStart+curSectLen) = 7; // tag leu16a(3, ptr+sectionStart+curSectLen+1); // length leu16a(hdr->Patient.Weight, ptr+sectionStart+curSectLen+3); // value *(ptr+sectionStart+curSectLen+5) = 1; // kg curSectLen += 6; } // Tag 8 (len = 1) if (hdr->Patient.Sex != 0) { *(ptr+sectionStart+curSectLen) = 8; // tag leu16a(1, ptr+sectionStart+curSectLen+1); // length *(ptr+sectionStart+curSectLen+3) = hdr->Patient.Sex; // value curSectLen += 4; } // Tag 11 (len = 2) if (aECG->systolicBloodPressure>0.0) { *(ptr+sectionStart+curSectLen) = 11; // tag leu16a(2, ptr+sectionStart+curSectLen+1); // length leu16a((uint16_t)aECG->systolicBloodPressure, ptr+sectionStart+curSectLen+3); // value curSectLen += 5; }; // Tag 12 (len = 2) if (aECG->diastolicBloodPressure>0.0) { *(ptr+sectionStart+curSectLen) = 12; // tag leu16a(2, ptr+sectionStart+curSectLen+1); // length leu16a((uint16_t)aECG->diastolicBloodPressure, ptr+sectionStart+curSectLen+3); // value curSectLen += 5; }; // Tag 13 (max len = 80) aECG->Diagnosis=""; len = strlen(aECG->Diagnosis); if (len>0) { *(ptr+sectionStart+curSectLen) = 13; // tag len = min(64,len+1); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->Diagnosis,len); curSectLen += 3+len; }; // Tag 14 (max len = 2 + 2 + 2 + 1 + 1 + 6 + 1 + 1 + 1 + 1 + 1 + 16 + 1 + 25 + 25 + 25 + 25 + 25) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 14 \n"); // Total = 161 (max value) *(ptr+sectionStart+curSectLen) = 14; // tag //len = 41; // minimum length // leu16a(len, ptr+sectionStart+curSectLen+1); // length memset(ptr+sectionStart+curSectLen+3,0,41); // dummy value curSectLen += 3; leu16a(aECG->Section1.Tag14.INST_NUMBER, ptr+sectionStart+curSectLen); leu16a(aECG->Section1.Tag14.DEPT_NUMBER, ptr+sectionStart+curSectLen+2); leu16a(aECG->Section1.Tag14.DEVICE_ID, ptr+sectionStart+curSectLen+4); *(ptr+sectionStart+curSectLen+ 6) = aECG->Section1.Tag14.DeviceType; *(ptr+sectionStart+curSectLen+ 7) = aECG->Section1.Tag14.MANUF_CODE; // tag 14, byte 7 (MANUF_CODE has to be 255) strncpy((char*)(ptr+sectionStart+curSectLen+8), aECG->Section1.Tag14.MOD_DESC, 6); // tag 14, byte 7 (MOD_DESC has to be "Cart1") *(ptr+sectionStart+curSectLen+14) = versionSection; // tag 14, byte 14 (VERSION has to be 20) *(ptr+sectionStart+curSectLen+14) = aECG->Section1.Tag14.VERSION; *(ptr+sectionStart+curSectLen+15) = aECG->Section1.Tag14.PROT_COMP_LEVEL; // tag 14, byte 15 (PROT_COMP_LEVEL has to be 0xA0 => level II) *(ptr+sectionStart+curSectLen+16) = aECG->Section1.Tag14.LANG_SUPP_CODE; // tag 14, byte 16 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) *(ptr+sectionStart+curSectLen+17) = aECG->Section1.Tag14.ECG_CAP_DEV; // tag 14, byte 17 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) *(ptr+sectionStart+curSectLen+18) = aECG->Section1.Tag14.MAINS_FREQ; // tag 14, byte 18 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) *(ptr+sectionStart+curSectLen+35) = strlen(aECG->Section1.Tag14.ANAL_PROG_REV_NUM)+1; // tag 14, byte 34 => length of ANAL_PROG_REV_NUM + 1 = 1 uint16_t len1 = 36; char* tmp; tmp = aECG->Section1.Tag14.ANAL_PROG_REV_NUM; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_SCP_SW; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; tmp = aECG->Section1.Tag14.ACQ_DEV_MANUF; len = min(25, strlen(tmp) + 1); strncpy((char*)(ptr+sectionStart+curSectLen+len1), tmp, len); len1 += len; leu16a(len1, ptr+sectionStart+curSectLen+1-3); // length curSectLen += len1; // Tag 16 (max len = 80) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 16 \n"); len = hdr->ID.Hospital ? strlen(hdr->ID.Hospital) : 0; if (len > 0) { *(ptr+sectionStart+curSectLen) = 16; // tag len = min(64,len+1); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),hdr->ID.Hospital,len); curSectLen += 3+len; } // Tag 20 (max len = 64 ) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 20 \n"); len = aECG->ReferringPhysician ? strlen(aECG->ReferringPhysician) : 0; if (len > 0) { *(ptr+sectionStart+curSectLen) = 20; // tag len = min(64,len+1); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->ReferringPhysician,len); curSectLen += 3+len; }; // Tag 21 (max len = 64 ) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 21 \n"); len = aECG->MedicationDrugs ? strlen(aECG->MedicationDrugs) : 0; if (len>0) { *(ptr+sectionStart+curSectLen) = 21; // tag len = min(64,len+1); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),aECG->MedicationDrugs,len); curSectLen += 3+len; }; // Tag 22 (max len = 40 ) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 22 \n"); len = hdr->ID.Technician ? strlen(hdr->ID.Technician) : 0; if (len > 0) { *(ptr+sectionStart+curSectLen) = 22; // tag len = min(64,len+1); leu16a(len, ptr+sectionStart+curSectLen+1); // length strncpy((char*)(ptr+sectionStart+curSectLen+3),hdr->ID.Technician,len); curSectLen += 3+len; } // Tag 24 ( len = 1 ) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 24 \n"); *(ptr+sectionStart+curSectLen) = 24; // tag leu16a(1, ptr+sectionStart+curSectLen+1); // length *(ptr+sectionStart+curSectLen+3) = aECG->EmergencyLevel; curSectLen += 4; // Tag 25 (len = 4) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 25 \n"); #if __FreeBSD__ || __APPLE__ || __NetBSD__ T0_tm = gdf_time2tm_time(hdr->T0); T0_tm->tm_gmtoff = hdr->tzmin*60; #else gdf_time T1 = hdr->T0; T1 += (int32_t)ldexp(timezone/86400.0,32); T0_tm = gdf_time2tm_time(T1); #endif *(ptr+sectionStart+curSectLen) = 25; // tag leu16a(4, ptr+sectionStart+curSectLen+1); // length leu16a(T0_tm->tm_year+1900, ptr+sectionStart+curSectLen+3);// year *(ptr+sectionStart+curSectLen+5) = (uint8_t)(T0_tm->tm_mon + 1);// month *(ptr+sectionStart+curSectLen+6) = (uint8_t)T0_tm->tm_mday; // day curSectLen += 7; // Tag 26 (len = 3) *(ptr+sectionStart+curSectLen) = 26; // tag leu16a(3, ptr+sectionStart+curSectLen+1); // length *(ptr+sectionStart+curSectLen+3) = (uint8_t)T0_tm->tm_hour; // hour *(ptr+sectionStart+curSectLen+4) = (uint8_t)T0_tm->tm_min; // minute *(ptr+sectionStart+curSectLen+5) = (uint8_t)T0_tm->tm_sec; // second curSectLen += 6; if (NS>0) { CHANNEL_TYPE *CH = hdr->CHANNEL; while (CH->OnOff != 1) CH++; // Tag 27 (len = 3) highpass filter *(ptr+sectionStart+curSectLen) = 27; // tag leu16a(2, ptr+sectionStart+curSectLen+1); // length leu16a((uint16_t)CH->HighPass, ptr+sectionStart+curSectLen+3); // hour curSectLen += 5; // Tag 28 (len = 3) lowpass filter *(ptr+sectionStart+curSectLen) = 28; // tag leu16a(2, ptr+sectionStart+curSectLen+1); // length leu16a((uint16_t)CH->LowPass, ptr+sectionStart+curSectLen+3); // hour curSectLen += 5; // Tag 29 (len = 1) filter bitmap uint8_t bitmap = 0; if (fabs(CH->LowPass-60.0)<0.01) bitmap = 1; else if (fabs(CH->LowPass-50.0)<0.01) bitmap = 2; else bitmap = 0; *(ptr+sectionStart+curSectLen) = 29; // tag leu16a(1, ptr+sectionStart+curSectLen+1); // length *(ptr+sectionStart+curSectLen+3) = bitmap; curSectLen += 4; } // Tag 32 (len = 5) if (VERBOSE_LEVEL>7) fprintf(stdout,"Section 1 Tag 32 \n"); *(ptr+sectionStart+curSectLen) = 32; // tag leu16a(2, ptr+sectionStart+curSectLen+1); // length if (hdr->Patient.Impairment.Heart==1) { *(ptr+sectionStart+curSectLen+3) = 0; *(ptr+sectionStart+curSectLen+4) = 1; // Apparently healthy curSectLen += 5; } else if (hdr->Patient.Impairment.Heart==3) { *(ptr+sectionStart+curSectLen+3) = 0; *(ptr+sectionStart+curSectLen+4) = 42; // Implanted cardiac pacemaker curSectLen += 5; } // Tag 34 (len = 5) *(ptr+sectionStart+curSectLen) = 34; // tag leu16a(5, ptr+sectionStart+curSectLen+1); // length lei16a(hdr->tzmin, ptr+sectionStart+curSectLen+3); lei16a(0, ptr+sectionStart+curSectLen+5); curSectLen += 8; // Tag 255 (len = 0) *(ptr+sectionStart+curSectLen) = 255; // tag leu16a(0, ptr+sectionStart+curSectLen+1); // length curSectLen += 3; // Evaluate the size and correct it if odd if (curSectLen & 1) { *(ptr+sectionStart+curSectLen++) = 0; } if (VERBOSE_LEVEL>7) fprintf(stdout,"End-of-Section %i %p\n",curSect,ptr); } else if (curSect==2) // SECTION 2 { } else if (curSect==3) // SECTION 3 { ptr = (uint8_t*)realloc(ptr,sectionStart+16+2+9*NS+1); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...) data.size=[%d,%d]\n",__FILE__,__LINE__,__func__,hdr->data.size[0],hdr->data.size[1]); // Number of leads enclosed *(ptr+sectionStart+curSectLen++) = NS; // ### Situations with reference beat subtraction are not supported // Situations with not all the leads simultaneously recorded are not supported // Situations number of leads simultaneouly recorded != total number of leads are not supported // We assume all the leads are recorded simultaneously *(ptr+sectionStart+curSectLen++) = (NS<<3) | 0x04; uint32_t SPR = hdr->SPR * hdr->NRec; for (i = 0; i < hdr->NS; i++) { CHANNEL_TYPE *CH=hdr->CHANNEL+i; if (CH->OnOff != 1) continue; leu32a(1L, ptr+sectionStart+curSectLen); leu32a(SPR, ptr+sectionStart+curSectLen+4); *(ptr+sectionStart+curSectLen+8) = (uint8_t)CH->LeadIdCode; curSectLen += 9; } // Evaluate the size and correct it if odd if ((curSectLen % 2) != 0) { *(ptr+sectionStart+curSectLen++) = 0; } memset(ptr+sectionStart+10,0,6); // reserved } else if (curSect==4) // SECTION 4 { } else if (curSect==5) // SECTION 5 { curSectLen = 0; // current section length aECG->Section5.StartPtr = sectionStart; aECG->Section5.Length = curSectLen; } else if (curSect==6) // SECTION 6 { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): Section %d v%3.1g %i,%i \n",__func__,__LINE__,curSect, versionSection*0.1,(int)aECG->Section6.StartPtr,(int)aECG->Section6.Length); if (versionSection < 25) // SECTION 6 { uint16_t GDFTYP = 3; size_t SZ = GDFTYP_BITS[GDFTYP]>>3; typeof(hdr->NS) i=0; for (i = 0; i < hdr->NS; i++) { CHANNEL_TYPE *hc=hdr->CHANNEL+i; if (hc->OnOff != 1) continue; hc->GDFTYP = GDFTYP; } ptr = (uint8_t*)realloc(ptr,sectionStart+16+6+2*NS+SZ*(hdr->data.size[0]*hdr->data.size[1])); PtrCurSect = ptr+sectionStart; curSectLen = 16; // current section length // Create all the fields char flagfirst = 1; for (i = 0; i < hdr->NS; i++) { CHANNEL_TYPE *CH=hdr->CHANNEL+i; if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i): %d#%d %g/%g \n",__func__,__LINE__,CH->OnOff,i,avm,AVM); if (CH->OnOff != 1) continue; // check for physical dimension and adjust scaling factor to "nV" avm = CH->Cal * 1e9 * PhysDimScale(CH->PhysDimCode); if (flagfirst) { // Amplitude Value Multiplier (AVM) AVM = avm; flagfirst=0; continue; } // check whether all channels have the same scaling factor if (fabs((AVM - avm)/AVM) > 1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): scaling factors differ between channel #1 and #%i. Scaling factor of 1st channel is used.\n",i+1); }; avm16 = lrint(AVM); leu16a(avm16, ptr+sectionStart+curSectLen); avm = leu16p(ptr+sectionStart+curSectLen); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): avm:%g avm16:%d AVM:%g\n", __func__, __LINE__, avm, avm16, AVM); curSectLen += 2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Scaling factor has been truncated (%f instead %f).\n",avm,AVM); // Sample interval AVM = 1e6/hdr->SampleRate; avm16 = lrint(AVM); leu16a(avm16, ptr+sectionStart+curSectLen); avm = leu16p(ptr+sectionStart+curSectLen); curSectLen += 2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Sampling interval has been truncated (%f instead %f us).\n",avm,AVM); // Diff used *(ptr+sectionStart+curSectLen++) = 0; // Bimodal/Non-bimodal *(ptr+sectionStart+curSectLen++) = 0; /* DATA COMPRESSION currently, no compression method is supported. In case of data compression, the data compression can happen here. */ // Fill the length block for (i = 0; i < NS; i++) { leu16a((uint16_t)hdr->data.size[0]*2, ptr+sectionStart+curSectLen); avm = leu16p(ptr+sectionStart+curSectLen); AVM = hdr->SPR*hdr->NRec*2; if (fabs((AVM - avm)/AVM)>1e-14) fprintf(stderr,"Warning SOPEN (SCP-WRITE): Block length truncated (%f instead %f us).\n",avm,AVM); curSectLen += 2; } /* data in channel multiplexed order */ for (i = 0; i < hdr->NS; i++) { hdr->CHANNEL[i].SPR *= hdr->NRec; }; hdr->NRec = 1; // Prepare filling the data block with the ECG samples by SWRITE curSectLen += SZ * hdr->SPR*hdr->NRec * NS; // Evaluate the size and correct it if odd if ((curSectLen % 2) != 0) { fprintf(stderr,"Warning Section 6 has an odd length\n"); *(ptr+sectionStart+curSectLen++) = 0; } memset(ptr+sectionStart+10,0,6); // reserved aECG->Section6.StartPtr = sectionStart; aECG->Section6.Length = curSectLen; } } else if (curSect==7) // SECTION 7 { if (hdr->SCP.Section7 != NULL) { curSectLen = hdr->SCP.Section7Length+16; // current section length ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); PtrCurSect = ptr+sectionStart; memcpy(PtrCurSect+16,hdr->SCP.Section7,hdr->SCP.Section7Length); } } else if (curSect==8) // SECTION 8 { if (hdr->SCP.Section8 != NULL) { curSectLen = hdr->SCP.Section8Length+16; // current section length ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); PtrCurSect = ptr+sectionStart; memcpy(PtrCurSect,hdr->SCP.Section8,hdr->SCP.Section8Length); } } else if (curSect==9) // SECTION 9 { if (hdr->SCP.Section9 != NULL) { curSectLen = hdr->SCP.Section9Length+16; // current section length ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); PtrCurSect = ptr+sectionStart; memcpy(PtrCurSect,hdr->SCP.Section9,hdr->SCP.Section9Length); } } else if (curSect==10) // SECTION 10 { if (hdr->SCP.Section10 != NULL) { curSectLen = hdr->SCP.Section10Length+16; // current section length ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); PtrCurSect = ptr+sectionStart; memcpy(PtrCurSect+16,hdr->SCP.Section10,hdr->SCP.Section10Length); } } else if (curSect==11) // SECTION 11 { if (hdr->SCP.Section11 != NULL) { curSectLen = hdr->SCP.Section11Length+16; // current section length ptr = (uint8_t*)realloc(ptr,sectionStart+curSectLen); PtrCurSect = ptr+sectionStart; memcpy(PtrCurSect+16,hdr->SCP.Section11,hdr->SCP.Section11Length); } } else if (curSect==12) // SECTION 12 { if (versionSection > 25 ) // SECTION 12, SCP version 3 { uint16_t gdftyp= 0; uint8_t bps = 0; //double PhysMax = -1.0/0.0; uint16_t PhysDimBaseCode = 4256; // Volt for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (hc->OnOff == 1) { if (bps < GDFTYP_BITS[gdftyp]) { bps = GDFTYP_BITS[hc->GDFTYP]; gdftyp = hc->GDFTYP; } } } if (NS>255) { NS=255; fprintf(stderr,"Warning SOPEN (SCP-WRITE): Number of channels exceeds 255, limited to 255.\n"); } bps = GDFTYP_BITS[gdftyp]>>3; double DigMax = ldexp(1.0, GDFTYP_BITS[gdftyp]-1)-1; int ns=0; for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (hc->OnOff > 0) { if (ns > 255) { hc->OnOff = 0; continue; } ns++; double scale = PhysDimScale(hc->PhysDimCode); hc->GDFTYP = gdftyp; hc->PhysMax = max(fabs(hc->PhysMax),fabs(-hc->PhysMin))*scale*1e9; hc->PhysMin = -hc->PhysMax; hc->Off = 0.0; hc->Cal = ceil(hc->PhysMax / hc->DigMax); // AVM must be integer //hc->DigMax = hc->PhysMax / hc->Cal; hc->DigMin = -hc->DigMax; hc->PhysDimCode = 4276; // nV } } curSectLen = 16 + 70 + NS * (4 + hdr->SPR*hdr->NRec * bps); // current section length without 16 bytes curSectLen+= (curSectLen & 1); ptr = (uint8_t*)realloc(ptr, sectionStart + curSectLen); memset(ptr + sectionStart, 0, 16+70); PtrCurSect = ptr + sectionStart + 16; leu32a((uint32_t)hdr->SampleRate, PtrCurSect); PtrCurSect[4] = (uint8_t)NS; leu32a((uint32_t)(hdr->NRec*hdr->SPR), PtrCurSect + 5); PtrCurSect[9] = (uint8_t)bps; // Recording Date and Time #if __FreeBSD__ || __APPLE__ || __NetBSD__ T0_tm = gdf_time2tm_time(hdr->T0); T0_tm->tm_gmtoff = hdr->tzmin*60; #else gdf_time T1 = hdr->T0; T1 += (int32_t)ldexp(timezone/86400.0,32); T0_tm = gdf_time2tm_time(T1); #endif leu16a(T0_tm->tm_year+1900, PtrCurSect+10); // year PtrCurSect[12] = (uint8_t)(T0_tm->tm_mon + 1); // month PtrCurSect[13] = (uint8_t)T0_tm->tm_mday; // day PtrCurSect[14] = (uint8_t)T0_tm->tm_hour; // hour PtrCurSect[15] = (uint8_t)T0_tm->tm_min; // minute PtrCurSect[16] = (uint8_t)T0_tm->tm_sec; // second // all other fields are set to zero. filter settings are defined in Section 1, Tags 27-29 /* Leads Definition block */ PtrCurSect += 70; for (k=0,ns=0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (hc->OnOff > 0) { PtrCurSect[ns*4] = hc->LeadIdCode; leu16a(hc->Cal, PtrCurSect+1+ns*4); // AVM per lead PtrCurSect[3+ns*4] = 0; ns++; } } /* ECG signals data block */ PtrCurSect += 4*NS; } aECG->Section12.StartPtr = sectionStart; aECG->Section12.Length = curSectLen; } else { } // write to pointer field in Section 0 leu16a(curSect, ptr+curSect*10+6+16); // leu32a(curSectLen, ptr+curSect*10+6+16+2); // length // Section start - must be odd. See EN1064:2005(E) Section 5.2.1 // write to Section ID Header if (curSectLen>0) { // Section 0: startpos in pointer field leu32a(sectionStart+1, ptr+curSect*10+6+16+6); // Section ID header (16 bytes) leu16a(curSect, ptr+sectionStart+2); // Section ID leu32a(curSectLen, ptr+sectionStart+4); // section length->section header ptr[sectionStart+8] = versionSection; // Section Version Number ptr[sectionStart+9] = versionProtocol; // Protocol Version Number if (curSect==0) { memcpy(ptr+16,"SCPECG",6); // defined as in ISO/DIS 11073-91064 Section 5.3.2 } else { memset(ptr+sectionStart+10,0,6); // reserved according to ISO/DIS 11073-91064 Section 5.2.7 } crc = CRCEvaluate(ptr+sectionStart+2,curSectLen-2); // compute CRC leu16a(crc, ptr+sectionStart); } sectionStart += curSectLen; // offset for next section } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); // Prepare filling the data block with the ECG samples by SWRITE if (versionSection < 25) hdr->AS.rawdata = ptr+aECG->Section6.StartPtr+16+6+2*NS; else hdr->AS.rawdata = ptr+aECG->Section12.StartPtr+16+70+4*NS; hdr->AS.Header = ptr; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i,%i %i,%i \n",__func__,__LINE__,(int)aECG->Section6.StartPtr,(int)aECG->Section6.Length,(int)aECG->Section12.StartPtr,(int)aECG->Section12.Length); return(0); } #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/t230/0000775000175000017500000000000014764352501013422 5stimfit-0.16.7/src/biosig/biosig4c++/t230/sopen_hl7aecg.cpp0000664000175000017500000015317514752215315016576 /* Copyright (C) 2006,2007,2009,2011,2012,2018 Alois Schloegl Copyright (C) 2007 Elias Apostolopoulos Copyright (C) 2011 Stoyan Mihaylov Copyright (C) 2018 Stefan Soueiha This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. */ #include // system includes #include // for strtod(3) #include #include "../biosig.h" #if defined(WITH_LIBTINYXML) # define TIXML_USE_STL # include #elif defined(WITH_LIBTINYXML2) # include #else # include "../XMLParser/tinyxml.h" #endif #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * convert time in string format into gdf-time format Currently, the following formats are supported YYYYMMDDhhmmss.uuuuuu YYYYMMDDhhmmss YYYYMMDD in case of error, zero is returned * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ EXTERN_C gdf_time str_time2gdf_time(const char *t1) { struct tm t0; gdf_time T; double fracsec = 0.0; double f; int len; #define MAXLEN 22 char t[MAXLEN+1]; if (t1==NULL) return(0); len = strlen(t1); if (len>MAXLEN) return(0); if (len<8) return(0); strncpy(t,t1,MAXLEN); t[len] = 0; if (VERBOSE_LEVEL>8) fprintf(stdout,"str_time2gdf_time: [%i]<%s>\n",len,t1); char *p = strrchr(t,'.'); if (p==NULL) { // no comma p = t+len; } else { for (p++, f=0.1; p[0]; p++, f=f/10) { if (p[0]<'0' || p[0]>'9') return(0); fracsec += (p[0]-'0')*f; } p = strrchr(t,'.'); } if (VERBOSE_LEVEL>8) fprintf(stdout,"str_time2gdf_time: [%i]<%s>\n",len,t1); if (len>=14) { // decode hhmmss p[0] = '\0'; p-=2; t0.tm_sec = atoi(p); p[0] = '\0'; p-=2; t0.tm_min = atoi(p); p[0] = '\0'; p-=2; t0.tm_hour = atoi(p); p[0] = '\0'; } else { t0.tm_sec = 0; t0.tm_min = 0; t0.tm_hour = 0; } p -= 2; t0.tm_mday = atoi(p); p[0] = '\0'; p-=2; t0.tm_mon = atoi(p)-1; p[0] = '\0'; p-=4; t0.tm_year = atoi(t)-1900; t0.tm_isdst = -1; T = tm_time2gdf_time(&t0); if (fracsec>0) T += ldexp(fracsec/86400,32); if (VERBOSE_LEVEL>8) fprintf(stdout,"str_time2gdf_time: [%i]<%s>\n",len,t1); return(T); } EXTERN_C int sopen_HL7aECG_read(HDRTYPE* hdr) { /* this function is a stub or placeholder and need to be defined in order to be useful. It will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ char tmp[80]; if (VERBOSE_LEVEL > 7) fprintf(stdout,"hl7r: [410]\n"); #if defined(TINYXML_INCLUDED) TiXmlDocument doc(hdr->FileName); #elif 0 // defined(TINYXML2_INCLUDED) // this is not ready yet tinyxml2::XMLDocument doc(hdr->FileName); #else biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "HL7aECG not supported because of missing libtinyxml - recompile with libtinyxml"); return -1; #endif if (VERBOSE_LEVEL > 7) fprintf(stdout,"hl7r: [411]\n"); if ( doc.LoadFile() ) { if (VERBOSE_LEVEL > 7) fprintf(stdout,"hl7r: [412]\n"); #if defined(TINYXML_INCLUDED) TiXmlHandle hDoc(&doc); TiXmlHandle geECG = hDoc.FirstChild("CardiologyXML"); TiXmlHandle IHE = hDoc.FirstChild("IHEDocumentList"); TiXmlHandle aECG = hDoc.FirstChild("AnnotatedECG"); TiXmlHandle SierraECG = hDoc.FirstChild("restingECG"); TiXmlHandle SierraECG2 = hDoc.FirstChild("restingecgdata"); #elif defined(TINYXML2_INCLUDED) TINYXML2_LIB XMLNode hDoc(doc); TINYXML2_LIB XMLNode geECG = hDoc.FirstChild("CardiologyXML"); TINYXML2_LIB XMLNode IHE = hDoc.FirstChild("IHEDocumentList"); TINYXML2_LIB XMLNode aECG = hDoc.FirstChild("AnnotatedECG"); TINYXML2_LIB XMLNode SierraECG = hDoc.FirstChild("restingECG"); TINYXML2_LIB XMLNode SierraECG2 = hDoc.FirstChild("restingecgdata"); #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [412]\n"); if (SierraECG.Element()) { fprintf(stdout,"Great! Philips Sierra ECG is recognized\n"); } else if (SierraECG2.Element()) { const char *t; const char *e; float notch = 0, lowpass=0, highpass=0; //uint16_t gdftyp = 16; struct tm t0; fprintf(stdout,"Great! Philips Sierra ECG 2 is recognized\n"); TiXmlHandle H = SierraECG2.FirstChild("dataacquisition"); if (H.Element()) { e = SierraECG2.FirstChild("dataacquisition").Element()->Attribute("date"); t0.tm_year = (int)strtod(e,(char**)&e) - 1900; t0.tm_mon = (int)strtod(e+1,(char**)&e) - 1 ; t0.tm_mday = (int)strtod(e+1,(char**)&e); e = SierraECG2.FirstChild("dataacquisition").Element()->Attribute("time"); t0.tm_hour = (int)strtod(e+1,(char**)&e); t0.tm_min = (int)strtod(e+1,(char**)&e); t0.tm_sec = (int)strtod(e+1,(char**)&e); hdr->T0 = tm_time2gdf_time(&t0); } H = SierraECG2.FirstChild("dataacquisition").FirstChild("signalcharacteristics").FirstChild("acsetting"); if (H.Element()) notch = atof(H.Element()->GetText()); H = SierraECG2.FirstChild("reportinfo").FirstChild("reportbandwidth").FirstChild("lowpassfiltersetting"); if (H.Element()) lowpass = atof(H.Element()->GetText()); H = SierraECG2.FirstChild("reportinfo").FirstChild("reportbandwidth").FirstChild("highpassfiltersetting"); if (H.Element()) highpass = atof(H.Element()->GetText()); H = SierraECG2.FirstChild("dataacquisition").FirstChild("acquirer").FirstChild("institutionname"); if (H.Element()) hdr->ID.Hospital = strdup(H.Element()->GetText()); H = SierraECG2.FirstChild("dataacquisition").FirstChild("signalcharacteristics").FirstChild("samplingrate"); if (H.Element()) hdr->SampleRate = atof(H.Element()->GetText()); H = SierraECG2.FirstChild("dataacquisition").FirstChild("signalcharacteristics").FirstChild("signalresolution"); double Cal = 1.0; if (H.Element()) Cal = atof(H.Element()->GetText()); H = SierraECG2.FirstChild("dataacquisition").FirstChild("signalcharacteristics").FirstChild("numberchannelsvalid"); if (H.Element()) hdr->NS = atoi(H.Element()->GetText()); H = SierraECG2.FirstChild("dataacquisition").FirstChild("signalcharacteristics").FirstChild("numberchannelsallocated"); if (H.Element()) { if (hdr->NS != atoi(H.Element()->GetText()) ) fprintf(stdout,"SierraECG: number of channels is ambiguous\n"); } H = SierraECG2.FirstChild("patient").FirstChild("generalpatientdata").FirstChild("patientid"); if (H.Element()) memcpy(hdr->Patient.Id, H.Element()->GetText(), MAX_LENGTH_PID); hdr->Patient.Name[0] = 0; size_t NameLength = 0; H = SierraECG2.FirstChild("patient").FirstChild("generalpatientdata").FirstChild("name").FirstChild("lastname"); if (H.Element()) { strncpy(hdr->Patient.Name, H.Element()->GetText(), MAX_LENGTH_NAME); hdr->Patient.Name[MAX_LENGTH_NAME]=0; NameLength = strlen(hdr->Patient.Name); } H = SierraECG2.FirstChild("patient").FirstChild("generalpatientdata").FirstChild("name").FirstChild("firstname"); if (H.Element()) { const char *str = H.Element()->GetText(); size_t l2 = strlen(str); if (NameLength+l2+1 < MAX_LENGTH_NAME) { hdr->Patient.Name[NameLength]= 0x1f; // unit separator ascii(31) strncpy(hdr->Patient.Name+NameLength+1, str, l2+1); NameLength += l2+1; } } H = SierraECG2.FirstChild("patient").FirstChild("generalpatientdata").FirstChild("name").FirstChild("middlename"); if (H.Element()) { const char *str = H.Element()->GetText(); size_t l2 = strlen(str); if (NameLength+l2+1 < MAX_LENGTH_NAME) { hdr->Patient.Name[NameLength]= ' '; strncpy(hdr->Patient.Name+NameLength+1, str, l2+1); NameLength += l2+1; } } H = SierraECG2.FirstChild("patient").FirstChild("generalpatientdata").FirstChild("age").FirstChild("years"); // if (H.Element()) hdr->Patient.Age != atoi(H.Element()->GetText()) H = SierraECG2.FirstChild("patient").FirstChild("generalpatientdata").FirstChild("sex"); if (H.Element()) { t = H.Element()->GetText(); hdr->Patient.Sex = (t[0]=='M') + (t[0]=='m') + 2 * ( (t[0]=='F') + (t[0]=='f') ); } H = SierraECG2.FirstChild("waveforms").FirstChild("parsedwaveforms"); if (H.Element()) { hdr->SPR = atof(H.Element()->Attribute("durationperchannel"))*hdr->SampleRate/1000; } hdr->NRec = 1; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (uint16_t k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->GDFTYP = 16; sprintf(hc->Label,"#%i",k); hc->Transducer[0] = 0; hc->Cal = Cal; hc->Off = 0.0; hc->OnOff = 1; hc->DigMin = -ldexp(1,15); hc->DigMax = +ldexp(1,15)-1; hc->PhysMin = hc->DigMin * Cal; hc->PhysMax = hc->DigMax * Cal; hc->PhysDimCode = PhysDimCode("nV"); //strcpy(hc->PhysDim,"nV"); hc->bi = k*hdr->SPR*4; hc->bi8 = 0; hc->LeadIdCode = 0; hc->SPR = hdr->SPR; hc->LowPass = lowpass; hc->HighPass = highpass; hc->Notch = notch; hc->TOffset = 0; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; } hdr->AS.bpb = sizeof(float)*hdr->NS; hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata, hdr->AS.bpb*hdr->NRec*hdr->SPR); hdr->AS.first = 0; hdr->AS.length= hdr->NRec; if (H.Element()) { const char *e = H.Element()->GetText(); size_t k = 0; while (e != NULL && k < hdr->SPR * (size_t)hdr->NRec * hdr->NS) { ((float*)hdr->AS.rawdata)[k++] = (float)strtod(e,(char**)&e); } } } else if (geECG.Element()) { hdr->ID.Manufacturer.Name = "GE"; TiXmlHandle H = geECG.FirstChild("ClinicalInfo").FirstChild("ObservationDateTime"); if (H.Element()) { struct tm t0; t0.tm_hour = atoi(H.FirstChild("Hour").Element()->GetText()); t0.tm_min = atoi(H.FirstChild("Minute").Element()->GetText()); t0.tm_sec = atoi(H.FirstChild("Second").Element()->GetText()); t0.tm_mday = atoi(H.FirstChild("Day").Element()->GetText()); t0.tm_mon = atoi(H.FirstChild("Month").Element()->GetText())-1; t0.tm_year = atoi(H.FirstChild("Year").Element()->GetText())-1900; hdr->T0 = tm_time2gdf_time(&t0); } H = geECG.FirstChild("Device-Type"); if (H.Element()) { strncpy(hdr->ID.Manufacturer._field, H.Element()->GetText(),MAX_LENGTH_PID); hdr->ID.Manufacturer.Model = hdr->ID.Manufacturer._field; } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [413]\n"); H = geECG.FirstChild("PatientInfo"); if (H.Element()) { strncpy(hdr->Patient.Id, H.FirstChild("PID").Element()->GetText(),MAX_LENGTH_PID); const char *tmp = H.FirstChild("PID").Element()->GetText(); hdr->Patient.Sex = (toupper(tmp[0])=='M') + 2*(toupper(tmp[0])=='F'); if (!hdr->FLAG.ANONYMOUS) { const char *str1 = H.FirstChild("Name").FirstChild("FamilyName").Element()->GetText(); const char *str2 = H.FirstChild("Name").FirstChild("GivenName").Element()->GetText(); size_t l1 = str1 ? strlen(str1) : 0; size_t l2 = str2 ? strlen(str2) : 0; if (0 < l1 && l1 <= MAX_LENGTH_PID) strncpy(hdr->Patient.Name, str1, l1+1); if (l1+l2+1 < MAX_LENGTH_PID) { hdr->Patient.Name[l1] = 0x1f; strncpy(hdr->Patient.Name+l1+1, str2, l2+1); } } } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [413]\n"); double Cal=0.0, LP=NAN, HP=NAN, Notch=0.0; hdr->NRec= 0; hdr->SPR = 1; hdr->NS = 1; H = geECG.FirstChild("FilterSetting"); if (H.Element()) { LP = atof(H.FirstChild("LowPass").Element()->GetText()); HP = atof(H.FirstChild("HighPass").Element()->GetText()); if (!strcasecmp("yes",H.FirstChild("Filter50Hz").Element()->GetText())) Notch = 50; else if (!strcasecmp("yes",H.FirstChild("Filter60Hz").Element()->GetText())) Notch = 60; } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [413]\n"); H = geECG.FirstChild("StripData"); TiXmlElement *C = NULL; if (H.Element()) { C = H.FirstChild("NumberOfLeads").Element(); if (C != NULL) hdr->NS = atoi(C->GetText()); C = H.FirstChild("ChannelSampleCountTotal").Element(); if (C != NULL) hdr->NRec = atoi(C->GetText()); hdr->SampleRate = atof(H.FirstChild("SampleRate").Element()->GetText()); Cal = atof(H.FirstChild("Resolution").Element()->GetText()); } uint16_t gdftyp = 3; hdr->AS.bpb = 0; int k=0, NCHAN = hdr->NS; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); C = H.FirstChild("WaveformData").Element(); while (C != NULL) { if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [413] %i\n",k); if (k>=NCHAN) { NCHAN = max(12,(NCHAN+1)*2); hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, NCHAN*sizeof(CHANNEL_TYPE)); } CHANNEL_TYPE *hc = hdr->CHANNEL + k; // default values hc->GDFTYP = gdftyp; hc->PhysDimCode = 4275; //PhysDimCode("uV"); hc->DigMin = (double)(int16_t)0x8000; hc->DigMax = (double)(int16_t)0x7fff; strncpy(hc->Label, C->Attribute("lead"), MAX_LENGTH_LABEL); hc->Transducer[0] = 0; hc->LeadIdCode = 0; size_t j; for (j=0; strcasecmp(hc->Label, LEAD_ID_TABLE[j]) && LEAD_ID_TABLE[j][0]; j++) {}; if (LEAD_ID_TABLE[j][0]) hc->LeadIdCode = j; hc->LowPass = LP; hc->HighPass = HP; hc->Notch = Notch; hc->Impedance = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; // defined hc->Cal = Cal; hc->Off = 0.0; hc->SPR = 1; hc->OnOff = 1; C = C->NextSiblingElement(); k++; } hdr->NS = k; if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [417] %i\n",hdr->NS); C = H.FirstChild("WaveformData").Element(); size_t szRawData = 0; size_t SPR = 0; for (k=0; kNS; k++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [415] %i\n",k); CHANNEL_TYPE *hc = hdr->CHANNEL + k; /* read data samples */ hc->DigMax = -1.0/0.0; hc->DigMin = 1.0/0.0; // int16_t* data = (int16_t*)(hdr->AS.rawdata)+SPR; hc->bi = hdr->AS.bpb; char *s = (char*)C->GetText(); const char *delim = ","; size_t spr = 0; while (s && *s) { s += strspn(s, delim); //skip kommas if (SPR+spr+1 >= szRawData) { szRawData = max(5000,2*szRawData); hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata, szRawData * sizeof(int16_t)); } double d = strtod(s,&s); ((int16_t*)hdr->AS.rawdata)[SPR+spr++] = d; /* get Min/Max */ if (d > hc->DigMax) hc->DigMax = d; if (d < hc->DigMin) hc->DigMin = d; } SPR += spr; hc->SPR = spr; hdr->SPR = lcm(hdr->SPR,spr); hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; C = C->NextSiblingElement(); } hdr->AS.bpb += hdr->SPR * 2; hdr->NRec = 1; hdr->AS.first = 0; hdr->AS.length = hdr->NRec; if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [497] %i\n",hdr->NS); } else if (IHE.Element()) { fprintf(stderr,"XML IHE: support for IHE XML is experimental - some important features are not implemented yet \n"); TiXmlHandle activityTime = IHE.FirstChild("activityTime"); TiXmlHandle recordTarget = IHE.FirstChild("recordTarget"); TiXmlHandle author = IHE.FirstChild("author"); /* an IHE file can contain several segments (i.e. components) need to implement TARGET_SEGMENT feature */ TiXmlHandle component = IHE.FirstChild("component"); if (VERBOSE_LEVEL>8) fprintf(stdout,"IHE: [413] \n"); if (author.FirstChild("assignedAuthor").Element()) { // TiXmlHandle noteText = author.FirstChild("noteText").Element(); TiXmlHandle assignedAuthor = author.FirstChild("assignedAuthor").Element(); if (assignedAuthor.FirstChild("assignedDevice").Element()) { TiXmlHandle assignedDevice = assignedAuthor.FirstChild("assignedDevice").Element(); hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field; if (assignedDevice.Element()) { strncpy(hdr->ID.Manufacturer._field, assignedDevice.FirstChild("manufacturerModelName").Element()->GetText(), MAX_LENGTH_MANUF); int len = strlen(hdr->ID.Manufacturer._field)+1; hdr->ID.Manufacturer.Model = hdr->ID.Manufacturer._field+len; strncpy(hdr->ID.Manufacturer._field+len, assignedDevice.FirstChild("code").Element()->Attribute("code"),MAX_LENGTH_MANUF-len); len += strlen(hdr->ID.Manufacturer.Model)+1; } } } if (recordTarget.FirstChild("patient").Element()) { TiXmlHandle patient = recordTarget.FirstChild("patient").Element(); TiXmlHandle id = patient.FirstChild("id").Element(); TiXmlHandle patientPatient = patient.FirstChild("patientPatient").Element(); TiXmlHandle providerOrganization = patient.FirstChild("providerOrganization").Element(); if (VERBOSE_LEVEL>8) fprintf(stdout,"IHE: [414] %p %p %p\n",id.Element(),patientPatient.Element(),providerOrganization.Element()); if (id.Element()) { char *strtmp = strdup(id.Element()->Attribute("root")); size_t len = strlen(strtmp); if (len <= MAX_LENGTH_RID) { strcpy(hdr->ID.Recording, strtmp); // Flawfinder: ignore if (strtmp) free(strtmp); strtmp = strdup(id.Element()->Attribute("extension")); size_t l1 = strlen(strtmp); if (len+1+l1 < MAX_LENGTH_RID) { len += 1 + l1; hdr->ID.Recording[len] = ' '; memcpy(hdr->ID.Recording+len+1,strtmp,l1+1); } else fprintf(stdout,"Warning HL7aECG(read): length of Recording ID exceeds maximum length %i>%i\n",(int)(len+1+l1),MAX_LENGTH_PID); } else fprintf(stdout,"Warning HL7aECG(read): length of Recording ID exceeds maximum length %i>%i\n",(int)len,MAX_LENGTH_PID); if (strtmp) free(strtmp); if (VERBOSE_LEVEL>7) fprintf(stdout,"IHE (read): length of Recording ID %i,%i\n",(int)len,MAX_LENGTH_PID); } if (VERBOSE_LEVEL>7) fprintf(stdout,"IHE: [414] RID= %s\n",hdr->ID.Recording); if (providerOrganization.Element()) { hdr->ID.Hospital = strdup(providerOrganization.FirstChild("name").Element()->GetText()); } if (VERBOSE_LEVEL>7) fprintf(stdout,"IHE: [414] hospital %s\n",hdr->ID.Hospital); if (patientPatient.Element()) { if (!hdr->FLAG.ANONYMOUS) { TiXmlHandle Name = patientPatient.FirstChild("name").Element(); if (Name.Element()) { char *str1 = strdup(Name.FirstChild("family").Element()->GetText()); char *str2 = strdup(Name.FirstChild("given").Element()->GetText()); size_t l1 = str1 ? strlen(str1) : 0; size_t l2 = str2 ? strlen(str2) : 0; if (l1 <= MAX_LENGTH_NAME) strcpy(hdr->Patient.Name, str1); // Flawfinder: ignore if (l1+l2+2 <= MAX_LENGTH_NAME) { strcpy(hdr->Patient.Name, str1); // Flawfinder: ignore hdr->Patient.Name[l1] = 0x1f; strcpy(hdr->Patient.Name+l1+1, str2); // Flawfinder: ignore } } } TiXmlHandle Gender = patientPatient.FirstChild("administrativeGenderCode").Element(); TiXmlHandle Birth = patientPatient.FirstChild("birthTime").Element(); if (Gender.Element()) { const char *gender = Gender.Element()->Attribute("code"); hdr->Patient.Sex = (tolower(gender[0])=='m') + (tolower(gender[0])=='f'); } if (Birth.Element()) { hdr->Patient.Birthday = str_time2gdf_time(Birth.Element()->Attribute("value")); } } } if (VERBOSE_LEVEL>8) fprintf(stdout,"IHE: [415] \n"); } else if(aECG.Element()){ if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [412]\n"); size_t len = strlen(aECG.FirstChild("id").Element()->Attribute("root")); if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [413]\n"); strncpy(hdr->ID.Recording,aECG.FirstChild("id").Element()->Attribute("root"),MAX_LENGTH_RID); if (len>MAX_LENGTH_RID) fprintf(stdout,"Warning HL7aECG(read): length of Recording ID exceeds maximum length %i>%i\n",(int)len,MAX_LENGTH_PID); if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [414]\n"); TiXmlHandle effectiveTime = aECG.FirstChild("effectiveTime"); char *T0 = NULL; if(effectiveTime.FirstChild("low").Element()) T0 = (char *)effectiveTime.FirstChild("low").Element()->Attribute("value"); else if(effectiveTime.FirstChild("center").Element()) T0 = (char *)effectiveTime.FirstChild("center").Element()->Attribute("value"); if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [413 2] <%s>\n", T0); if (T0 != NULL) hdr->T0 = str_time2gdf_time(T0); if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [413 4]\n"); TiXmlHandle demographic = aECG.FirstChild("componentOf").FirstChild("timepointEvent").FirstChild("componentOf").FirstChild("subjectAssignment").FirstChild("subject").FirstChild("trialSubject"); TiXmlElement *id = demographic.FirstChild("id").Element(); if(id) { const char* tmpstr = id->Attribute("extension"); size_t len = strlen(tmpstr); if (len>MAX_LENGTH_PID) fprintf(stdout,"Warning HL7aECG(read): length of Patient Id exceeds maximum length %i>%i\n",(int)len,MAX_LENGTH_PID); strncpy(hdr->Patient.Id,tmpstr,MAX_LENGTH_PID); } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [413]\n"); if (!hdr->FLAG.ANONYMOUS) { demographic = demographic.FirstChild("subjectDemographicPerson"); TiXmlElement *Name1 = demographic.FirstChild("name").Element(); if (Name1 != NULL) { const char *name = Name1->GetText(); if (name != NULL) { size_t len = strlen(name); if (len>MAX_LENGTH_NAME) fprintf(stdout,"Warning HL7aECG(read): length of Patient Name exceeds maximum length %i>%i\n",(int)len,MAX_LENGTH_PID); strncpy(hdr->Patient.Name, name, MAX_LENGTH_NAME); } else { fprintf(stderr,"Warning: composite subject name is not supported.\n"); if (VERBOSE_LEVEL>7) { fprintf(stdout,"hl7r: [413++]<%s>\n",name); for (int k=1;k<40;k++) fprintf(stderr,"%c.",((char*)Name1)[k]); } //hdr->Patient.Name[0] = 0; /* ### FIXME: support of composite patient name. const char *Name11 = Name1->Attribute("family"); fprintf(stdout,"Patient Family Name %p\n", Name11); char *Name2 = Name.FirstChild("given")->GetText(); if ((Name1!=NULL) || (Name2!=NULL)) { strncpy(hdr->Patient.Name, Name1, MAX_LENGTH_NAME); } */ } } else { hdr->Patient.Name[0] = 0; fprintf(stderr,"Warning: Patient Name not available could not be read.\n"); } } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [414]\n"); /* non-standard fields height and weight */ TiXmlElement *weight = demographic.FirstChild("weight").Element(); if (weight) { uint16_t code = PhysDimCode(weight->Attribute("unit")); if ((code & 0xFFE0) != 1728) fprintf(stderr,"Warning: incorrect weight unit (%s)\n",weight->Attribute("unit")); else // convert to kilogram hdr->Patient.Weight = (uint8_t)(atof(weight->Attribute("value"))*PhysDimScale(code)*1e-3); } TiXmlElement *height = demographic.FirstChild("height").Element(); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [415]\n"); if (height) { uint16_t code = PhysDimCode(height->Attribute("unit")); if ((code & 0xFFE0) != 1280) fprintf(stderr,"Warning: incorrect height unit (%s) %i \n",height->Attribute("unit"),code); else // convert to centimeter hdr->Patient.Height = (uint8_t)(atof(height->Attribute("value"))*PhysDimScale(code)*1e+2); } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [416]\n"); TiXmlElement *birthday = demographic.FirstChild("birthTime").Element(); if(birthday){ T0 = (char *)birthday->Attribute("value"); if (T0==NULL) T0=(char *)birthday->GetText(); // workaround for reading two different formats hdr->Patient.Birthday = str_time2gdf_time(T0); } if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [417]\n"); if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [418]\n"); TiXmlElement *sex = demographic.FirstChild("administrativeGenderCode").Element(); if(sex){ if (sex->Attribute("code")==NULL) hdr->Patient.Sex = 0; else if(!strcmp(sex->Attribute("code"),"F")) hdr->Patient.Sex = 2; else if(!strcmp(sex->Attribute("code"),"M")) hdr->Patient.Sex = 1; else hdr->Patient.Sex = 0; } else { hdr->Patient.Sex = 0; } if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [419]\n"); int LowPass=0, HighPass=0, Notch=0; TiXmlHandle channels = aECG.FirstChild("component").FirstChild("series").FirstChild("component").FirstChild("sequenceSet"); TiXmlHandle variables = aECG.FirstChild("component").FirstChild("series"); for(TiXmlElement *tmpvar = variables.FirstChild("controlVariable").Element(); tmpvar; tmpvar = tmpvar->NextSiblingElement("controlVariable")){ if(!strcmp(tmpvar->FirstChildElement("controlVariable")->FirstChildElement("code")->Attribute("code"), "MDC_ATTR_FILTER_NOTCH")) Notch = atoi(tmpvar->FirstChildElement("controlVariable")->FirstChildElement("component")->FirstChildElement("controlVariable")->FirstChildElement("value")->Attribute("value")); else if(!strcmp(tmpvar->FirstChildElement("controlVariable")->FirstChildElement("code")->Attribute("code"), "MDC_ATTR_FILTER_LOW_PASS")) LowPass = atoi(tmpvar->FirstChildElement("controlVariable")->FirstChildElement("component")->FirstChildElement("controlVariable")->FirstChildElement("value")->Attribute("value")); else if(!strcmp(tmpvar->FirstChildElement("controlVariable")->FirstChildElement("code")->Attribute("code"), "MDC_ATTR_FILTER_HIGH_PASS")) HighPass = atoi(tmpvar->FirstChildElement("controlVariable")->FirstChildElement("component")->FirstChildElement("controlVariable")->FirstChildElement("value")->Attribute("value")); } if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7r: [421]\n"); hdr->NRec = 1; // hdr->SPR = 1; // hdr->AS.rawdata = (uint8_t *)malloc(hdr->SPR); // int32_t *data; hdr->SampleRate = 1.0/atof(channels.FirstChild("component").FirstChild("sequence").FirstChild("value").FirstChild("increment").Element()->Attribute("value")); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [517] %f\n",hdr->SampleRate); /*************** Annotations **********************/ TiXmlHandle AnnotationSet = aECG.FirstChild("component").FirstChild("series").FirstChild("subjectOf").FirstChild("annotationSet"); TiXmlHandle Annotation = AnnotationSet.Child("component", 1).FirstChild("annotation").FirstChild("component").FirstChild("annotation"); size_t N_Event = 0, N=0; for(int i = 1; AnnotationSet.Child("component", i).FirstChild("annotation").Element(); ++i) { for(int j = 0; j<3; ++j) { Annotation = AnnotationSet.Child("component", i).FirstChild("annotation").Child("component",j).FirstChild("annotation"); if (Annotation.FirstChild("value").Element() == NULL) break; const char *code = Annotation.FirstChild("value").Element()->Attribute("code"); if (code==NULL) break; uint16_t EventTyp1 = 0, EventTyp2 = 0; if (!strcmp(code,"MDC_ECG_WAVC_PWAVE")) { EventTyp1 = 0x0502; // start P-Wave EventTyp2 = 0x8502; // end P-Wave } else if (!strcmp(code,"MDC_ECG_WAVC_QRSWAVE")) { EventTyp1 = 0x0503; // start QRS EventTyp2 = 0x8505; // end QRS } else if (!strcmp(code,"MDC_ECG_WAVC_TWAVE")) { EventTyp1 = 0x0506; // start T-Wave EventTyp2 = 0x8506; // end T-Wave } if ((N+3) > N_Event) { N_Event = max(16,2*(N+2)); hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP,N_Event*sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS,N_Event*sizeof(*hdr->EVENT.POS)); } TiXmlHandle Boundary = Annotation.FirstChild("support").FirstChild("supportingROI").FirstChild("component").FirstChild("boundary").FirstChild("value"); int64_t pos1=0, pos2=0; if (Boundary.FirstChild("low").Element()) { const char *tmpstr = (Boundary.FirstChild("low").Element()->Attribute("value")); pos1 = (ldexp((str_time2gdf_time(tmpstr)-hdr->T0)*86400*hdr->SampleRate,-32)); hdr->EVENT.TYP[N] = EventTyp1; hdr->EVENT.POS[N] = pos1; N++; } if (Boundary.FirstChild("high").Element()) { const char *tmpstr = (Boundary.FirstChild("high").Element()->Attribute("value")); pos2 = (ldexp((str_time2gdf_time(tmpstr)-hdr->T0)*86400*hdr->SampleRate,-32)); hdr->EVENT.TYP[N] = EventTyp2; hdr->EVENT.POS[N] = pos2; N++; } } } hdr->EVENT.N = N; TiXmlHandle channel = channels.Child("component", 1).FirstChild("sequence"); for (hdr->NS = 0; channel.Element(); ++(hdr->NS), channel = channels.Child("component", hdr->NS+1).FirstChild("sequence")) {}; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); channel = channels.Child("component", 1).FirstChild("sequence"); hdr->AS.bpb = 0; size_t szRawData = 0; size_t SPR = 0; hdr->SPR = 1; for(int i = 0; channel.Element(); ++i, channel = channels.Child("component", i+1).FirstChild("sequence")){ const char *code = channel.FirstChild("code").Element()->Attribute("code"); CHANNEL_TYPE *hc = hdr->CHANNEL+i; hc->LeadIdCode = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] %i\n",i); strncpy(hc->Label, code, min(40, MAX_LENGTH_LABEL)); hc->Label[MAX_LENGTH_LABEL] = '\0'; hc->Transducer[0] = '\0'; hc->GDFTYP = 16; // float32 hc->DigMax = -1.0/0.0; hc->DigMin = 1.0/0.0; if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] %i\n",i); char *s = (char*) channel.FirstChild("value").FirstChild("digits").Element()->GetText(); size_t spr = 0; //char *ps = s ? s+strlen(s) : NULL; //end of s if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] %i %p <%s>\n",i,s,s); while (s && *s) { if (SPR+spr+1 >= szRawData) { szRawData = max(5000, 2*szRawData); hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata, szRawData * sizeof(float)); } double d = strtod(s,&s); ((float*)(hdr->AS.rawdata))[SPR + spr++] = d; /* get Min/Max */ if(d > hc->DigMax) hc->DigMax = d; if(d < hc->DigMin) hc->DigMin = d; } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] %i %i\n",i,(int)spr); hc->bi = hdr->AS.bpb; SPR += spr; hc->SPR = spr; if (spr>0) hdr->SPR = lcm(hdr->SPR,spr); hc->OnOff = 1; hc->LeadIdCode = 0; hdr->AS.bpb += hc->SPR * sizeof(float); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420+] %i\n",i); /* scaling factors */ const char *tmpchar; tmpchar = channel.FirstChild("value").FirstChild("scale").Element()->Attribute("value"); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] <%s>\n",tmpchar); hc->Cal = atof(tmpchar); tmpchar = channel.FirstChild("value").FirstChild("origin").Element()->Attribute("value"); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] <%s>\n",tmpchar); hc->Off = atof(tmpchar); hc->DigMax += 1; hc->DigMin -= 1; if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] Cal: %f Off: %f\n",hc->Cal,hc->Off); hc->PhysMax = hc->DigMax*hc->Cal + hc->Off; hc->PhysMin = hc->DigMin*hc->Cal + hc->Off; /* Physical units */ strncpy(tmp, channel.FirstChild("value").FirstChild("origin").Element()->Attribute("unit"),20); hc->PhysDimCode = PhysDimCode(tmp); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7r: [420] %i\n",i); hc->LowPass = LowPass; hc->HighPass = HighPass; hc->Notch = Notch; // hc->XYZ[0] = l_endian_f32( *(float*) (Header2+ 4*k + 224*hdr->NS) ); // hc->XYZ[1] = l_endian_f32( *(float*) (Header2+ 4*k + 228*hdr->NS) ); // hc->XYZ[2] = l_endian_f32( *(float*) (Header2+ 4*k + 232*hdr->NS) ); // //memcpy(&hdr->CHANNEL[k].XYZ,Header2 + 4*k + 224*hdr->NS,12); // hc->Impedance= ldexp(1.0, (uint8_t)Header2[k + 236*hdr->NS]/8); // hc->Impedance = INF; // for(int k1=0; k1<3; hdr->CHANNEL[index].XYZ[k1++] = 0.0); } hdr->FLAG.OVERFLOWDETECTION = 0; if (VERBOSE_LEVEL>7) { fprintf(stdout,"hl7r: [430] %i\n",hdr->AS.B4C_ERRNUM); hdr2ascii(hdr,stdout,3); fprintf(stdout,"hl7r: [431] %i\n",hdr->AS.B4C_ERRNUM); } } else { fprintf(stderr, "%s : failed to parse (2)\n", hdr->FileName); } } else fprintf(stderr, "%s : failed to parse (1)\n", hdr->FileName); return(0); }; EXTERN_C void sopen_HL7aECG_write(HDRTYPE* hdr) { if (VERBOSE_LEVEL > 7) fprintf(stdout,"hl7w: [610] <%s>\n",hdr->FileName); size_t k; for (k=0; kNS; k++) { hdr->CHANNEL[k].GDFTYP = 16; //float32 hdr->CHANNEL[k].SPR *= hdr->NRec; } hdr->SPR *= hdr->NRec; hdr->NRec = 1; hdr->FILE.OPEN=2; return; }; EXTERN_C int sclose_HL7aECG_write(HDRTYPE* hdr){ /* this function is a stub or placeholder and need to be defined in order to be useful. It will be called by the function SOPEN in "biosig.c" Input: HDR structure Output: char* HDR.AS.Header // contains the content which will be written to the file in SOPEN */ if (VERBOSE_LEVEL > 7) fprintf(stdout,"hl7c: [910] <%s>\n",hdr->FileName); struct tm *t0; char tmp[80]; #if defined(TINYXML_INCLUDED) TiXmlDocument doc; TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "UTF-8", ""); doc.LinkEndChild(decl); #elif 0 // defined(TINYXML2_INCLUDED) // this is not ready yet #else biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "HL7aECG not supported because of missing libtinyxml - recompile with libtinyxml"); return -1; #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"910 %i\n",1); TiXmlElement *root = new TiXmlElement("AnnotatedECG"); root->SetAttribute("xmlns", "urn:hl7-org:v3"); root->SetAttribute("xmlns:voc", "urn:hl7-org:v3/voc"); root->SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); root->SetAttribute("xsi:schemaLocation", "urn:hl7-org:v3/HL7/aECG/2003-12/schema/PORT_MT020001.xsd"); root->SetAttribute("classCode", "OBS"); root->SetAttribute("moodCode", "EVN"); root->SetAttribute("type", "Observation"); doc.LinkEndChild(root); TiXmlElement *rootid = new TiXmlElement("id"); rootid->SetAttribute("root", hdr->ID.Recording); root->LinkEndChild(rootid); TiXmlElement *rootCode = new TiXmlElement("code"); rootCode->SetAttribute("code", "93000"); rootCode->SetAttribute("codeSystem", "2.16.840.1.113883.6.12"); rootCode->SetAttribute("codeSystemName", "CPT-4"); root->LinkEndChild(rootCode); if (VERBOSE_LEVEL>7) fprintf(stdout,"910 %i\n",2); char timelow[24], timehigh[24]; gdf_time t1,t2; t1 = hdr->T0; if (VERBOSE_LEVEL>7) fprintf(stdout,"gdftime: hdr->T0: %ld\n", t1); t0 = gdf_time2tm_time(t1); sprintf(timelow, "%4d%2d%2d%2d%2d%2d", t0->tm_year+1900, t0->tm_mon+1, t0->tm_mday, t0->tm_hour, t0->tm_min, t0->tm_sec); t1 = hdr->T0 + ldexp((hdr->SPR/hdr->SampleRate)/(3600.0*24),32); t0 = gdf_time2tm_time(t1); sprintf(timehigh, "%4d%2d%2d%2d%2d%2d", t0->tm_year+1900, t0->tm_mon+1, t0->tm_mday, t0->tm_hour, t0->tm_min, t0->tm_sec); for(int i=0; i<18; ++i) { if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 920 %i\n",i); if(timelow[i] == ' ') timelow[i] = '0'; if(timehigh[i] == ' ') timehigh[i] = '0'; } if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 930\n"); TiXmlElement *effectiveTime = new TiXmlElement("effectiveTime"); TiXmlElement *effectiveTimeLow = new TiXmlElement("low"); effectiveTimeLow->SetAttribute("value", timelow); effectiveTime->LinkEndChild(effectiveTimeLow); TiXmlElement *effectiveTimeHigh = new TiXmlElement("high"); effectiveTimeHigh->SetAttribute("value", timehigh); effectiveTime->LinkEndChild(effectiveTimeHigh); root->LinkEndChild(effectiveTime); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 931\n"); TiXmlElement *rootComponentOf = new TiXmlElement("componentOf"); rootComponentOf->SetAttribute("typeCode", "COMP"); rootComponentOf->SetAttribute("contextConductionInd", "true"); root->LinkEndChild(rootComponentOf); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 932\n"); TiXmlElement *timePointEvent = new TiXmlElement("timepointEvent"); timePointEvent->SetAttribute("classCode", "CTTEVENT"); timePointEvent->SetAttribute("moodCode", "EVN"); rootComponentOf->LinkEndChild(timePointEvent); TiXmlElement *timePointComponentOf = new TiXmlElement("componentOf"); timePointComponentOf->SetAttribute("typeCode", "COMP"); timePointComponentOf->SetAttribute("contextConductionInd", "true"); timePointEvent->LinkEndChild(timePointComponentOf); TiXmlElement *subjectAssignment = new TiXmlElement("subjectAssignment"); subjectAssignment->SetAttribute("classCode", "CLNTRL"); subjectAssignment->SetAttribute("moodCode", "EVN"); timePointComponentOf->LinkEndChild(subjectAssignment); TiXmlElement *subject = new TiXmlElement("subject"); subject->SetAttribute("typeCode", "SBJ"); subject->SetAttribute("contextControlCode", "OP"); subjectAssignment->LinkEndChild(subject); TiXmlElement *trialSubject = new TiXmlElement("trialSubject"); trialSubject->SetAttribute("classCode", "RESBJ"); subject->LinkEndChild(trialSubject); if (strlen(hdr->Patient.Id)>0) { TiXmlElement *trialSubjectId = new TiXmlElement("id"); trialSubjectId->SetAttribute("extension", hdr->Patient.Id); trialSubject->LinkEndChild(trialSubjectId); } TiXmlElement *trialSubjectDemographicPerson = new TiXmlElement("subjectDemographicPerson"); trialSubjectDemographicPerson->SetAttribute("classCode", "PSN"); trialSubjectDemographicPerson->SetAttribute("determinerCode", "INSTANCE"); trialSubject->LinkEndChild(trialSubjectDemographicPerson); if (VERBOSE_LEVEL>7) fprintf(stdout,"933\n"); if (strlen(hdr->Patient.Name)>0) if (!hdr->FLAG.ANONYMOUS) { TiXmlElement *subjectDemographicPersonName = new TiXmlElement("name"); char tmpstr[MAX_LENGTH_NAME+1]; strcpy(tmpstr, hdr->Patient.Name); char *LastName=strtok(tmpstr, "\x1f"); char *FirstName=strtok(NULL, "\x1f"); /* LastName */ TiXmlElement *subjectDemographicPersonLastName = new TiXmlElement("family"); TiXmlText *lastnameText = new TiXmlText(LastName); subjectDemographicPersonLastName->LinkEndChild(lastnameText); subjectDemographicPersonName->LinkEndChild(subjectDemographicPersonLastName); /* FirstName */ TiXmlElement *subjectDemographicPersonFirstName = new TiXmlElement("given"); TiXmlText *firstnameText = new TiXmlText(FirstName); subjectDemographicPersonFirstName->LinkEndChild(firstnameText); subjectDemographicPersonName->LinkEndChild(subjectDemographicPersonFirstName); trialSubjectDemographicPerson->LinkEndChild(subjectDemographicPersonName); } TiXmlElement *subjectDemographicPersonGender = new TiXmlElement("administrativeGenderCode"); if(hdr->Patient.Sex == 1){ subjectDemographicPersonGender->SetAttribute("code", "M"); subjectDemographicPersonGender->SetAttribute("displayName", "Male"); } else if(hdr->Patient.Sex == 2){ subjectDemographicPersonGender->SetAttribute("code", "F"); subjectDemographicPersonGender->SetAttribute("displayName", "Female"); } else{ subjectDemographicPersonGender->SetAttribute("code", "UN"); subjectDemographicPersonGender->SetAttribute("displayName", "Undefined"); } subjectDemographicPersonGender->SetAttribute("codeSystem", "2.16.840.1.113883.5.1"); subjectDemographicPersonGender->SetAttribute("codeSystemName", "AdministrativeGender"); trialSubjectDemographicPerson->LinkEndChild(subjectDemographicPersonGender); if (hdr->Patient.Birthday>0) { t0 = gdf_time2tm_time(hdr->Patient.Birthday); // TODO: fixme if "t0->tm_sec" sprintf(tmp, "%04d%02d%02d%02d%02d%02d", t0->tm_year+1900, t0->tm_mon+1, t0->tm_mday, t0->tm_hour, t0->tm_min, t0->tm_sec); TiXmlElement *subjectDemographicPersonBirthtime = new TiXmlElement("birthTime"); subjectDemographicPersonBirthtime->SetAttribute("value", tmp); trialSubjectDemographicPerson->LinkEndChild(subjectDemographicPersonBirthtime); } /* write non-standard fields height and weight */ if (hdr->Patient.Weight) { sprintf(tmp,"%i",hdr->Patient.Weight); TiXmlElement *subjectDemographicPersonWeight = new TiXmlElement("weight"); subjectDemographicPersonWeight->SetAttribute("value", tmp); subjectDemographicPersonWeight->SetAttribute("unit", "kg"); trialSubjectDemographicPerson->LinkEndChild(subjectDemographicPersonWeight); } if (hdr->Patient.Height) { sprintf(tmp,"%i",hdr->Patient.Height); TiXmlElement *subjectDemographicPersonHeight = new TiXmlElement("height"); subjectDemographicPersonHeight->SetAttribute("value", tmp); subjectDemographicPersonHeight->SetAttribute("unit", "cm"); trialSubjectDemographicPerson->LinkEndChild(subjectDemographicPersonHeight); } if (VERBOSE_LEVEL>7) fprintf(stdout,"937\n"); TiXmlElement *subjectAssignmentComponentOf = new TiXmlElement("componentOf"); subjectAssignmentComponentOf->SetAttribute("typeCode", "COMP"); subjectAssignmentComponentOf->SetAttribute("contextConductionInd", "true"); subjectAssignment->LinkEndChild(subjectAssignmentComponentOf); TiXmlElement *clinicalTrial = new TiXmlElement("clinicalTrial"); clinicalTrial->SetAttribute("classCode", "CLNTRL"); clinicalTrial->SetAttribute("moodCode", "EVN"); subjectAssignmentComponentOf->LinkEndChild(clinicalTrial); TiXmlElement *clinicalTrialId = new TiXmlElement("id"); clinicalTrialId->SetAttribute("root", "GRATZ"); clinicalTrialId->SetAttribute("extension", "CLINICAL_TRIAL"); clinicalTrial->LinkEndChild(clinicalTrialId); /* location/trialSite/location/name */ /* hdr->ID.Hospital is malloc'ed only if exist */ TiXmlText *t_location = new TiXmlText(hdr->ID.Hospital ? hdr->ID.Hospital : ""); TiXmlElement *s_location_1 = new TiXmlElement("location"); TiXmlElement *s_location_2 = new TiXmlElement("trialSite"); TiXmlElement *s_location_3 = new TiXmlElement("location"); TiXmlElement *s_location_name = new TiXmlElement("name"); s_location_name->LinkEndChild(t_location); s_location_3->LinkEndChild(s_location_name); s_location_2->LinkEndChild(s_location_3); s_location_1->LinkEndChild(s_location_2); clinicalTrial->LinkEndChild(s_location_1); TiXmlElement *rootComponent = new TiXmlElement("component"); rootComponent->SetAttribute("typeCode", "COMP"); rootComponent->SetAttribute("contextConductionInd", "true"); root->LinkEndChild(rootComponent); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 939\n"); TiXmlElement *series = new TiXmlElement("series"); series->SetAttribute("classCode", "OBSSER"); series->SetAttribute("moodCode", "EVN"); rootComponent->LinkEndChild(series); TiXmlElement *seriesCode = new TiXmlElement("code"); seriesCode->SetAttribute("code", "RHYTHM"); seriesCode->SetAttribute("seriesCode", "2.16.840.1.113883.5.4"); series->LinkEndChild(seriesCode); TiXmlElement *seriesEffectiveTime = new TiXmlElement("effectiveTime"); TiXmlElement *seriesEffectiveTimeLow = new TiXmlElement("low"); seriesEffectiveTimeLow->SetAttribute("value", timelow); seriesEffectiveTime->LinkEndChild(seriesEffectiveTimeLow); TiXmlElement *seriesEffectiveTimeHigh = new TiXmlElement("high"); seriesEffectiveTimeHigh->SetAttribute("value", timehigh); seriesEffectiveTime->LinkEndChild(seriesEffectiveTimeHigh); series->LinkEndChild(seriesEffectiveTime); /* Manufacturer device modelname manu name */ TiXmlText *t_modelname = new TiXmlText(hdr->ID.Manufacturer.Model ? hdr->ID.Manufacturer.Model : ""); TiXmlText *t_manuname = new TiXmlText(hdr->ID.Manufacturer.Name ? hdr->ID.Manufacturer.Name : ""); TiXmlElement *s_author = new TiXmlElement("author"); TiXmlElement *s_seriesauthor = new TiXmlElement("seriesAuthor"); TiXmlElement *s_manudev = new TiXmlElement("manufacturedSeriesDevice"); TiXmlElement *s_manumodel = new TiXmlElement("manufacturerModelName"); s_manumodel->LinkEndChild(t_modelname); s_manudev->LinkEndChild(s_manumodel); s_seriesauthor->LinkEndChild(s_manudev); TiXmlElement *s_manuorg = new TiXmlElement("manufacturerOrganization"); TiXmlElement *s_manuorgname = new TiXmlElement("name"); s_manuorgname->LinkEndChild(t_manuname); s_manuorg->LinkEndChild(s_manuorgname); s_seriesauthor->LinkEndChild(s_manuorg); s_author->LinkEndChild(s_seriesauthor); series->LinkEndChild(s_author); for(int i=3; i; --i){ if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 950 %i\n",i); TiXmlElement *seriesControlVariable = new TiXmlElement("controlVariable"); seriesControlVariable->SetAttribute("typeCode", "CTRLV"); series->LinkEndChild(seriesControlVariable); TiXmlElement *CTRLControlVariable = new TiXmlElement("controlVariable"); CTRLControlVariable->SetAttribute("classCode", "OBS"); seriesControlVariable->LinkEndChild(CTRLControlVariable); TiXmlElement *controlVariableCode = new TiXmlElement("code"); CTRLControlVariable->LinkEndChild(controlVariableCode); TiXmlElement *controlVariableComponent = new TiXmlElement("component"); controlVariableComponent->SetAttribute("typeCode", "COMP"); CTRLControlVariable->LinkEndChild(controlVariableComponent); TiXmlElement *componentControlVariable = new TiXmlElement("controlVariable"); componentControlVariable->SetAttribute("classCode", "OBS"); controlVariableComponent->LinkEndChild(componentControlVariable); TiXmlElement *componentControlVariableCode = new TiXmlElement("code"); componentControlVariable->LinkEndChild(componentControlVariableCode); TiXmlElement *componentControlVariableValue = new TiXmlElement("value"); componentControlVariableValue->SetAttribute("xsi:type", "PQ"); componentControlVariable->LinkEndChild(componentControlVariableValue); switch(i){ case 3: controlVariableCode->SetAttribute("code", "MDC_ATTR_FILTER_NOTCH"); componentControlVariableCode->SetAttribute("code", "MDC_ATTR_NOTCH_FREQ"); componentControlVariableValue->SetDoubleAttribute("value", hdr->CHANNEL[0].Notch); break; case 2: controlVariableCode->SetAttribute("code", "MDC_ATTR_FILTER_LOW_PASS"); componentControlVariableCode->SetAttribute("code", "MDC_ATTR_FILTER_CUTOFF_FREQ"); componentControlVariableValue->SetDoubleAttribute("value", hdr->CHANNEL[0].LowPass); break; case 1: controlVariableCode->SetAttribute("code", "MDC_ATTR_FILTER_HIGH_PASS"); componentControlVariableCode->SetAttribute("code", "MDC_ATTR_FILTER_CUTOFF_FREQ"); componentControlVariableValue->SetDoubleAttribute("value", hdr->CHANNEL[0].HighPass); break; } controlVariableCode->SetAttribute("codeSystem", "2.16.840.1.113883.6.24"); controlVariableCode->SetAttribute("codeSystemName", "MDC"); componentControlVariableCode->SetAttribute("codeSystem", "2.16.840.1.113883.6.24"); componentControlVariableCode->SetAttribute("codeSystemName", "MDC"); componentControlVariableValue->SetAttribute("unit", "Hz"); switch(i){ case 3: controlVariableCode->SetAttribute("displayName", "Notch Filter"); componentControlVariableCode->SetAttribute("displayName", "Notch Frequency"); break; case 2: controlVariableCode->SetAttribute("displayName", "Low Pass Filter"); componentControlVariableCode->SetAttribute("displayName", "Cutoff Frequency"); break; case 1: controlVariableCode->SetAttribute("displayName", "High Pass Filter"); componentControlVariableCode->SetAttribute("displayName", "Cutoff Frequency"); break; } } TiXmlElement *seriesComponent = new TiXmlElement("component"); seriesComponent->SetAttribute("typeCode", "COMP"); seriesComponent->SetAttribute("contextConductionInd", "true"); series->LinkEndChild(seriesComponent); TiXmlElement *sequenceSet = new TiXmlElement("sequenceSet"); sequenceSet->SetAttribute("classCode", "OBSCOR"); sequenceSet->SetAttribute("moodCode", "EVN"); seriesComponent->LinkEndChild(sequenceSet); TiXmlElement *sequenceSetComponent = new TiXmlElement("component"); sequenceSetComponent->SetAttribute("typeCode", "COMP"); sequenceSetComponent->SetAttribute("contextConductionInd", "true"); sequenceSet->LinkEndChild(sequenceSetComponent); TiXmlElement *sequence = new TiXmlElement("sequence"); sequence->SetAttribute("classCode", "OBS"); sequence->SetAttribute("moodCode", "EVN"); sequenceSetComponent->LinkEndChild(sequence); TiXmlElement *sequenceCode = new TiXmlElement("code"); sequenceCode->SetAttribute("code", "TIME_ABSOLUTE"); sequenceCode->SetAttribute("codeSystem", "2.16.840.1.113883.6.24"); sequence->LinkEndChild(sequenceCode); TiXmlElement *sequenceValue = new TiXmlElement("value"); sequenceValue->SetAttribute("xsi:type", "GLIST_TS"); sequence->LinkEndChild(sequenceValue); TiXmlElement *valueHead = new TiXmlElement("head"); valueHead->SetAttribute("value", timelow); valueHead->SetAttribute("unit", "s"); // TODO: value is date/time of the day - unit=[s] does not make sense sequenceValue->LinkEndChild(valueHead); TiXmlElement *valueIncrement = new TiXmlElement("increment"); valueIncrement->SetDoubleAttribute("value", 1/hdr->SampleRate); valueIncrement->SetAttribute("unit", "s"); sequenceValue->LinkEndChild(valueIncrement); TiXmlText *digitsText; float*Dat; char *S; char *pS; #ifdef NO_BI size_t bi = 0; #endif for(int i=0; iNS; ++i) if (hdr->CHANNEL[i].OnOff) { if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 960 %i\n",i); sequenceSetComponent = new TiXmlElement("component"); sequenceSetComponent->SetAttribute("typeCode", "COMP"); sequenceSetComponent->SetAttribute("contextConductionInd", "true"); sequenceSet->LinkEndChild(sequenceSetComponent); sequence = new TiXmlElement("sequence"); sequence->SetAttribute("classCode", "OBS"); sequence->SetAttribute("moodCode", "EVN"); sequenceSetComponent->LinkEndChild(sequence); sequenceCode = new TiXmlElement("code"); if (hdr->CHANNEL[i].LeadIdCode) { strcpy(tmp,"MDC_ECG_LEAD_"); // Flawfinder: ignore strcat(tmp,LEAD_ID_TABLE[hdr->CHANNEL[i].LeadIdCode]); // Flawfinder: ignore } else strcpy(tmp,hdr->CHANNEL[i].Label); // Flawfinder: ignore sequenceCode->SetAttribute("code", tmp); sequenceCode->SetAttribute("codeSystem", "2.16.840.1.113883.6.24"); sequenceCode->SetAttribute("codeSystemName", "MDC"); sequence->LinkEndChild(sequenceCode); sequenceValue = new TiXmlElement("value"); sequenceValue->SetAttribute("xsi:type", "SLIST_PQ"); sequence->LinkEndChild(sequenceValue); valueHead = new TiXmlElement("origin"); valueHead->SetDoubleAttribute("value", hdr->CHANNEL[i].Off); // valueHead->SetDoubleAttribute("value", 0); valueHead->SetAttribute("unit", PhysDim3(hdr->CHANNEL[i].PhysDimCode)); sequenceValue->LinkEndChild(valueHead); valueIncrement = new TiXmlElement("scale"); valueIncrement->SetDoubleAttribute("value", hdr->CHANNEL[i].Cal); //valueIncrement->SetDoubleAttribute("value", 1); valueIncrement->SetAttribute("unit", PhysDim3(hdr->CHANNEL[i].PhysDimCode)); sequenceValue->LinkEndChild(valueIncrement); TiXmlElement *valueDigits = new TiXmlElement("digits"); sequenceValue->LinkEndChild(valueDigits); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c [967] %i %f\n",i,*(float*)(hdr->AS.rawdata + hdr->CHANNEL[i].bi)); #ifndef NO_BI Dat=(float*)(hdr->AS.rawdata + hdr->CHANNEL[i].bi); #else Dat=(float*)(hdr->AS.rawdata + bi); #endif //size_t sz = GDFTYP_BITS[hdr->CHANNEL[i].GDFTYP]>>3; S=new char[32*hdr->CHANNEL[i].SPR]; S[0]=0; pS=S; for (unsigned int j=0; jCHANNEL[i].SPR; ++j) { if (VERBOSE_LEVEL>8) fprintf(stdout,"hl7c 969: %i %i %f \n",i, j, Dat [j]); pS+=sprintf(pS,"%g ",Dat[j]); } #ifdef NO_BI bi += hdr->CHANNEL[i].SPR*sz; if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 970 %i %i \n%s \n",i, bi, S); #else if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 970 %i %i \n%s \n",i, hdr->CHANNEL[i].bi, S); #endif digitsText = new TiXmlText(S); valueDigits->LinkEndChild(digitsText); delete []S; } #if defined(WITH_LIBTINYXML) if (hdr->FILE.COMPRESSION) fprintf(stderr,"WARNING: saving of compressed HL7aECG file not supported - compression flag is ignored\n"); int status = doc.SaveFile(hdr->FileName); #else int status = doc.SaveFile(hdr->FileName, (char)hdr->FILE.COMPRESSION); #endif // doc.SaveFile(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"hl7c 989 (%i)\n",status); return(0); }; stimfit-0.16.7/src/biosig/biosig4c++/biosig-dev.h0000664000175000017500000011540214752215315015054 /* % Copyright (C) 2005-2020 Alois Schloegl % This file is part of the "BioSig for C/C++" repository % (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. */ /* Internal definitions (external API is defined in biosig.h) */ /****************************************************************************/ /** **/ /** CONSTANTS and Global variables **/ /** **/ /****************************************************************************/ #ifndef __BIOSIG_INTERNAL_H__ #define __BIOSIG_INTERNAL_H__ #include #include #include #if defined(__MINGW32__) #include #endif #include #include "physicalunits.h" #ifdef __cplusplus extern "C" { #endif #ifdef NDEBUG #define VERBOSE_LEVEL 0 // turn off debugging information, but its only used without NDEBUG #else extern int VERBOSE_LEVEL; // used for debugging, variable is always defined #endif /* Including ZLIB enables reading gzipped files (they are decompressed on-the-fly) The output files can be zipped, too. */ #ifdef HAVE_ZLIB #include #ifndef ZLIB_H #if defined(__MINGW64__) #include "win64/zlib/zlib.h" #elif defined(__MINGW32__) #include "win32/zlib/include/zlib.h" #endif #endif #endif #ifdef HAVE_CHOLMOD #ifdef __APPLE__ #include #else #include #endif #endif #ifdef HAVE_HDF5 #include #endif #ifdef WITH_NIFTI #include #endif #ifdef WITH_GSL #include #endif #ifdef __WIN32__ #define FILESEP '\\' char *getlogin (void); #else #define FILESEP '/' #endif /* test whether HDR.CHANNEL[].{bi,bi8} can be replaced, reduction of header size by about 3% currently this is not working, because FAMOS seems to need it. //#define NO_BI */ /* External API definitions - this was part of old biosig.h */ // #include "biosig.h" /****************************************************************************/ /** **/ /** DEFINITIONS, TYPEDEFS AND MACROS **/ /** **/ /****************************************************************************/ #define BIOSIG_VERSION_MAJOR 3 #define BIOSIG_VERSION_MINOR 0 #define BIOSIG_PATCHLEVEL 2 // for backward compatibility #define BIOSIG_VERSION_STEPPING BIOSIG_PATCHLEVEL #define BIOSIG_VERSION (BIOSIG_VERSION_MAJOR * 10000 + BIOSIG_VERSION_MINOR * 100 + BIOSIG_PATCHLEVEL) // biosigCHECK_VERSION returns true if BIOSIG_VERSION is at least a.b.c #define biosigCHECK_VERSION(a,b,c) (BIOSIG_VERSION >= ( 10000*(a) + 100*(b) + (c) ) ) #if defined(_MSC_VER) && (_MSC_VER < 1600) #if defined(_WIN64) typedef __int64 ssize_t; typedef unsigned __int64 size_t; #else typedef __int32 ssize_t; typedef unsigned __int32 size_t; #endif typedef unsigned __int64 uint64_t; typedef __int64 int64_t; typedef unsigned __int32 uint32_t; typedef __int32 int32_t; typedef __int16 int16_t; typedef unsigned __int8 uint8_t; typedef __int8 int8_t; #else #include #endif #include "gdftime.h" /* * pack structures to fulfil following requirements: * (1) Matlab v7.3+ requires 8 byte alignment * (2) in order to use mingw-compiled libbiosig with MS' VisualStudio, * the structurs must be packed in a MS compatible way. */ #pragma pack(push, 8) //* this is probably redundant to the #pragma pack(8) statement, its here to do it the gnu way, too. */ #ifdef __GNUC__ #define ATT_ALI __attribute__ ((aligned (8))) #define ATT_DEPREC __attribute__ ((deprecated)) #else #define ATT_ALI #define ATT_DEPREC #endif #if defined(_MINGW32__) || defined(__CYGWIN__) #pragma ms_struct on #define ATT_MSSTRUCT __attribute__ ((ms_struct)) #else #define ATT_MSSTRUCT #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * biosig_data_type data type of internal data format * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ typedef double biosig_data_type; /****************************************************************************/ /** **/ /** CONSTANTS and Global variables **/ /** **/ /****************************************************************************/ /* for error handling */ enum B4C_ERROR { B4C_NO_ERROR=0, B4C_FORMAT_UNKNOWN, B4C_FORMAT_UNSUPPORTED, B4C_CANNOT_OPEN_FILE, B4C_CANNOT_WRITE_FILE, B4C_CANNOT_APPEND_FILE, B4C_INSUFFICIENT_MEMORY, B4C_ENDIAN_PROBLEM, B4C_CRC_ERROR, B4C_DATATYPE_UNSUPPORTED, B4C_SCLOSE_FAILED, B4C_DECOMPRESSION_FAILED, B4C_MEMORY_ALLOCATION_FAILED, B4C_RAWDATA_COLLAPSING_FAILED, B4C_REREF_FAILED, B4C_INCOMPLETE_FILE, B4C_UNSPECIFIC_ERROR, B4C_CHAR_ENCODING_UNSUPPORTED }; #ifdef BIN #undef BIN // needed for biosig4perl #endif #ifdef EVENT #undef EVENT // defined by MS VC++ #endif /* list of file formats */ enum FileFormat { noFile, unknown, ABF, ABF2, ACQ, ACR_NEMA, AIFC, AIFF, AINF, alpha, ARFF, ASCII_IBI, ASCII, AU, ASF, ATES, ATF, AVI, AXG, Axona, BCI2000, BDF, BESA, BIN, BKR, BLSC, BMP, BNI, BSCS, BrainVision, BrainVisionVAmp, BrainVisionMarker, BZ2, CDF, CFS, CFWB, CNT, CTF, DICOM, DEMG, EBS, EDF, EEG1100, EEProbe, EEProbe2, EEProbeAvr, EGI, EGIS, ELF, EMBLA, EMSA, ePrime, ET_MEG, ETG4000, EVENT, EXIF, FAMOS, FEF, FIFF, FITS, FLAC, GDF, GDF1, GIF, GTF, GZIP, HDF, HL7aECG, HEKA, IBW, ISHNE, ITX, JPEG, JSON, Lexicor, Matlab, MFER, MIDI, MIT, MM, MSI, MSVCLIB, MS_LNK, MX, native, NeuroLoggerHEX, NetCDF, NEURON, NEV, NEX1, NIFTI, NUMPY, OGG, OpenXDF, PBMA, PBMN, PDF, PDP, Persyst, PGMA, PGMB, PLEXON, PNG, PNM, POLY5, PPMA, PPMB, PS, RDF, RIFF, SASXPT, SCP_ECG, SIGIF, Sigma, SMA, SMR, SND, SQLite, SPSS, STATA, SVG, SXI, SYNERGY, TDMS, TIFF, TMS32, TMSiLOG, TRC, UNIPRO, VRML, VTK, WAV, WCP, WG1, WinEEG, WMF, XML, XPM, Z, ZIP, ZIP2, RHD2000, RHS2000, IntanCLP, EBNEURO, SigViewerEventsCSV, XDF, EAS, EZ3, ARC, WFT, BiosigDump, LastPlaceHolder, invalid=0xffff }; /****************************************************************************/ /** **/ /** DEFINITIONS, TYPEDEFS AND MACROS **/ /** **/ /****************************************************************************/ typedef int64_t nrec_t; /* type for number of records */ /****************************************************************************/ /** **/ /** TYPEDEFS AND STRUCTURES **/ /** **/ /****************************************************************************/ /* This structure defines the header for each channel (variable header) */ // TODO: change fixed length strings to dynamically allocated strings #define MAX_LENGTH_LABEL 80 // TMS: 40, AXG: 79 #define MAX_LENGTH_TRANSDUCER 80 #if (BIOSIG_VERSION < 10600) #define MAX_LENGTH_PHYSDIM 20 // DEPRECATED - DO NOT USE #else #undef MAX_LENGTH_PHYSDIM #endif #define MAX_LENGTH_PID 80 // length of Patient ID: MFER<65, GDF<67, EDF/BDF<81, etc. #define MAX_LENGTH_RID 80 // length of Recording ID: EDF,GDF,BDF<80, HL7 ? #define MAX_LENGTH_NAME 132 // max length of personal name: MFER<=128, EBS<=33*4 #define MAX_LENGTH_MANUF 128 // max length of manufacturer field: MFER<128 #define MAX_LENGTH_TECHNICIAN 128 // max length of manufacturer field: SCP<41 typedef struct CHANNEL_STRUCT { double PhysMin ATT_ALI; /* physical minimum */ double PhysMax ATT_ALI; /* physical maximum */ double DigMin ATT_ALI; /* digital minimum */ double DigMax ATT_ALI; /* digital maximum */ double Cal ATT_ALI; /* gain factor */ double Off ATT_ALI; /* bias */ char Label[MAX_LENGTH_LABEL+1] ATT_ALI; /* Label of channel */ char OnOff ATT_ALI; /* 0: channel is off, not consider for data output; 1: channel is turned on; 2: channel containing time axis */ uint16_t LeadIdCode ATT_ALI; /* Lead identification code */ char Transducer[MAX_LENGTH_TRANSDUCER+1] ATT_ALI; /* transducer e.g. EEG: Ag-AgCl electrodes */ #ifdef MAX_LENGTH_PHYSDIM char PhysDim[MAX_LENGTH_PHYSDIM+1] ATT_ALI ATT_DEPREC; /* DONOT USE - use PhysDim3(PhysDimCode) instead */ #endif uint16_t PhysDimCode ATT_ALI; /* code for physical dimension - PhysDim3(PhysDimCode) returns corresponding string */ float TOffset ATT_ALI; /* time delay of sampling */ float LowPass ATT_ALI; /* lowpass filter */ float HighPass ATT_ALI; /* high pass */ float Notch ATT_ALI; /* notch filter */ float XYZ[3] ATT_ALI; /* sensor position */ union { /* context specific channel information */ float Impedance ATT_ALI; /* Electrode Impedance in Ohm, defined only if PhysDim = _Volt */ float fZ ATT_ALI; /* ICG probe frequency, defined only if PhysDim = _Ohm */ } ATT_ALI; /* this part should not be used by application programs */ uint8_t* bufptr ATT_ALI; /* pointer to buffer: NRec<=1 and bi,bi8 not used */ uint32_t SPR ATT_ALI; /* samples per record (block) */ uint32_t bi ATT_ALI; /* start byte (byte index) of channel within data block */ uint32_t bi8 ATT_ALI; /* start bit (bit index) of channel within data block */ uint16_t GDFTYP ATT_ALI; /* data type */ } CHANNEL_TYPE ATT_ALI ATT_MSSTRUCT; /* This structure defines the general (fixed) header */ typedef struct HDR_STRUCT { char* FileName ATT_ALI; /* FileName - dynamically allocated, local copy of file name */ union { // workaround for transition to cleaner fieldnames float VERSION; /* GDF version number */ float Version; /* GDF version number */ } ATT_ALI; union { // workaround for transition to cleaner fieldnames enum FileFormat TYPE; /* type of file format */ enum FileFormat Type; /* type of file format */ } ATT_ALI; struct { size_t size[2] ATT_ALI; /* size {rows, columns} of data block */ biosig_data_type* block ATT_ALI; /* data block */ } data ATT_ALI; uint8_t IPaddr[16] ATT_ALI; /* IP address of recording device (if applicable) */ double SampleRate ATT_ALI; /* Sampling rate */ nrec_t NRec ATT_ALI; /* number of records/blocks -1 indicates length is unknown. */ gdf_time T0 ATT_ALI; /* starttime of recording */ uint32_t HeadLen ATT_ALI; /* length of header in bytes */ uint32_t SPR ATT_ALI; /* samples per block (when different sampling rates are used, this is the LCM(CHANNEL[..].SPR) */ uint32_t LOC[4] ATT_ALI; /* location of recording according to RFC1876 */ uint16_t NS ATT_ALI; /* number of channels */ int16_t tzmin ATT_ALI; /* time zone : minutes east of UTC */ #ifdef CHOLMOD_H cholmod_sparse *Calib ATT_ALI; /* re-referencing matrix */ #else void *Calib ATT_ALI; /* re-referencing matrix */ #endif CHANNEL_TYPE *rerefCHANNEL ATT_ALI; /* Patient specific information */ struct { gdf_time Birthday; /* Birthday of Patient */ // Age; // the age is HDR.T0 - HDR.Patient.Birthday, even if T0 and Birthday are not known uint16_t Headsize[3]; /* circumference, nasion-inion, left-right mastoid in millimeter; */ /* Patient Name: * can consist of up to three components, separated by the unit separator ascii(31), 0x1f, containing in that order Last name, first name, second last name (see also SCP-ECG specification EN1064, Section 1, tag 0, 1, and 3) * for privacy protection this field is by default not supported, support can be turned on with FLAG.ANONYMOUS */ char Name[MAX_LENGTH_NAME+1]; char Id[MAX_LENGTH_PID+1]; /* patient identification, identification code as used in hospital */ uint8_t Weight; /* weight in kilograms [kg] 0:unkown, 255: overflow */ uint8_t Height; /* height in centimeter [cm] 0:unkown, 255: overflow */ // BMI; // the body-mass index = weight[kg]/height[m]^2 /* Patient classification */ int8_t Sex; /* 0:Unknown, 1: Male, 2: Female */ int8_t Handedness; /* 0:Unknown, 1: Right, 2: Left, 3: Equal */ int8_t Smoking; /* 0:Unknown, 1: NO, 2: YES */ int8_t AlcoholAbuse; /* 0:Unknown, 1: NO, 2: YES */ int8_t DrugAbuse; /* 0:Unknown, 1: NO, 2: YES */ int8_t Medication; /* 0:Unknown, 1: NO, 2: YES */ struct { int8_t Visual; /* 0:Unknown, 1: NO, 2: YES, 3: Corrected */ int8_t Heart; /* 0:Unknown, 1: NO, 2: YES, 3: Pacemaker */ } Impairment; } Patient ATT_ALI; struct { char Recording[MAX_LENGTH_RID+1]; /* HL7, EDF, GDF, BDF replaces HDR.AS.RID */ char* Technician; char* Hospital; /* recording institution */ uint64_t Equipment; /* identifies this software */ struct { /* see SCP: section1, tag14, MFER: tag23: "Manufacturer^model^version number^serial number" */ const char* Name; const char* Model; const char* Version; const char* SerialNumber; char _field[MAX_LENGTH_MANUF+1]; /* buffer */ } Manufacturer; } ID ATT_ALI; /* position of electrodes; see also HDR.CHANNEL[k].XYZ */ struct { float REF[3]; /* XYZ position of reference electrode */ float GND[3]; /* XYZ position of ground electrode */ } ELEC ATT_ALI; /* EVENTTABLE */ struct { double SampleRate ATT_ALI; /* for converting POS and DUR into seconds */ uint16_t *TYP ATT_ALI; /* defined at http://biosig.svn.sourceforge.net/viewvc/biosig/trunk/biosig/doc/eventcodes.txt */ uint32_t *POS ATT_ALI; /* starting position [in samples] using a 0-based indexing */ uint32_t *DUR ATT_ALI; /* duration [in samples] */ uint16_t *CHN ATT_ALI; /* channel number; 0: all channels */ #if (BIOSIG_VERSION >= 10500) gdf_time *TimeStamp ATT_ALI; /* store time stamps */ #endif const char* *CodeDesc ATT_ALI; /* describtion of "free text"/"user specific" events (encoded with TYP=0..255 */ uint32_t N ATT_ALI; /* number of events */ uint16_t LenCodeDesc ATT_ALI; /* length of CodeDesc Table */ } EVENT ATT_ALI; struct { /* flags */ char OVERFLOWDETECTION; /* overflow & saturation detection 0: OFF, !=0 ON */ char UCAL; /* UnCalibration 0: scaling !=0: NO scaling - raw data return */ char ANONYMOUS; /* 1: anonymous mode, no personal names are processed */ char ROW_BASED_CHANNELS; /* 0: column-based data [default]; 1: row-based data */ char TARGETSEGMENT; /* in multi-segment files (like Nihon-Khoden, EEG1100), it is used to select a segment */ } FLAG ATT_ALI; CHANNEL_TYPE *CHANNEL ATT_ALI; // moving CHANNEL after the next struct (HDR.FILE) gives problems at AMD64 MEX-file. // perhaps some alignment problem. struct { /* File specific data */ #ifdef ZLIB_H gzFile gzFID; #else void* gzFID; #endif #ifdef _BZLIB_H // BZFILE* bzFID; #endif FILE* FID; /* file handle */ size_t size; /* size of file - experimental: only partly supported */ size_t POS; /* current reading/writing position [in blocks] */ //size_t POS2; // current reading/writing position [in samples] */ int Des; /* file descriptor */ int DES; /* descriptor for streams */ uint8_t OPEN; /* 0: closed, 1:read, 2: write */ uint8_t LittleEndian; /* 1 if file is LittleEndian data format and 0 for big endian data format*/ uint8_t COMPRESSION; /* 0: no compression 9: best compression */ } FILE ATT_ALI; /* internal variables (not public) */ struct { const char* B4C_ERRMSG; /* error message */ // char PID[MAX_LENGTH_PID+1]; // use HDR.Patient.Id instead // char* RID; // recording identification uint32_t bpb; /* total bytes per block */ uint32_t bpb8; /* total bits per block */ uint8_t* Header; uint8_t* rawEventData; uint8_t* rawdata; /* raw data block */ size_t first; /* first block loaded in buffer - this is equivalent to hdr->FILE.POS */ size_t length; /* number of block(s) loaded in buffer */ uint8_t* auxBUF; /* auxillary buffer - used for storing EVENT.CodeDesc, MIT FMT infor, alpha:rawdata header */ union { char* bci2000; /* application specific free text field */ char* fpulse; char* stimfit; }; uint32_t SegSel[5]; /* segment selection in a hirachical data formats, e.g. sweeps in HEKA/PatchMaster format */ enum B4C_ERROR B4C_ERRNUM; /* error code */ char flag_collapsed_rawdata; /* 0 if rawdata contain obsolete channels, too. */ } AS ATT_ALI; void *aECG; /* used as an pointer to (non-standard) auxilary information - mostly used for hacks */ uint64_t viewtime; /* used by edfbrowser */ #if (BIOSIG_VERSION >= 10500) struct { /* This part contains Section 7-11 of the SCP-ECG format without its 16 byte "Section ID header". These sections are also stored in GDF Header 3 (tag 9-13) It is mostly used for SCP<->GDF conversion. The pointers points into hdr->AS.Header, so do not dynamically re-allocate the pointers. */ const uint8_t* Section7; const uint8_t* Section8; const uint8_t* Section9; const uint8_t* Section10; const uint8_t* Section11; uint32_t Section7Length; uint32_t Section8Length; uint32_t Section9Length; uint32_t Section10Length; uint32_t Section11Length; } SCP; #endif } HDRTYPE ATT_MSSTRUCT; /* This structure defines codes and groups of the event table */ // Desription of event codes struct etd_t { uint16_t typ; // used in HDR.EVENT.TYP uint16_t groupid; // defines the group id as used in EventCodeGroups below const char* desc; // name/description of event code // const decrease signifitiantly number of warning } ATT_MSSTRUCT; // Groups of event codes struct event_groups_t { uint16_t groupid; const char* GroupDescription; // const decrease signifitiantly number of warning } ATT_MSSTRUCT; struct FileFormatStringTable_t { enum FileFormat fmt; const char* FileTypeString; } ATT_MSSTRUCT; struct NomenclatureAnnotatedECG_t { uint16_t part; uint16_t code10; uint32_t cf_code10; const char *refid; } ATT_MSSTRUCT; extern const struct etd_t ETD [] __attribute__ ((visibility ("default") )); extern const struct event_groups_t EventCodeGroups [] __attribute__ ((visibility ("default") )); extern const struct FileFormatStringTable_t FileFormatStringTable []; typedef struct { const char *free_text_event_limiter; } biosig_options_type; HDRTYPE* sopen_extended(const char* FileName, const char* MODE, HDRTYPE* hdr, biosig_options_type* options) __attribute__ ((visibility ("default") )); /* reset structure packing to default settings */ #pragma pack(pop) #if defined(_MINGW32__) || defined(__CYGWIN__) #pragma ms_struct reset #endif #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #if 0 #elif defined(__linux__) # include # include #elif defined(__FreeBSD__) # include #elif defined(__GLIBC__) // for Hurd # include # include #elif defined(__CYGWIN__) # include # include #elif defined(__WIN32__) || defined(_WIN32) # include # define __BIG_ENDIAN 4321 # define __LITTLE_ENDIAN 1234 # define __BYTE_ORDER __LITTLE_ENDIAN # define bswap_16(x) __builtin_bswap16(x) # define bswap_32(x) __builtin_bswap32(x) # define bswap_64(x) __builtin_bswap64(x) # include # if defined(__MINGW32__) # include # endif # if BYTE_ORDER == LITTLE_ENDIAN # define htobe16(x) htons(x) # define htole16(x) (x) # define be16toh(x) ntohs(x) # define le16toh(x) (x) # define htobe32(x) htonl(x) # define htole32(x) (x) # define be32toh(x) ntohl(x) # define le32toh(x) (x) # define htole64(x) (x) # if defined(__MINGW32__) # define htobe64(x) __builtin_bswap64(x) # define be64toh(x) __builtin_bswap64(x) # else # define ntohll(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) | (unsigned int)ntohl(((int)(x >> 32)))) # define htonll(x) ntohll(x) # define htobe64(x) htonll(x) # define be64toh(x) ntohll(x) # endif # define le64toh(x) (x) # elif BYTE_ORDER == BIG_ENDIAN /* that would be xbox 360 */ # define htobe16(x) (x) # define htole16(x) __builtin_bswap16(x) # define be16toh(x) (x) # define le16toh(x) __builtin_bswap16(x) # define htobe32(x) (x) # define htole32(x) __builtin_bswap32(x) # define be32toh(x) (x) # define le32toh(x) __builtin_bswap32(x) # define htobe64(x) (x) # define htole64(x) __builtin_bswap64(x) # define be64toh(x) (x) # define le64toh(x) __builtin_bswap64(x) # else # error byte order not supported # endif #elif defined(__NetBSD__) # include # define __BIG_ENDIAN _BIG_ENDIAN # define __LITTLE_ENDIAN _LITTLE_ENDIAN # define __BYTE_ORDER _BYTE_ORDER # define bswap_16(x) bswap16(x) # define bswap_32(x) bswap32(x) # define bswap_64(x) bswap64(x) #elif defined(__APPLE__) # define __BIG_ENDIAN 4321 # define __LITTLE_ENDIAN 1234 #if (defined(__LITTLE_ENDIAN__) && (__LITTLE_ENDIAN__ == 1)) #define __BYTE_ORDER __LITTLE_ENDIAN #else #define __BYTE_ORDER __BIG_ENDIAN #endif # include # define bswap_16 OSSwapInt16 # define bswap_32 OSSwapInt32 # define bswap_64 OSSwapInt64 # define htobe16(x) OSSwapHostToBigInt16(x) # define htole16(x) OSSwapHostToLittleInt16(x) # define be16toh(x) OSSwapBigToHostInt16(x) # define le16toh(x) OSSwapLittleToHostInt16(x) # define htobe32(x) OSSwapHostToBigInt32(x) # define htole32(x) OSSwapHostToLittleInt32(x) # define be32toh(x) OSSwapBigToHostInt32(x) # define le32toh(x) OSSwapLittleToHostInt32(x) # define htobe64(x) OSSwapHostToBigInt64(x) # define htole64(x) OSSwapHostToLittleInt64(x) # define be64toh(x) OSSwapBigToHostInt64(x) # define le64toh(x) OSSwapLittleToHostInt64(x) #elif defined(__OpenBSD__) # include # define bswap_16 __swap16 # define bswap_32 __swap32 # define bswap_64 __swap64 #elif defined(__NetBSD__) || defined(__DragonFly__) # include # define be16toh(x) betoh16(x) # define le16toh(x) letoh16(x) # define be32toh(x) betoh32(x) # define le32toh(x) letoh32(x) # define be64toh(x) betoh64(x) # define le64toh(x) letoh64(x) #elif (defined(BSD) && (BSD >= 199103)) && !defined(__GLIBC__) # include # define __BIG_ENDIAN _BIG_ENDIAN # define __LITTLE_ENDIAN _LITTLE_ENDIAN # define __BYTE_ORDER _BYTE_ORDER # define bswap_16(x) __bswap16(x) # define bswap_32(x) __bswap32(x) # define bswap_64(x) __bswap64(x) #elif defined(__GNUC__) /* use byteswap macros from the host system, hopefully optimized ones ;-) */ # include # include # define bswap_16(x) __bswap_16 (x) # define bswap_32(x) __bswap_32 (x) # define bswap_64(x) __bswap_64 (x) #elif defined(__sparc__) # define __BIG_ENDIAN 4321 # define __LITTLE_ENDIAN 1234 # define __BYTE_ORDER __BIG_ENDIAN #else # error Unknown platform #endif #if defined(__sparc__) # ifndef bswap_16 # define bswap_16(x) \ ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8)) # endif # ifndef bswap_32 # define bswap_32(x) \ ((((x) & 0xff000000) >> 24) \ | (((x) & 0x00ff0000) >> 8) \ | (((x) & 0x0000ff00) << 8) \ | (((x) & 0x000000ff) << 24)) # endif # ifndef bswap_64 # define bswap_64(x) \ ((((x) & 0xff00000000000000ull) >> 56) \ | (((x) & 0x00ff000000000000ull) >> 40) \ | (((x) & 0x0000ff0000000000ull) >> 24) \ | (((x) & 0x000000ff00000000ull) >> 8) \ | (((x) & 0x00000000ff000000ull) << 8) \ | (((x) & 0x0000000000ff0000ull) << 24) \ | (((x) & 0x000000000000ff00ull) << 40) \ | (((x) & 0x00000000000000ffull) << 56)) # endif #endif #if !defined(__BIG_ENDIAN) && !defined(__LITTLE_ENDIAN) #error ENDIANITY is not known #endif static inline uint16_t leu16p(const void* i) { uint16_t a; memcpy(&a, i, sizeof(a)); return (le16toh(a)); } static inline int16_t lei16p(const void* i) { uint16_t a; memcpy(&a, i, sizeof(a)); return ((int16_t)le16toh(a)); } static inline uint32_t leu32p(const void* i) { uint32_t a; memcpy(&a, i, sizeof(a)); return (le32toh(a)); } static inline int32_t lei32p(const void* i) { uint32_t a; memcpy(&a, i, sizeof(a)); return ((int32_t)le32toh(a)); } static inline uint64_t leu64p(const void* i) { uint64_t a; memcpy(&a, i, sizeof(a)); return (le64toh(a)); } static inline int64_t lei64p(const void* i) { uint64_t a; memcpy(&a, i, sizeof(a)); return ((int64_t)le64toh(a)); } static inline uint16_t beu16p(const void* i) { uint16_t a; memcpy(&a, i, sizeof(a)); return ((int16_t)be16toh(a)); } static inline int16_t bei16p(const void* i) { uint16_t a; memcpy(&a, i, sizeof(a)); return ((int16_t)be16toh(a)); } static inline uint32_t beu32p(const void* i) { uint32_t a; memcpy(&a, i, sizeof(a)); return (be32toh(a)); } static inline int32_t bei32p(const void* i) { uint32_t a; memcpy(&a, i, sizeof(a)); return ((int32_t)be32toh(a)); } static inline uint64_t beu64p(const void* i) { uint64_t a; memcpy(&a, i, sizeof(a)); return ((int64_t)be64toh(a)); } static inline int64_t bei64p(const void* i) { uint64_t a; memcpy(&a, i, sizeof(a)); return ((int64_t)be64toh(a)); } static inline void leu16a(uint16_t i, void* r) { i = htole16(i); memcpy(r, &i, sizeof(i)); } static inline void lei16a( int16_t i, void* r) { i = htole16(i); memcpy(r, &i, sizeof(i)); } static inline void leu32a(uint32_t i, void* r) { i = htole32(i); memcpy(r, &i, sizeof(i)); } static inline void lei32a( int32_t i, void* r) { i = htole32(i); memcpy(r, &i, sizeof(i)); } static inline void leu64a(uint64_t i, void* r) { i = htole64(i); memcpy(r, &i, sizeof(i)); } static inline void lei64a( int64_t i, void* r) { i = htole64(i); memcpy(r, &i, sizeof(i)); } static inline void beu16a(uint16_t i, void* r) { i = htobe16(i); memcpy(r, &i, sizeof(i)); }; static inline void bei16a( int16_t i, void* r) { i = htobe16(i); memcpy(r, &i, sizeof(i)); } static inline void beu32a(uint32_t i, void* r) { i = htobe32(i); memcpy(r, &i, sizeof(i)); } static inline void bei32a( int32_t i, void* r) { i = htobe32(i); memcpy(r, &i, sizeof(i)); } static inline void beu64a(uint64_t i, void* r) { i = htobe64(i); memcpy(r, &i, sizeof(i)); } static inline void bei64a( int64_t i, void* r) { i = htobe64(i); memcpy(r, &i, sizeof(i)); } static inline float lef32p(const void* i) { // decode little endian float pointer uint32_t o; union { uint32_t i; float r; } c; memcpy(&o,i,4); c.i = le32toh(o); return(c.r); } static inline double lef64p(const void* i) { // decode little endian double pointer uint64_t o=0; union { uint64_t i; double r; } c; memcpy(&o,i,8); c.i = le64toh(o); return(c.r); } static inline float bef32p(const void* i) { // decode little endian float pointer uint32_t o; union { uint32_t i; float r; } c; memcpy(&o,i,4); c.i = be32toh(o); return(c.r); } static inline double bef64p(const void* i) { // decode little endian double pointer uint64_t o=0; union { uint64_t i; double r; } c; memcpy(&o,i,8); c.i = be64toh(o); return(c.r); } static inline void lef32a( float i, void* r) { uint32_t i32; memcpy(&i32, &i, sizeof(i)); i32 = le32toh(i32); memcpy(r, &i32, sizeof(i32)); } static inline void lef64a( double i, void* r) { uint64_t i64; memcpy(&i64, &i, sizeof(i)); i64 = le64toh(i64); memcpy(r, &i64, sizeof(i64)); } static inline void bef32a( float i, void* r) { uint32_t i32; memcpy(&i32, &i, sizeof(i)); i32 = be32toh(i32); memcpy(r, &i32, sizeof(i32)); } static inline void bef64a( double i, void* r) { uint64_t i64; memcpy(&i64, &i, sizeof(i)); i64 = be64toh(i64); memcpy(r, &i64, sizeof(i64)); } #ifndef NAN # define NAN (0.0/0.0) /* used for encoding of missing values */ #endif #ifndef INFINITY # define INFINITY (1.0/0.0) /* positive infinity */ #endif #ifndef isfinite # define isfinite(a) (-INFINITY < (a) && (a) < INFINITY) #endif /* The macro IS_SET() can be used to test for defines in if (IS_SET(...)) { } as well as in #if (IS_SET(...)) #endif http://www.thepowerbase.com/2012/04/latest-release-of-linux-contains-code-developed-via-google-plus/ */ #define macrotest_1 , #define IS_SET(macro) is_set_(macro) #define is_set_(value) is_set__(macrotest_##value) #define is_set__(comma) is_set___(comma 1, 0) #define is_set___(_, v, ...) v /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * global constants and variables * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /****************************************************************************/ /** **/ /** TYPEDEFS AND STRUCTURES **/ /** **/ /****************************************************************************/ /* This structure defines the fields used for "VitalFEF" */ typedef struct asn1 { void *pduType; void *SAS; } ASN1_t; /* This structure defines the fields used for "Annotated ECG" */ typedef struct aecg { char* test; /* test field for annotated ECG */ float diastolicBloodPressure; /* in mmHg */ float systolicBloodPressure; /* in mmHg */ char* MedicationDrugs; char* ReferringPhysician; char* LatestConfirmingPhysician; char* Diagnosis; uint8_t EmergencyLevel; /* 0: routine 1-10: increased emergency level */ float HeartRate; float P_wave[2]; /* start and end */ float QRS_wave[2]; /* start and end */ float T_wave[2]; /* start and end */ float P_QRS_T_axes[3]; /***** SCP only fields *****/ struct { uint8_t HUFFMAN; uint8_t REF_BEAT; uint8_t DIFF; uint8_t BIMODAL; } FLAG; struct { //uint8_t tag14[41],tag15[41]; struct { uint16_t INST_NUMBER; /* tag 14, byte 1-2 */ uint16_t DEPT_NUMBER; /* tag 14, byte 3-4 */ uint16_t DEVICE_ID; /* tag 14, byte 5-6 */ uint8_t DeviceType; /* tag 14, byte 7: 0: Cart, 1: System (or Host) */ uint8_t MANUF_CODE; /* tag 14, byte 8 (MANUF_CODE has to be 255) */ char* MOD_DESC; /* tag 14, byte 9 (MOD_DESC has to be "Cart1") */ uint8_t VERSION; /* tag 14, byte 15 (VERSION has to be 20) */ uint8_t PROT_COMP_LEVEL; /* tag 14, byte 16 (PROT_COMP_LEVEL has to be 0xA0 => level II) */ uint8_t LANG_SUPP_CODE; /* tag 14, byte 17 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) */ uint8_t ECG_CAP_DEV; /* tag 14, byte 18 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) */ uint8_t MAINS_FREQ; /* tag 14, byte 19 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) */ char reserved[22]; /* char[35-19] reserved; */ char* ANAL_PROG_REV_NUM; char* SERIAL_NUMBER_ACQ_DEV; char* ACQ_DEV_SYS_SW_ID; char* ACQ_DEV_SCP_SW; /* tag 14, byte 38 (SCP_IMPL_SW has to be "OpenECG XML-SCP 1.00") */ char* ACQ_DEV_MANUF; /* tag 14, byte 38 (ACQ_DEV_MANUF has to be "Manufacturer") */ } Tag14, Tag15; } Section1; struct { size_t StartPtr; size_t Length; } Section5; struct { size_t StartPtr; size_t Length; } Section6; struct { size_t StartPtr; size_t Length; } Section7; struct { char Confirmed; // 0: original report (not overread); 1:Confirmed report; 2: Overread report (not confirmed) struct tm t; uint8_t NumberOfStatements; char **Statements; } Section8; struct { char* StartPtr; size_t Length; } Section9; struct { size_t StartPtr; size_t Length; } Section10; struct { char Confirmed; // 0: original report (not overread); 1:Confirmed report; 2: Overread report (not confirmed) struct tm t; uint8_t NumberOfStatements; char **Statements; } Section11; struct { size_t StartPtr; size_t Length; } Section12; } aECG_TYPE; /****************************************************************************/ /** **/ /** INTERNAL FUNCTIONS **/ /** **/ /****************************************************************************/ #pragma GCC visibility push(default) /* file access wrapper: use ZLIB (if available) or STDIO */ HDRTYPE* ifopen(HDRTYPE* hdr, const char* mode ); int ifclose(HDRTYPE* hdr); int ifeof(HDRTYPE* hdr); int ifflush(HDRTYPE* hdr); size_t ifread(void* buf, size_t size, size_t nmemb, HDRTYPE* hdr); size_t ifwrite(void* buf, size_t size, size_t nmemb, HDRTYPE* hdr); int ifprintf(HDRTYPE* hdr, const char *format, va_list arg); int ifputc(int c, HDRTYPE* hdr); int ifgetc(HDRTYPE* hdr); char* ifgets(char *str, int n, HDRTYPE* hdr); int ifseek(HDRTYPE* hdr, ssize_t offset, int whence ); ssize_t iftell(HDRTYPE* hdr); int ifgetpos(HDRTYPE* hdr, size_t *pos); int iferror(HDRTYPE* hdr); /* various utility functions */ uint32_t gcd(uint32_t A, uint32_t B); uint32_t lcm(uint32_t A, uint32_t B); #pragma GCC visibility pop extern const uint16_t GDFTYP_BITS[] __attribute__ ((visibility ("default") )) ; extern const char *LEAD_ID_TABLE[]; uint16_t CRCEvaluate(uint8_t* datablock, uint32_t datalength); int16_t CRCCheck(uint8_t* datablock, uint32_t datalength); #if (BIOSIG_VERSION < 10700) // this deprecated since Aug 2013, v1.5.7 #ifndef _WIN32 ATT_DEPREC int strcmpi(const char* str1, const char* str2); // use strcasecmp() instead #endif ATT_DEPREC int strncmpi(const char* str1, const char* str2, size_t n); // use strncasecmp() instead #endif int month_string2int(const char *s); int u32cmp(const void *a, const void *b); void biosigERROR(HDRTYPE *hdr, enum B4C_ERROR errnum, const char *errmsg) __attribute__ ((visibility ("default") )); /* sets the local and the (deprecated) global error variables B4C_ERRNUM and B4C_ERRMSG the global error variables are kept for backwards compatibility. */ /* some important functions used internally, the interface for these functios is a bit clumsy and are therefore not exported to standard user applications. */ void struct2gdfbin(HDRTYPE *hdr) __attribute__ ((visibility ("default") )); int gdfbin2struct(HDRTYPE *hdr) __attribute__ ((visibility ("default") )); /* struct2gdfbin and gdfbin2struct convert between the streamed header information (as in a GDF file or on a network connection) and the header structure HDRTYPE Specifically, the fixed header, the variable hadder and the optional header information (header 1,2 and 3). This incluedes the description of the user-specified events (TYP=1..255), but not the event table itself. ------------------------------------------------------------------------*/ size_t hdrEVT2rawEVT(HDRTYPE *hdr) __attribute__ ((visibility ("default") )); void rawEVT2hdrEVT(HDRTYPE *hdr, size_t length_rawEventTable) __attribute__ ((visibility ("default") )); /* rawEVT2hdrEVT and hdrEVT2rawEVT convert between streamed event table and the structure HDRTYPE.EVENT. ------------------------------------------------------------------------*/ int NumberOfChannels(HDRTYPE *hdr) __attribute__ ((visibility ("default") )); /* returns the number of channels returned by SREAD. This might be different than the number of data channels in the file because of status,event and annotation channels, and because some rereferencing is applied ------------------------------------------------------------------------*/ size_t reallocEventTable(HDRTYPE *hdr, size_t EventN); /* allocate, and resize memory of event table ------------------------------------------------------------------------*/ void FreeGlobalEventCodeTable(void); /* free memory allocated for global event code ------------------------------------------------------------------------*/ size_t sread_raw(size_t START, size_t LEN, HDRTYPE* hdr, char flag, void *buf, size_t bufsize) __attribute__ ((visibility ("default") )); /* sread_raw: LEN data segments are read from file associated with hdr, starting from segment START. If buf==NULL, a sufficient amount of memory is (re-)allocated in hdr->AS.rawdata and the data is copied into hdr->AS.rawdata, and LEN*hdr->AS.bpb bytes are read and stored. If buf points to some memory location of size bufsize, the data is stored in buf, no reallocation of memory is possible, and only the minimum(bufsize, LEN*hdr->AS.bpb) is stored. No Overflowdetection or calibration is applied. The number of successfully read data blocks is returned, this can be smaller than LEN at the end of the file, of when bufsize is not large enough. The data can be "cached", this means that more than the requested number of blocks is available in hdr->AS.rawdata. hdr->AS.first and hdr->AS.length contain the number of the first block and the number of blocks, respectively. --------------------------------------------------------------- */ size_t bpb8_collapsed_rawdata(HDRTYPE *hdr) __attribute__ ((visibility ("default") )); /* bpb8_collapsed_rawdata computes the bits per block when rawdata is collapsed --------------------------------------------------------------- */ HDRTYPE* getfiletype(HDRTYPE* hdr); /* identify file format from header information input: hdr->AS.Header contains header of hdr->HeadLen bytes hdr->TYPE must be unknown, otherwise no FileFormat evaluation is performed output: hdr->TYPE file format hdr->VERSION is defined for some selected formats e.g. ACQ, EDF, BDF, GDF --------------------------------------------------------------- */ const char* GetFileTypeString(enum FileFormat FMT) __attribute__ ((visibility ("default") )); /* returns a string with file format --------------------------------------------------------------- */ enum FileFormat GetFileTypeFromString(const char *) __attribute__ ((visibility ("default") )); /* returns file format from string --------------------------------------------------------------- */ #ifdef __cplusplus } #endif /****************************************************************************/ /** **/ /** EOF **/ /** **/ /****************************************************************************/ #endif /* BIOSIG_INTERNAL_H */ stimfit-0.16.7/src/biosig/biosig4c++/physicalunits.c0000664000175000017500000002202014752215315015707 /* Copyright (C) 2005-2019 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "physicalunits.h" #ifdef HAVE_PTHREAD // This is optional, because so far there are no multi-threaded applications for libbiosig. #include #endif /* physical units are defined in prEN ISO 11073-10101 (Nov 2003) Health Informatics - Point-of-care medical device communications - Part 10101:Nomenclature (ISO/DIS 11073-10101:2003) Table A.6.1: Table of Decimal Factors CEN/TC251/PT40 2001 File Exchange Format for Vital Signs - Annex A Table A.4.1: Table of Decimal Factors const double scale[32] = */ const struct PhysDimIdx { const uint16_t idx; const char* PhysDimDesc; } _physdim[] = { #include "units.i" {0xffff, "end-of-table" }, } ; /* compare strings, accept bit7=1 */ int strcmp8(const char* str1, const char* str2) { unsigned int k=0; int r; r = str1[k] - str2[k]; while (r==0 && str1[k]!='\0' && str2[k]!='\0') { k++; r = str1[k] - str2[k]; } return(r); } const char* PhysDimFactor[] = { "","da","h","k","M","G","T","P", // 0..7 "E","Z","Y","#","#","#","#","#", // 8..15 "d","c","m","u","n","p","f","a", // 16..23 "z","y","#","#","#","#","#","#", // 24..31 "\xB5" //hack for "" = "u" // 32 }; #ifndef NAN # define NAN (0.0/0.0) /* used for encoding of missing values */ #endif double PhysDimScale(uint16_t PhysDimCode) { // converting PhysDimCode -> scaling factor const double scale[] = { 1e+0, 1e+1, 1e+2, 1e+3, 1e+6, 1e+9, 1e+12, 1e+15, // 0..7 1e+18,1e+21,1e+24,NAN, NAN, NAN, NAN, NAN, // 8..15 1e-1, 1e-2, 1e-3, 1e-6, 1e-9, 1e-12, 1e-15, 1e-18, // 16..23 1e-21,1e-24,NAN, NAN, NAN, NAN, NAN, NAN, // 24..31 1e-6 // hack for "" = "u" // 32 }; return (scale[PhysDimCode & 0x001f]); } // DEPRECATED: USE INSTEAD PhysDim3(uint16_t PhysDimCode) __attribute__ ((deprecated)) char* PhysDim(uint16_t PhysDimCode, char *PhysDim) { #define MAX_LENGTH_PHYSDIM 20 // DEPRECATED - DO NOT USE // converting PhysDimCode -> PhysDim uint16_t k=0; size_t l2 = strlen(PhysDimFactor[PhysDimCode & 0x001F]); memcpy(PhysDim,PhysDimFactor[PhysDimCode & 0x001F],l2); PhysDimCode &= ~0x001F; for (k=0; _physdim[k].idx<0xffff; k++) if (PhysDimCode == _physdim[k].idx) { strncpy(PhysDim+l2, _physdim[k].PhysDimDesc, MAX_LENGTH_PHYSDIM+1-l2); PhysDim[MAX_LENGTH_PHYSDIM]='\0'; break; } return(PhysDim); #undef MAX_LENGTH_PHYSDIM } char* PhysDim2(uint16_t PhysDimCode) { // converting PhysDimCode -> PhysDim uint16_t k = 0; uint16_t l2 = strlen(PhysDimFactor[PhysDimCode & 0x001F]); for (k = 0; _physdim[k].idx < 0xffff; k++) if ( (PhysDimCode & ~0x001F) == _physdim[k].idx) { char *PhysDim = (char*)malloc(l2 + 1 + strlen(_physdim[k].PhysDimDesc)); if (PhysDim==NULL) return (NULL); memcpy(PhysDim, PhysDimFactor[PhysDimCode & 0x001F], l2); strcpy(PhysDim+l2, _physdim[k].PhysDimDesc); return(PhysDim); } return(NULL); } uint16_t PhysDimCode(const char* PhysDim0) { // converting PhysDim -> PhysDimCode /* converts Physical dimension into 16 bit code */ uint16_t k1, k2; char s[80]; char *s1; if (PhysDim0==NULL) return(0); while (isspace(*PhysDim0)) PhysDim0++; // remove leading whitespace if (strlen(PhysDim0)==0) return(0); // greedy search - check all codes 0..65535 for (k1=0; k1<33; k1++) if (strncmp(PhysDimFactor[k1],PhysDim0,strlen(PhysDimFactor[k1]))==0 && (PhysDimScale(k1)>0.0)) { // exclude if beginning of PhysDim0 differs from PhysDimFactor and if NAN strncpy(s, PhysDimFactor[k1],3); s1 = s+strlen(s); for (k2=0; _physdim[k2].idx < 0xffff; k2++) { strncpy(s1, _physdim[k2].PhysDimDesc, 77); if (strcmp8(PhysDim0, s)==0) { if (k1==32) k1 = 19; // hack for "µ" = "u" return(_physdim[k2].idx+k1); } } } return(0); } /*------------------------------------------------------------------------ * Table of Physical Units * * This part can be better optimized with a more sophisticated hash table * PhysDimTable depends only on constants, defined in units.csv/units.i; however, the table is only initialized upon usage. * These functions are thread safe except for the call to PhysDim2 which updates the table (it does a malloc). Everything else is just read operation, and the content is defined only by PhysDimFactor and PhysDimIdx, which are constant. * The implementation does not seem straightforward, but it should be faster to store already computed strings in a table, rather then recomputing them, again and again. *------------------------------------------------------------------------*/ #define PHYS_DIM_TABLE_SIZE 0x10000 static char *PhysDimTable[PHYS_DIM_TABLE_SIZE]; static char FlagInit_PhysDimTable = 0; #ifdef _PTHREAD_H pthread_mutex_t mutexPhysDimTable = PTHREAD_MUTEX_INITIALIZER; #endif /***** Release allocated memory *****/ void ClearPhysDimTable(void) { #ifdef _PTHREAD_H pthread_mutex_lock(&mutexPhysDimTable); #endif unsigned k = 0; while (k < PHYS_DIM_TABLE_SIZE) { char *o = PhysDimTable[k++]; if (o != NULL) free(o); } FlagInit_PhysDimTable = 0; #ifdef _PTHREAD_H pthread_mutex_unlock(&mutexPhysDimTable); #endif } /***** PhysDim3 returns the text representation of the provided 16bit code *****/ const char* PhysDim3(uint16_t PhysDimCode) { #ifdef _PTHREAD_H pthread_mutex_lock(&mutexPhysDimTable); #endif if (!FlagInit_PhysDimTable) { memset(PhysDimTable, 0, PHYS_DIM_TABLE_SIZE * sizeof(char*)); atexit(&ClearPhysDimTable); FlagInit_PhysDimTable = 1; } char **o = PhysDimTable+PhysDimCode; if (*o==NULL) *o = PhysDim2(PhysDimCode); #ifdef _PTHREAD_H pthread_mutex_unlock(&mutexPhysDimTable); #endif return( (const char*) *o); } /****************************************************************************/ /** **/ /** EOF **/ /** **/ /****************************************************************************/ #ifdef TEST_PHYSDIMTABLE_PERFORMANCE /*********************************** this is just for testing and is not part of the library ***********************************/ #include #include int main() { int k; char *s = NULL; struct rusage t[6]; struct timeval r[3]; /* #define PhysDim3(k) (PhysDim3(4275)) #define PhysDim2(k) (PhysDim2(4275)) */ int c[6]; memset(c,0,sizeof(c)); getrusage(RUSAGE_SELF, &t[0]); // initialize PhysDimTable for (k=0; k<0x10000; k++) c[0] += (PhysDim3(k)!=NULL); getrusage(RUSAGE_SELF, &t[1]); // recall PhysDimTable - many entries are Null, triggering a call to PhysDim2 for (k=0; k<0x10000; k++) c[1] += (PhysDim3(k)!=NULL); getrusage(RUSAGE_SELF, &t[2]); // recall PhysDimTable with a fixed code for (k=0; k<0x10000; k++) c[2] += (PhysDim3(4275)!=NULL); getrusage(RUSAGE_SELF, &t[3]); // trivial implementation PhysDimTable for (k=0; k<0x10000; k++) { s = PhysDim2(k); if (s!=NULL) { free(s); c[3]++; } } getrusage(RUSAGE_SELF, &t[4]); // trivial implementation PhysDimTable for a fixed code for (k=0; k<0x10000; k++) { s = PhysDim2(4275); if (s!=NULL) { free(s); c[4]++; } } getrusage(RUSAGE_SELF, &t[5]); // trivial implementation PhysDimTable for (k=0; k<0x10000; k++) { if ( (k & ~0x001f)==65408) continue; // exclude user-defined code for Bel, because it was later added in the standard s = (char*)PhysDim3(k); int m = PhysDimCode(s); c[5] += (m==k); if ((m!=k) && (s!=NULL) && (s[0]!='#')) { fprintf(stdout,"%s\t%d\t%d\t%s\n",PhysDimFactor[k & 0x1f],k,m,s); } } for (k=0; k<6; k++) { //fprintf(stdout,"=== [%i]: %d.%06d\t%d.%06d\n",k, t[k].ru_utime.tv_sec,t[k].ru_utime.tv_usec,t[k].ru_stime.tv_sec,t[k].ru_stime.tv_usec); if (!k) continue; timersub(&(t[k].ru_utime), &(t[k-1].ru_utime), &r[0]); fprintf(stdout,"usr [%i]: %d.%06d\t",k, r[0].tv_sec,r[0].tv_usec); timersub(&(t[k].ru_stime), &(t[k-1].ru_stime) ,&r[1]); fprintf(stdout,"sys [%i]: %d.%06d\t",k, r[1].tv_sec,r[1].tv_usec); timeradd(&r[0],&r[1],&r[2]); fprintf(stdout,"tot [%i]: %d.%06d\t%i\n",k,r[2].tv_sec,r[2].tv_usec,c[k-1]); } return 0; } #endif stimfit-0.16.7/src/biosig/biosig4c++/gdftime.h0000664000175000017500000001204514752215315014442 /* % Copyright (C) 2005-2013,2020 Alois Schloegl % This file is part of the "BioSig for C/C++" repository % (biosig4c++/libbiosig) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /****************************************************************************/ /** **/ /** DEFINITIONS, TYPEDEFS AND MACROS **/ /** **/ /****************************************************************************/ #ifndef __GDFTIME_H__ #define __GDFTIME_H__ #if defined(_MSC_VER) && (_MSC_VER < 1600) typedef __int64 int64_t; #else #include #endif #include #include #include /* ensure that definition of "byte" does not conflict between rpcndr.h (Windows/mingw only) and bits/cpp_type_traits.h under g++ see also https://github.com/mxe/mxe/issues/2759 */ #define _GLIBCXX_INCLUDE_NEXT_C_HEADERS #include #undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS #ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Conversion of time formats between Unix and GDF format. The default time format in BIOSIG uses a 64-bit fixed point format with reference date 01-Jan-0000 00h00m00s (value=0). One unit indicates the 2^(-32) part of 1 day (ca 20 us). Accordingly, the higher 32 bits count the number of days, the lower 32 bits describe the fraction of a day. 01-Jan-1970 is the day 719529. time_t t0; t0 = time(NULL); T0 = (double)t0/86400.0; // convert seconds in days since 1970-Jan-01 floor(T0) + 719529; // number of days since 01-Jan-0000 floor(ldexp(T0-floor(T0),32)); // fraction x/2^32; one day is 2^32 The following macros define the conversions between the unix time and the GDF format. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ typedef int64_t gdf_time, gdftime_t; /* gdf time is represented in 64 bits */ #define t_time2gdf_time(t) ((gdf_time)floor(ldexp(((double)(t))/86400.0 + 719529.0, 32))) #define gdf_time2t_time(t) ((ldexp(((double)(t)),-32) - 719529.0)*86400.0) #define ntp_time2gdf_time(t) ((gdf_time)ldexp(ldexp(((double)(t)),-32)/86400 + 719529.0 - 70,32)) #define gdf_time2ntp_time(t) ((int64_t)ldexp((ldexp(((double)(t)),-32) - 719529.0 + 70) * 86400,32)) #pragma GCC visibility push(default) #ifdef __cplusplus EXTERN_C { #endif /* * converts struct tm into gdf_time format */ gdftime_t tm_time2gdf_time(struct tm *t); /* * gdf_time2tm_time converts gdf-time into struct tm format, this is deprecated because time resolution (sub-seconds) are lost */ struct tm *gdf_time2tm_time(gdftime_t t); /* * re-entrant version of gdf_time2tm_time, memory for t must be allocated this is deprecated because time resolution (sub-seconds) are lost */ int gdf_time2tm_time_r(gdftime_t t, struct tm *tm); /* converts date and time to strings using this format %Y-%m-%d %H:%M:%S with microsecond resolution, if needed. %04d-%02d-%02d %02d:%02d:%02d %04d-%02d-%02d %02d:%02d:%09.6f strfgdftime resembles strftime(...), except for format %s and %S which will also present 6 digits the fraction of the second */ size_t snprintf_gdftime(char *out, size_t outbytesleft, gdftime_t T); size_t snprintf_gdfdate(char *out, size_t outbytesleft, gdftime_t T); size_t snprintf_gdfdatetime(char *out, size_t outbytesleft, gdftime_t T); size_t strfgdftime(char *out, size_t outbytesleft, const char *FMT, gdftime_t T); /* gdftime_t string2gdftime(const char*) gdftime_t string2gdfdate(const char*) gdftime_t string2gdfdatetime(const char*) gdftime_t time2gdftime(int,int,float) gdftime_t date2gdftime(int,int,int) gdftime_t datetime2gdftime(int,int,int,int,int,float) void gdftime2datetime(&int,&int,&int,&int,&int,&float) void gdftime2time(&int,&int,&float) void gdftime2date(&int,&int,&int) */ #ifdef __cplusplus } #endif #pragma GCC visibility pop /****************************************************************************/ /** **/ /** EOF **/ /** **/ /****************************************************************************/ #endif /* __BIOSIG_EXT_H__ */ stimfit-0.16.7/src/biosig/biosig4c++/biosig.c0000664000175000017500000172651714752215315014313 /* Copyright (C) 2005-2021 Alois Schloegl Copyright (C) 2011 Stoyan Mihaylov This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Library function for reading and writing of varios biosignal data formats. It provides also one reference implementation for reading and writing of the GDF data format [1]. Features: - reading and writing of EDF, BDF, GDF1, GDF2, CWFB, HL7aECG, SCP files - reading of ACQ, AINF, BKR, BrainVision, CNT, DEMG, EGI, ETG4000, MFER files The full list of supported formats is shown at http://pub.ist.ac.at/~schloegl/biosig/TESTED implemented functions: - SOPEN, SREAD, SWRITE, SCLOSE, SEOF, SSEEK, STELL, SREWIND References: [1] GDF - A general data format for biomedical signals. available online http://arxiv.org/abs/cs.DB/0608052 */ /* TODO: ensure that hdr->CHANNEL[.].TOffset gets initialized after every alloc() */ #define _GNU_SOURCE #include #include #include #include #include #include // define macro isnan() #include #include #ifdef _WIN32 // Can't include sys/stat.h or sopen is declared twice. #include struct stat { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; _dev_t st_rdev; _off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; }; int __cdecl stat(const char *_Filename,struct stat *_Stat); #else #include #endif #ifdef WITH_CURL # include #endif int VERBOSE_LEVEL __attribute__ ((visibility ("default") )) = 0; // this variable is always available, but only used without NDEBUG #include "biosig.h" #include "biosig-network.h" #ifdef _WIN32 #include #include #define FILESEP '\\' #else #include #include /* sockaddr_in and sockaddr_in6 definitions. */ #include #include #define FILESEP '/' #endif #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) char* getlogin (void); char* xgethostname (void); /*----------------------------------------------------------------------- error handling should use error variables local to each HDR otherwise, sopen() etc. is not re-entrant. Therefore, use of variables B4C_ERRNUM and B4C_ERRMSG is deprecated; Use instead serror2(hdr), hdr->AS.B4C_ERRNUM, hdr->AS.B4C_ERRMSG. ----------------------------------------------------------------------- */ // do not expose deprecated interface in libgdf #ifndef ONLYGDF ATT_DEPREC int B4C_ERRNUM = 0; ATT_DEPREC const char *B4C_ERRMSG; #endif #ifdef HAVE_CHOLMOD cholmod_common CHOLMOD_COMMON_VAR; void CSstop() { cholmod_finish(&CHOLMOD_COMMON_VAR); } void CSstart () { cholmod_start (&CHOLMOD_COMMON_VAR) ; /* start CHOLMOD */ atexit (&CSstop) ; } #endif #ifndef ONLYGDF #ifdef __cplusplus extern "C" { #endif int sopen_SCP_read (HDRTYPE* hdr); int sopen_SCP_write (HDRTYPE* hdr); int sopen_HL7aECG_read (HDRTYPE* hdr); void sopen_HL7aECG_write(HDRTYPE* hdr); void sopen_abf_read (HDRTYPE* hdr); void sopen_abf2_read (HDRTYPE* hdr); void sopen_axg_read (HDRTYPE* hdr); void sopen_alpha_read (HDRTYPE* hdr); void sopen_cadwell_read(HDRTYPE* hdr); void sopen_biosigdump_read (HDRTYPE* hdr); void sopen_cfs_read (HDRTYPE* hdr); void sopen_FAMOS_read (HDRTYPE* hdr); void sopen_fiff_read (HDRTYPE* hdr); int sclose_HL7aECG_write(HDRTYPE* hdr); void sopen_ibw_read (HDRTYPE* hdr); void sopen_itx_read (HDRTYPE* hdr); void sopen_smr_read (HDRTYPE* hdr); void sopen_rhd2000_read (HDRTYPE* hdr); void sopen_rhs2000_read (HDRTYPE* hdr); void sopen_intan_clp_read (HDRTYPE* hdr); #ifdef WITH_TDMS void sopen_tdms_read (HDRTYPE* hdr); #endif int sopen_trc_read (HDRTYPE* hdr); int sopen_unipro_read (HDRTYPE* hdr); #ifdef WITH_FEF int sopen_fef_read(HDRTYPE* hdr); int sclose_fef_read(HDRTYPE* hdr); #endif void sopen_heka(HDRTYPE* hdr,FILE *fid); int sopen_hdf5 (HDRTYPE *hdr); int sopen_matlab (HDRTYPE *hdr); int sopen_sqlite (HDRTYPE* hdr); #if defined(WITH_DICOM) || defined(WITH_DCMTK) int sopen_dicom_read(HDRTYPE* hdr); #endif void sopen_atf_read(HDRTYPE* hdr); void sread_atf(HDRTYPE* hdr); #ifdef __cplusplus } #endif #endif //ONLYGDF const uint16_t GDFTYP_BITS[] __attribute__ ((visibility ("default") )) = { 8, 8, 8,16,16,32,32,64,64,32,64, 0, 0, 0, 0, 0, /* 0 */ 32,64,128,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 32 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 48 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 64 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128: EEG1100 coder, */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,10, 0,12, 0, 0, 0,16, /* 256 - 271*/ 0, 0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,32, /* 255+24 = bit24, 3 byte */ 0, 0, 0, 0, 0, 0, 0,40, 0, 0, 0, 0, 0, 0, 0,48, 0, 0, 0, 0, 0, 0, 0,56, 0, 0, 0, 0, 0, 0, 0,64, 0, 0, 0, 0, 0, 0, 0,72, 0, 0, 0, 0, 0, 0, 0,80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 384 - 399*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,10, 0,12, 0, 0, 0,16, /* 512 - 527*/ 0, 0, 0, 0, 0, 0, 0,24, 0, 0, 0, 0, 0, 0, 0,32, 0, 0, 0, 0, 0, 0, 0,40, 0, 0, 0, 0, 0, 0, 0,48, 0, 0, 0, 0, 0, 0, 0,56, 0, 0, 0, 0, 0, 0, 0,64, 0, 0, 0, 0, 0, 0, 0,72, 0, 0, 0, 0, 0, 0, 0,80 }; const char *gdftyp_string[] = { "char","int8","uint8","int16","uint16","int32","uint32","int64","uint64", "","","","","","","","float32","float64","float128" }; const char *LEAD_ID_TABLE[] = { "unspecified", "I","II","V1","V2","V3","V4","V5","V6", "V7","V2R","V3R","V4R","V5R","V6R","V7R","X", "Y","Z","CC5","CM5","LA","RA","LL","fI", "fE","fC","fA","fM","fF","fH","dI", "dII","dV1","dV2","dV3","dV4","dV5", "dV6","dV7","dV2R","dV3R","dV4R","dV5R", "dV6R","dV7R","dX","dY","dZ","dCC5","dCM5", "dLA","dRA","dLL","dfI","dfE","dfC","dfA", "dfM","dfF","dfH","III","aVR","aVL","aVF", "aVRneg","V8","V9","V8R","V9R","D","A","J", "Defib","Extern","A1","A2","A3","A4","dV8", "dV9","dV8R","dV9R","dD","dA","dJ","Chest", "V","VR","VL","VF","MCL","MCL1","MCL2","MCL3", "MCL4","MCL5","MCL6","CC","CC1","CC2","CC3", "CC4","CC6","CC7","CM","CM1","CM2","CM3","CM4", "CM6","dIII","daVR","daVL","daVF","daVRneg","dChest", "dV","dVR","dVL","dVF","CM7","CH5","CS5","CB5","CR5", "ML","AB1","AB2","AB3","AB4","ES","AS","AI","S", "dDefib","dExtern","dA1","dA2","dA3","dA4","dMCL1", "dMCL2","dMCL3","dMCL4","dMCL5","dMCL6","RL","CV5RL", "CV6LL","CV6LU","V10","dMCL","dCC","dCC1","dCC2", "dCC3","dCC4","dCC6","dCC7","dCM","dCM1","dCM2", "dCM3","dCM4","dCM6","dCM7","dCH5","dCS5","dCB5", "dCR5","dML","dAB1","dAB2","dAB3","dAB4","dES", "dAS","dAI","dS","dRL","dCV5RL","dCV6LL","dCV6LU","dV10" /* EEG Leads - non consecutive index ,"NZ","FPZ","AFZ","FZ","FCZ","CZ","CPZ","PZ", "POZ","OZ","IZ","FP1","FP2","F1","F2","F3","F4", "F5","F6","F7","F8","F9","F10","FC1","FC2","FC3", "FC4","FC5","FC6","FT7","FT8","FT9","FT10","C1", "C2","C3","C4","C5","C6","CP1","CP2","CP3","CP4", "CP5","CP6","P1","P2","P3","P4","P5","P6","P9", "P10","O1","O2","AF3","AF4","AF7","AF8","PO3", "PO4","PO7","PO8","T3","T7","T4","T8","T5","P7", "T6","P8","T9","T10","TP7","TP8","TP9","TP10", "A1","A2","T1","T2","PG1","PG2","SP1","SP2", "E0","EL1","EL2","EL3","EL4","EL5","EL6","EL7", "ER1","ER2","ER3","ER4","ER5","ER6","ER7","ELL", "ERL","ELA","ELB","ERA","ERB" */ , "\0\0" }; // stop marker #ifndef ONLYGDF /* This information was obtained from here: http://www.physionet.org/physiotools/wfdb/lib/ecgcodes.h */ const char *MIT_EVENT_DESC[] = { "normal beat", "left bundle branch block beat", "right bundle branch block beat", "aberrated atrial premature beat", "premature ventricular contraction", "fusion of ventricular and normal beat", "nodal (junctional) premature beat", "atrial premature contraction", "premature or ectopic supraventricular beat", "ventricular escape beat", "nodal (junctional) escape beat", "paced beat", "unclassifiable beat", "signal quality change", "condition 15", "isolated QRS-like artifact", "condition 17", "ST change", "T-wave change", "systole", "diastole", "comment annotation", "measurement annotation", "P-wave peak", "left or right bundle branch block", "non-conducted pacer spike", "T-wave peak", "rhythm change", "U-wave peak", "learning", "ventricular flutter wave", "start of ventricular flutter/fibrillation", "end of ventricular flutter/fibrillation", "atrial escape beat", "supraventricular escape beat", "link to external data (aux contains URL)", "non-conducted P-wave (blocked APB)", "fusion of paced and normal beat", "PQ junction (beginning of QRS)", "J point (end of QRS)", "R-on-T premature ventricular contraction", "condition 42", "condition 43", "condition 44", "condition 45", "condition 46", "condition 47", "condition 48", "not-QRS (not a getann/putann code)", // code = 0 is mapped to 49(ACMAX) ""}; #endif //ONLYGDF /* --------------------------------------------------- * * Predefined Event Code Table * * --------------------------------------------------- */ #if (BIOSIG_VERSION < 10500) ATT_DEPREC static uint8_t GLOBAL_EVENTCODES_ISLOADED = 0; ATT_DEPREC struct global_t { uint16_t LenCodeDesc; uint16_t *CodeIndex; const char **CodeDesc; char *EventCodesTextBuffer; } Global; // deprecated since Oct 2012, v1.4.0 #endif // event table desription const struct etd_t ETD [] = { #include "eventcodes.i" {0, 0, ""} }; // event groups const struct event_groups_t EventCodeGroups [] = { #include "eventcodegroups.i" {0xffff, "end-of-table" }, }; /****************************************************************************/ /** **/ /** INTERNAL FUNCTIONS **/ /** **/ /****************************************************************************/ // greatest common divisor uint32_t gcd(uint32_t A, uint32_t B) { uint32_t t; if (A0) { t = B; B = A%B; A = t; } return(A); }; // least common multiple - used for obtaining the common HDR.SPR uint32_t lcm(uint32_t A, uint32_t B) { if (A==0 || B==0) { fprintf(stderr,"%s (line %d) %s(%d,%d)\n",__FILE__,__LINE__,__func__,A,B); return 0; } // return(A*(B/gcd(A,B)) with overflow detection uint64_t A64 = A; A64 *= B/gcd(A,B); if (A64 > 0x00000000ffffffffllu) { fprintf(stderr,"Error: HDR.SPR=LCM(%u,%u) overflows and does not fit into uint32.\n",(unsigned)A,(unsigned)B); } return((uint32_t)A64); }; #ifndef ONLYGDF void* mfer_swap8b(uint8_t *buf, int8_t len, char FLAG_SWAP) { if (VERBOSE_LEVEL==9) fprintf(stdout,"swap=%i %i %i \nlen=%i %2x%2x%2x%2x%2x%2x%2x%2x\n", (int)FLAG_SWAP, __BYTE_ORDER, __LITTLE_ENDIAN, (int)len, (unsigned)buf[0],(unsigned)buf[1],(unsigned)buf[2],(unsigned)buf[3], (unsigned)buf[4],(unsigned)buf[5],(unsigned)buf[6],(unsigned)buf[7] ); #ifndef S_SPLINT_S #if __BYTE_ORDER == __BIG_ENDIAN if (FLAG_SWAP) { unsigned k; for (k=len; k < sizeof(uint64_t); buf[k++]=0); *(uint64_t*)buf = bswap_64(*(uint64_t*)buf); } else { *(uint64_t*)buf >>= (sizeof(uint64_t)-len)*8; } #elif __BYTE_ORDER == __LITTLE_ENDIAN if (FLAG_SWAP) { *(uint64_t*)buf = bswap_64(*(uint64_t*)buf) >> (sizeof(uint64_t)-len)*8; } else { unsigned k; for (k=len; k < sizeof(uint64_t); buf[k++]=0) {}; } #endif #endif if (VERBOSE_LEVEL==9) fprintf(stdout,"%2x%2x%2x%2x%2x%2x%2x%2x %i %f\n", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5], buf[6],buf[7],(int)*(uint64_t*)buf,*(double*)buf ); return(buf); } /* -------------------------------- * float to ascii[8] conversion * -------------------------------- */ int ftoa8(char* buf, double num) { // used for converting scaling factors Dig/Phys/Min/Max into EDF header // Important note: buf may need more than len+1 bytes. make sure there is enough memory allocated. double f1,f2; if (num==ceil(num)) sprintf(buf,"%d",(int)num); else sprintf(buf,"%f",num); f1 = atof(buf); buf[8] = 0; // truncate f2 = atof(buf); return (fabs(f1-f2) > (fabs(f1)+fabs(f2)) * 1e-6); } int is_nihonkohden_signature(char *str) { return (!( strncmp(str, "EEG-1200A V01.00", 16) && strncmp(str, "EEG-1100A V01.00", 16) && strncmp(str, "EEG-1100B V01.00", 16) && strncmp(str, "EEG-1100C V01.00", 16) && strncmp(str, "QI-403A V01.00", 16) && strncmp(str, "QI-403A V02.00", 16) && strncmp(str, "EEG-2100 V01.00", 16) && strncmp(str, "EEG-2100 V02.00", 16) && strncmp(str, "DAE-2100D V01.30", 16) && strncmp(str, "DAE-2100D V02.00", 16) )); } #endif //ONLYGDF #if (BIOSIG_VERSION < 10700) int strncmpi(const char* str1, const char* str2, size_t n) { fprintf(stderr,"Warning from libbiosig: use of function strncmpi() is deprecated - use instead strncasecmp()\n"); return strncasecmp(str1,str2,n); } int strcmpi(const char* str1, const char* str2) { fprintf(stderr,"Warning from libbiosig: use of function strcmpi() is deprecated - use instead strcasecmp()\n"); return strcasecmp(str1,str2); } #endif /* Converts name of month int numeric value. */ int month_string2int(const char *s) { const char ListOfMonth[12][4] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"}; int k; for (k = 0; k < 12; k++) if (!strncasecmp(s, ListOfMonth[k], 3)) return k; return -1; } /* compare uint32_t */ int u32cmp(const void *a,const void *b) { return((int)(*(uint32_t*)a - *(uint32_t*)b)); } /* Interface for mixed use of ZLIB and STDIO If ZLIB is not available, STDIO is used. If ZLIB is availabe, HDR.FILE.COMPRESSION tells whether STDIO or ZLIB is used. */ HDRTYPE* ifopen(HDRTYPE* hdr, const char* mode) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) { hdr->FILE.gzFID = gzopen(hdr->FileName, mode); hdr->FILE.OPEN = (hdr->FILE.gzFID != NULL); } else #endif { hdr->FILE.FID = fopen(hdr->FileName, mode); hdr->FILE.OPEN = (hdr->FILE.FID != NULL); } return(hdr); } int ifclose(HDRTYPE* hdr) { hdr->FILE.OPEN = 0; #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzclose(hdr->FILE.gzFID)); else #endif return(fclose(hdr->FILE.FID)); } int ifflush(HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzflush(hdr->FILE.gzFID,Z_FINISH)); else #endif return(fflush(hdr->FILE.FID)); } size_t ifread(void* ptr, size_t size, size_t nmemb, HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION>0) return(gzread(hdr->FILE.gzFID, ptr, size * nmemb)/size); else #endif return(fread(ptr, size, nmemb, hdr->FILE.FID)); } size_t ifwrite(void* ptr, size_t size, size_t nmemb, HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzwrite(hdr->FILE.gzFID, ptr, size*nmemb)/size); else #endif return(fwrite(ptr, size, nmemb, hdr->FILE.FID)); } int ifprintf(HDRTYPE* hdr, const char *format, va_list arg) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzprintf(hdr->FILE.gzFID, format, arg)); else #endif return(fprintf(hdr->FILE.FID, format, arg)); } int ifputc(int c, HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzputc(hdr->FILE.gzFID, c)); else #endif return(fputc(c,hdr->FILE.FID)); } int ifgetc(HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzgetc(hdr->FILE.gzFID)); else #endif return(fgetc(hdr->FILE.FID)); } char* ifgets(char *str, int n, HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzgets(hdr->FILE.gzFID, str, n)); else #endif return(fgets(str,n,hdr->FILE.FID)); } int ifseek(HDRTYPE* hdr, ssize_t offset, int whence) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) { if (whence==SEEK_END) fprintf(stdout,"Warning SEEK_END is not supported but used in gzseek/ifseek.\nThis can cause undefined behaviour.\n"); return(gzseek(hdr->FILE.gzFID,offset,whence)); } else #endif #if defined(__MINGW64__) return(_fseeki64(hdr->FILE.FID,offset,whence)); #else return(fseek(hdr->FILE.FID,offset,whence)); #endif } ssize_t iftell(HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gztell(hdr->FILE.gzFID)); else #endif return(ftell(hdr->FILE.FID)); } int ifsetpos(HDRTYPE* hdr, size_t *pos) { #if __gnu_linux__ // gnu linux on sparc needs this fpos_t p; p.__pos = *pos; #elif __sparc__ || __APPLE__ || __MINGW32__ || ANDROID || __NetBSD__ || __CYGWIN__ || __FreeBSD__ fpos_t p = *pos; #else fpos_t p; p.__pos = *pos; #endif #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) { gzseek(hdr->FILE.gzFID,*pos,SEEK_SET); size_t pos1 = *pos; *pos = gztell(hdr->FILE.gzFID); return(*pos - pos1); } else #endif { int c= fsetpos(hdr->FILE.FID,&p); #if __gnu_linux__ // gnu linux on sparc needs this *pos = p.__pos; #elif __sparc__ || __APPLE__ || __MINGW32__ || ANDROID || __NetBSD__ || __CYGWIN__ || __FreeBSD__ *pos = p; #else *pos = p.__pos; #endif return(c); } } int ifgetpos(HDRTYPE* hdr, size_t *pos) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) { z_off_t p = gztell(hdr->FILE.gzFID); if (p<0) return(-1); else { *pos = p; return(0); } } else #endif { fpos_t p; int c = fgetpos(hdr->FILE.FID, &p); #if __gnu_linux__ // gnu linux on sparc needs this *pos = p.__pos; // ugly hack but working #elif __sparc__ || __APPLE__ || __MINGW32__ || ANDROID || __NetBSD__ || __CYGWIN__ || __FreeBSD__ *pos = p; #else *pos = p.__pos; // ugly hack but working #endif return(c); } } int ifeof(HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) return(gzeof(hdr->FILE.gzFID)); else #endif return(feof(hdr->FILE.FID)); } int iferror(HDRTYPE* hdr) { #ifdef ZLIB_H if (hdr->FILE.COMPRESSION) { int errnum; const char *tmp = gzerror(hdr->FILE.gzFID,&errnum); fprintf(stderr,"GZERROR: %i %s \n",errnum, tmp); return(errnum); } else #endif return(ferror(hdr->FILE.FID)); } /*------------------------------------------------------------------------ sort event table according to EVENT.POS ------------------------------------------------------------------------*/ struct event { uint32_t POS; uint32_t DUR; uint16_t TYP; uint16_t CHN; #if (BIOSIG_VERSION >= 10500) gdf_time TimeStamp; #endif }; int compare_eventpos(const void *e1, const void *e2) { return(((struct event*)(e1))->POS - ((struct event*)(e2))->POS); } void sort_eventtable(HDRTYPE *hdr) { size_t k; struct event *entry = (struct event*) calloc(hdr->EVENT.N, sizeof(struct event)); if ((hdr->EVENT.DUR != NULL) && (hdr->EVENT.CHN != NULL)) for (k=0; k < hdr->EVENT.N; k++) { entry[k].TYP = hdr->EVENT.TYP[k]; entry[k].POS = hdr->EVENT.POS[k]; entry[k].CHN = hdr->EVENT.CHN[k]; entry[k].DUR = hdr->EVENT.DUR[k]; } else for (k=0; k < hdr->EVENT.N; k++) { entry[k].TYP = hdr->EVENT.TYP[k]; entry[k].POS = hdr->EVENT.POS[k]; } #if (BIOSIG_VERSION >= 10500) if (hdr->EVENT.TimeStamp != NULL) for (k=0; k < hdr->EVENT.N; k++) { entry[k].TimeStamp = hdr->EVENT.TimeStamp[k]; } #endif qsort(entry, hdr->EVENT.N, sizeof(struct event), &compare_eventpos); if ((hdr->EVENT.DUR != NULL) && (hdr->EVENT.CHN != NULL)) for (k=0; k < hdr->EVENT.N; k++) { hdr->EVENT.TYP[k] = entry[k].TYP; hdr->EVENT.POS[k] = entry[k].POS; hdr->EVENT.CHN[k] = entry[k].CHN; hdr->EVENT.DUR[k] = entry[k].DUR; } else for (k=0; k < hdr->EVENT.N; k++) { hdr->EVENT.TYP[k] = entry[k].TYP; hdr->EVENT.POS[k] = entry[k].POS; } #if (BIOSIG_VERSION >= 10500) if (hdr->EVENT.TimeStamp != NULL) for (k=0; k < hdr->EVENT.N; k++) { hdr->EVENT.TimeStamp[k] = entry[k].TimeStamp; } #endif free(entry); } /*------------------------------------------------------------------------ re-allocates memory for Eventtable. hdr->EVENT.N contains actual number of events EventN determines the size of the allocated memory return value: in case of success, EVENT_N is returned in case of failure SIZE_MAX is returned; ------------------------------------------------------------------------*/ size_t reallocEventTable(HDRTYPE *hdr, size_t EventN) { size_t n; hdr->EVENT.POS = (uint32_t*)realloc(hdr->EVENT.POS, EventN * sizeof(*hdr->EVENT.POS)); hdr->EVENT.DUR = (uint32_t*)realloc(hdr->EVENT.DUR, EventN * sizeof(*hdr->EVENT.DUR)); hdr->EVENT.TYP = (uint16_t*)realloc(hdr->EVENT.TYP, EventN * sizeof(*hdr->EVENT.TYP)); hdr->EVENT.CHN = (uint16_t*)realloc(hdr->EVENT.CHN, EventN * sizeof(*hdr->EVENT.CHN)); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = (gdf_time*)realloc(hdr->EVENT.TimeStamp, EventN * sizeof(gdf_time)); #endif if (hdr->EVENT.POS==NULL) return SIZE_MAX; if (hdr->EVENT.TYP==NULL) return SIZE_MAX; if (hdr->EVENT.CHN==NULL) return SIZE_MAX; if (hdr->EVENT.DUR==NULL) return SIZE_MAX; if (hdr->EVENT.TimeStamp==NULL) return SIZE_MAX; for (n = hdr->EVENT.N; n< EventN; n++) { hdr->EVENT.TYP[n] = 0; hdr->EVENT.CHN[n] = 0; hdr->EVENT.DUR[n] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[n] = 0; #endif } return EventN; } /*------------------------------------------------------------------------ converts event table from {TYP,POS} to [TYP,POS,CHN,DUR} format ------------------------------------------------------------------------*/ void convert2to4_eventtable(HDRTYPE *hdr) { size_t k1,k2,N=hdr->EVENT.N; sort_eventtable(hdr); if (hdr->EVENT.DUR == NULL) hdr->EVENT.DUR = (typeof(hdr->EVENT.DUR)) calloc(N,sizeof(*hdr->EVENT.DUR)); if (hdr->EVENT.CHN == NULL) hdr->EVENT.CHN = (typeof(hdr->EVENT.CHN)) calloc(N,sizeof(*hdr->EVENT.CHN)); for (k1=0; k1EVENT.TYP) typ = hdr->EVENT.TYP[k1]; if ((typ < 0x8000) && (typ>0) && !hdr->EVENT.DUR[k1]) for (k2 = k1+1; k2EVENT.TYP[k2]) { hdr->EVENT.DUR[k1] = hdr->EVENT.POS[k2] - hdr->EVENT.POS[k1]; hdr->EVENT.TYP[k2] = 0; break; } } } for (k1=0,k2=0; k1EVENT.TYP[k2]=hdr->EVENT.TYP[k1]; hdr->EVENT.POS[k2]=hdr->EVENT.POS[k1]; hdr->EVENT.DUR[k2]=hdr->EVENT.DUR[k1]; hdr->EVENT.CHN[k2]=hdr->EVENT.CHN[k1]; #if (BIOSIG_VERSION >= 10500) if (hdr->EVENT.TimeStamp != NULL) hdr->EVENT.TimeStamp[k2] = hdr->EVENT.TimeStamp[k1]; #endif } if (hdr->EVENT.TYP[k1]) k2++; } hdr->EVENT.N = k2; } /*------------------------------------------------------------------------ converts event table from [TYP,POS,CHN,DUR} to {TYP,POS} format ------------------------------------------------------------------------*/ void convert4to2_eventtable(HDRTYPE *hdr) { size_t k1,k2,N = hdr->EVENT.N; if ((hdr->EVENT.DUR == NULL) || (hdr->EVENT.CHN == NULL)) return; for (k1=0; k1EVENT.CHN[k1]) return; hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP,2*N*sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS,2*N*sizeof(*hdr->EVENT.POS)); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = (gdf_time*) realloc(hdr->EVENT.TimeStamp,2*N*sizeof(gdf_time)); #endif for (k1=0,k2=N; k1EVENT.DUR[k1]) { hdr->EVENT.TYP[k2] = hdr->EVENT.TYP[k1] | 0x8000; hdr->EVENT.POS[k2] = hdr->EVENT.POS[k1] + hdr->EVENT.DUR[k1]; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[k2] = hdr->EVENT.TimeStamp[k1] + lround(ldexp(hdr->EVENT.DUR[k1]/(hdr->EVENT.SampleRate*24*3600),32)); #endif k2++; } hdr->EVENT.N = k2; free(hdr->EVENT.CHN); hdr->EVENT.CHN=NULL; free(hdr->EVENT.DUR); hdr->EVENT.DUR=NULL; sort_eventtable(hdr); } /*------------------------------------------------------------------------ write GDF event table utility function for SCLOSE and SFLUSH_GDF_EVENT_TABLE TODO: writing of TimeStamps ------------------------------------------------------------------------*/ void write_gdf_eventtable(HDRTYPE *hdr) { uint32_t k32u; uint8_t buf[88]; char flag; fprintf(stdout,"write_gdf_eventtable is obsolete - use hdrEVT2rawEVT instead;\n"); ifseek(hdr, hdr->HeadLen + hdr->AS.bpb*hdr->NRec, SEEK_SET); if (VERBOSE_LEVEL>7) fprintf(stdout,"WriteEventTable: %p %p %p %p\t",hdr->EVENT.TYP,hdr->EVENT.POS,hdr->EVENT.DUR,hdr->EVENT.CHN); flag = (hdr->EVENT.DUR != NULL) && (hdr->EVENT.CHN != NULL); if (flag) // any DUR or CHN is larger than 0 for (k32u=0, flag=0; (k32uEVENT.N) && !flag; k32u++) flag |= hdr->EVENT.CHN[k32u] || hdr->EVENT.DUR[k32u]; if (VERBOSE_LEVEL>7) fprintf(stdout,"flag=%d.\n",flag); buf[0] = (flag ? 3 : 1); if (hdr->VERSION < 1.94) { k32u = lround(hdr->EVENT.SampleRate); buf[1] = k32u & 0x000000FF; buf[2] = (k32u>>8 ) & 0x000000FF; buf[3] = (k32u>>16) & 0x000000FF; leu32a(hdr->EVENT.N, buf+4); } else { k32u = hdr->EVENT.N; buf[1] = k32u & 0x000000FF; buf[2] = (k32u>>8 ) & 0x000000FF; buf[3] = (k32u>>16) & 0x000000FF; lef32a(hdr->EVENT.SampleRate, buf+4); }; for (k32u=0; k32uEVENT.N; k32u++) { hdr->EVENT.POS[k32u] = htole32(hdr->EVENT.POS[k32u]); hdr->EVENT.TYP[k32u] = htole16(hdr->EVENT.TYP[k32u]); } ifwrite(buf, 8, 1, hdr); ifwrite(hdr->EVENT.POS, sizeof(*hdr->EVENT.POS), hdr->EVENT.N, hdr); ifwrite(hdr->EVENT.TYP, sizeof(*hdr->EVENT.TYP), hdr->EVENT.N, hdr); if (flag) { for (k32u=0; k32uEVENT.N; k32u++) { hdr->EVENT.DUR[k32u] = le32toh(hdr->EVENT.DUR[k32u]); hdr->EVENT.CHN[k32u] = le16toh(hdr->EVENT.CHN[k32u]); } ifwrite(hdr->EVENT.CHN, sizeof(*hdr->EVENT.CHN), hdr->EVENT.N,hdr); ifwrite(hdr->EVENT.DUR, sizeof(*hdr->EVENT.DUR), hdr->EVENT.N,hdr); } } #if (BIOSIG_VERSION < 10500) /* Stubs for deprecated functions */ ATT_DEPREC void FreeGlobalEventCodeTable() {} // deprecated since Oct 2012, v1.4.0 ATT_DEPREC void LoadGlobalEventCodeTable() {} // deprecated since Oct 2012, v1.4.0 #endif /*------------------------------------------------------------------------ adds free text annotation to event table the EVENT.TYP is identified from the table EVENT.CodeDesc if annotations is not listed in CodeDesc, it is added to CodeDesc The table is limited to 256 entries, because the table EventCodes allows only codes 0-255 as user specific entry. ------------------------------------------------------------------------*/ void FreeTextEvent(HDRTYPE* hdr,size_t N_EVENT, const char* annotation) { /* free text annotations encoded as user specific events (codes 1-255) */ /* !!! annotation is not copied, but it is assumed that annotation string is also available after return usually, the string is available in hdr->AS.Header; still this can disappear (free, or rellocated) before the Event table is destroyed. !!! */ size_t k; int flag; // static int LengthCodeDesc = 0; if (hdr->EVENT.CodeDesc == NULL) { hdr->EVENT.CodeDesc = (typeof(hdr->EVENT.CodeDesc)) realloc(hdr->EVENT.CodeDesc,257*sizeof(*hdr->EVENT.CodeDesc)); hdr->EVENT.CodeDesc[0] = ""; // typ==0, is always empty hdr->EVENT.LenCodeDesc = 1; } if (annotation == NULL) { hdr->EVENT.TYP[N_EVENT] = 0; return; } // First, compare text with any predefined event description for (k=0; ETD[k].typ != 0; k++) { if (!strcmp(ETD[k].desc, annotation)) { // annotation is already a predefined event hdr->EVENT.TYP[N_EVENT] = ETD[k].typ; return; } } // Second, compare text with user-defined event description flag=1; for (k=0; (k < hdr->EVENT.LenCodeDesc) && flag; k++) { if (!strncmp(hdr->EVENT.CodeDesc[k], annotation, strlen(annotation))) { hdr->EVENT.TYP[N_EVENT] = k; flag = 0; } } // Third, add event description if needed if (flag && (hdr->EVENT.LenCodeDesc < 256)) { hdr->EVENT.TYP[N_EVENT] = hdr->EVENT.LenCodeDesc; hdr->EVENT.CodeDesc[hdr->EVENT.LenCodeDesc] = annotation; hdr->EVENT.LenCodeDesc++; } if (hdr->EVENT.LenCodeDesc > 255) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Maximum number of user-defined events (256) exceeded"); } } /*------------------------------------------------------------------------ returns clear text description of n-th event -------------------------------------------------------------- */ const char* GetEventDescription(HDRTYPE *hdr, size_t N) { if (hdr==NULL || N >= hdr->EVENT.N) return NULL; uint16_t TYP = hdr->EVENT.TYP[N]; if (TYP < hdr->EVENT.LenCodeDesc) // user-specified events, TYP < 256 return hdr->EVENT.CodeDesc[TYP]; if (TYP < 256) // not defined by user return NULL; // end of event: encoded by 0x8000+TYP if ((hdr->EVENT.TYP[N] & 0x8000) && (hdr->TYPE==GDF)) return (NULL); if ((hdr->EVENT.TYP[N] == 0x7fff) && (hdr->TYPE==GDF)) return "[neds]"; // event definition according to GDF's eventcodes.txt table uint16_t k; for (k=0; ETD[k].typ != 0; k++) if (ETD[k].typ==TYP) return ETD[k].desc; fprintf(stderr,"Warning: invalid event type 0x%04x\n",TYP); return (NULL); } /*------------------------------------------------------------------------ DUR2VAL converts sparse sample values in the event table from the DUR format (uint32, machine endian) to the sample value. Endianity of the platform is considered. ------------------------------------------------------------------------*/ double dur2val(uint32_t DUR, uint16_t gdftyp) { if (gdftyp==5) return (double)(int32_t)DUR; if (gdftyp==6) return (double)(uint32_t)DUR; if (gdftyp==16) { float fDur; memcpy(&fDur,&DUR,4); return (double)fDur; } union { uint32_t t32; uint16_t t16[2]; uint8_t t8[4]; } u; /* make sure u32 is always little endian like in the GDF file and only then extract the sample value */ u.t32 = htole32(DUR); if (gdftyp==1) return (double)(int8_t)(u.t8[0]); if (gdftyp==2) return (double)(uint8_t)(u.t8[0]); if (gdftyp==3) return (double)(int16_t)le16toh(u.t16[0]); if (gdftyp==4) return (double)(uint16_t)le16toh(u.t16[0]); return NAN; } /*------------------------------------------------------------------------ getTimeChannelNumber searches all channels, whether one channel contains the time axis Return value: the number of the first channel containing the time axis is returned. if no time channel is found, 0 is returned; Note: a 1-based indexing is used, the corresponding time channel is used the header of the time channel is in hdr->CHANNEL[getTimeChannelNumber(hdr)-1] ------------------------------------------------------------------------*/ int getTimeChannelNumber(HDRTYPE* hdr) { typeof(hdr->NS) k; for (k=0; kNS; k++) if (hdr->CHANNEL[k].OnOff==2) return (k+1); return 0; } /*------------------------------------------------------------------------ biosig_set_hdr_ipaddr set the field HDR.IPaddr based on the IP address of hostname Return value: 0: hdr->IPaddr is set otherwise hdr->IPaddr is not set ------------------------------------------------------------------------*/ int biosig_set_hdr_ipaddr(HDRTYPE *hdr, const char *hostname) { struct addrinfo hints; struct addrinfo *result, *rp; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = 0; hints.ai_flags = 0; hints.ai_protocol = 0; /* Any protocol */ int s = getaddrinfo(hostname, NULL, &hints, &result); if (s != 0) return -1; // IPaddr can not be set for (rp = result; rp != NULL; rp = rp->ai_next) { if ( rp->ai_family == AF_INET6) memcpy(hdr->IPaddr, &(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr), 16); else if ( rp->ai_family == AF_INET) { memcpy(hdr->IPaddr, &(((struct sockaddr_in *)rp->ai_addr)->sin_addr.s_addr), 4); memset(hdr->IPaddr+4, 0, 12); } break; // set first found address } freeaddrinfo(result); return 0; } /****************************************************************************/ /** **/ /** EXPORTED FUNCTIONS **/ /** **/ /****************************************************************************/ uint32_t get_biosig_version (void) { return ((BIOSIG_VERSION_MAJOR<<16) + (BIOSIG_VERSION_MINOR<<8) + BIOSIG_PATCHLEVEL); } /****************************************************************************/ /** INIT HDR **/ /****************************************************************************/ #define Header1 ((char*)hdr->AS.Header) HDRTYPE* constructHDR(const unsigned NS, const unsigned N_EVENT) { /* HDR is initialized, memory is allocated for NS channels and N_EVENT number of events. The purpose is to define all parameters at an initial step. No parameters must remain undefined. */ HDRTYPE* hdr = (HDRTYPE*)malloc(sizeof(HDRTYPE)); union { uint32_t testword; uint8_t testbyte[sizeof(uint32_t)]; } EndianTest; int k,k1; uint8_t LittleEndian; size_t BitsPerBlock; EndianTest.testword = 0x4a3b2c1d; LittleEndian = (EndianTest.testbyte[0]==0x1d && EndianTest.testbyte[1]==0x2c && EndianTest.testbyte[2]==0x3b && EndianTest.testbyte[3]==0x4a ); assert ( ( LittleEndian && __BYTE_ORDER == __LITTLE_ENDIAN) || (!LittleEndian && __BYTE_ORDER == __BIG_ENDIAN ) ); hdr->FileName = NULL; hdr->FILE.OPEN = 0; hdr->FILE.FID = 0; hdr->FILE.POS = 0; hdr->FILE.Des = 0; hdr->FILE.COMPRESSION = 0; hdr->FILE.size = 0; #ifdef ZLIB_H hdr->FILE.gzFID = 0; #endif hdr->AS.B4C_ERRNUM = B4C_NO_ERROR; hdr->AS.B4C_ERRMSG = NULL; hdr->AS.Header = NULL; hdr->AS.rawEventData = NULL; hdr->AS.auxBUF = NULL; hdr->AS.bpb = 0; hdr->TYPE = noFile; hdr->VERSION = 2.0; hdr->AS.rawdata = NULL; //(uint8_t*) malloc(0); hdr->AS.flag_collapsed_rawdata = 0; // is rawdata not collapsed hdr->AS.first = 0; hdr->AS.length = 0; // no data loaded memset(hdr->AS.SegSel,0,sizeof(hdr->AS.SegSel)); hdr->Calib = NULL; hdr->rerefCHANNEL = NULL; hdr->NRec = 0; hdr->SPR = 0; hdr->NS = NS; hdr->SampleRate = 4321.5; hdr->Patient.Id[0]=0; strcpy(hdr->ID.Recording,"00000000"); hdr->data.size[0] = 0; // rows hdr->data.size[1] = 0; // columns hdr->data.block = NULL; #if __FreeBSD__ || __APPLE__ || __NetBSD__ time_t t=time(NULL); struct tm *tt = localtime(&t); hdr->tzmin = tt->tm_gmtoff/60; hdr->T0 = t_time2gdf_time(time(NULL)-tt->tm_gmtoff); // localtime #else hdr->T0 = t_time2gdf_time(time(NULL)-timezone); // localtime hdr->tzmin = -timezone/60; // convert from seconds west of UTC to minutes east; #endif { uint8_t Equipment[8] = "b4c_1.5 "; Equipment[4] = BIOSIG_VERSION_MAJOR+'0'; Equipment[6] = BIOSIG_VERSION_MINOR+'0'; memcpy(&(hdr->ID.Equipment), &Equipment, 8); } hdr->ID.Manufacturer._field[0] = 0; hdr->ID.Manufacturer.Name = NULL; hdr->ID.Manufacturer.Model = NULL; hdr->ID.Manufacturer.Version = NULL; hdr->ID.Manufacturer.SerialNumber = NULL; hdr->ID.Technician = NULL; hdr->ID.Hospital = NULL; memset(hdr->IPaddr, 0, 16); { // some local variables are used only in this block #ifdef _WIN32 #if 1 // getlogin() a flawfinder level [4] issue, recommended to use getpwuid(geteuid()) but not available on Windows hdr->ID.Technician = strdup(getlogin()); #else // this compiles but stops with "Program error" on wine char str[1001]; GetUserName(str,1000); if (VERBOSE_LEVEL>7) fprintf(stdout,"Name:%s\n",str); hdr->ID.Technician = strdup(str); #endif #else char *username = NULL; struct passwd *p = getpwuid(geteuid()); if (p != NULL) username = p->pw_name; if (username) hdr->ID.Technician = strdup(username); #endif } #ifndef WITHOUT_NETWORK #ifdef _WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(1,1), &wsadata); #endif { // set default IP address to local IP address char *localhostname; localhostname = xgethostname(); if (localhostname) { biosig_set_hdr_ipaddr(hdr, localhostname); free (localhostname); } } #ifdef _WIN32 WSACleanup(); #endif #endif // not WITHOUT_NETWORK hdr->Patient.Name[0] = 0; //hdr->Patient.Id[0] = 0; hdr->Patient.Birthday = (gdf_time)0; // Unknown; hdr->Patient.Medication = 0; // 0:Unknown, 1: NO, 2: YES hdr->Patient.DrugAbuse = 0; // 0:Unknown, 1: NO, 2: YES hdr->Patient.AlcoholAbuse=0; // 0:Unknown, 1: NO, 2: YES hdr->Patient.Smoking = 0; // 0:Unknown, 1: NO, 2: YES hdr->Patient.Sex = 0; // 0:Unknown, 1: Male, 2: Female hdr->Patient.Handedness = 0; // 0:Unknown, 1: Right, 2: Left, 3: Equal hdr->Patient.Impairment.Visual = 0; // 0:Unknown, 1: NO, 2: YES, 3: Corrected hdr->Patient.Impairment.Heart = 0; // 0:Unknown, 1: NO, 2: YES, 3: Pacemaker hdr->Patient.Weight = 0; // 0:Unknown hdr->Patient.Height = 0; // 0:Unknown for (k1=0; k1<3; k1++) { hdr->Patient.Headsize[k1] = 0; // Unknown; hdr->ELEC.REF[k1] = 0.0; hdr->ELEC.GND[k1] = 0.0; } hdr->LOC[0] = 0x00292929; hdr->LOC[1] = 48*3600000+(1<<31); // latitude hdr->LOC[2] = 15*3600000+(1<<31); // longitude hdr->LOC[3] = 35000; //altitude in centimeter above sea level hdr->FLAG.UCAL = 0; // un-calibration OFF (auto-scaling ON) hdr->FLAG.OVERFLOWDETECTION = 1; // overflow detection ON hdr->FLAG.ANONYMOUS = 1; // <>0: no personal names are processed hdr->FLAG.TARGETSEGMENT = 1; // read 1st segment hdr->FLAG.ROW_BASED_CHANNELS=0; // define variable header hdr->CHANNEL = (CHANNEL_TYPE*)calloc(hdr->NS, sizeof(CHANNEL_TYPE)); BitsPerBlock = 0; for (k=0;kNS;k++) { size_t nbits; CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Label[0] = 0; hc->LeadIdCode= 0; strcpy(hc->Transducer, "EEG: Ag-AgCl electrodes"); hc->PhysDimCode = 19+4256; // uV hc->PhysMax = +100; hc->PhysMin = -100; hc->DigMax = +2047; hc->DigMin = -2048; hc->Cal = NAN; hc->Off = 0.0; hc->TOffset = 0.0; hc->GDFTYP = 3; // int16 hc->SPR = 1; // one sample per block hc->bi = 2*k; hc->bi8 = BitsPerBlock; nbits = GDFTYP_BITS[hc->GDFTYP]*hc->SPR; BitsPerBlock += nbits; hc->OnOff = 1; hc->HighPass = 0.16; hc->LowPass = 70.0; hc->Notch = 50; hc->Impedance = INFINITY; hc->fZ = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; } // define EVENT structure hdr->EVENT.N = N_EVENT; hdr->EVENT.SampleRate = 0; hdr->EVENT.CodeDesc = NULL; hdr->EVENT.LenCodeDesc = 0; if (hdr->EVENT.N) { hdr->EVENT.POS = (uint32_t*) calloc(hdr->EVENT.N, sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*) calloc(hdr->EVENT.N, sizeof(*hdr->EVENT.TYP)); hdr->EVENT.DUR = (uint32_t*) calloc(hdr->EVENT.N, sizeof(*hdr->EVENT.DUR)); hdr->EVENT.CHN = (uint16_t*) calloc(hdr->EVENT.N, sizeof(*hdr->EVENT.CHN)); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = (gdf_time*) calloc(hdr->EVENT.N, sizeof(gdf_time)); #endif } else { hdr->EVENT.POS = NULL; hdr->EVENT.TYP = NULL; hdr->EVENT.DUR = NULL; hdr->EVENT.CHN = NULL; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = NULL; #endif } // initialize specialized fields hdr->aECG = NULL; hdr->AS.bci2000 = NULL; #if (BIOSIG_VERSION >= 10500) hdr->SCP.Section7 = NULL; hdr->SCP.Section8 = NULL; hdr->SCP.Section9 = NULL; hdr->SCP.Section10 = NULL; hdr->SCP.Section11 = NULL; hdr->SCP.Section7Length = 0; hdr->SCP.Section8Length = 0; hdr->SCP.Section9Length = 0; hdr->SCP.Section10Length = 0; hdr->SCP.Section11Length = 0; #endif return(hdr); } /* just for debugging void debug_showptr(HDRTYPE* hdr) { fprintf(stdout,"=========================\n"); fprintf(stdout,"&AS.Header=%p\n",hdr->AS.Header); fprintf(stdout,"&AS.auxBUF=%p\n",hdr->AS.auxBUF); fprintf(stdout,"&aECG=%p\n",hdr->aECG); fprintf(stdout,"&AS.bci2000=%p\n",hdr->AS.bci2000); fprintf(stdout,"&AS.rawEventData=%p\n",hdr->AS.rawEventData); fprintf(stdout,"&AS.rawData=%p\n",hdr->AS.rawdata); fprintf(stdout,"&data.block=%p\n",hdr->data.block); fprintf(stdout,"&CHANNEL=%p\n",hdr->CHANNEL); fprintf(stdout,"&EVENT.POS=%p\n",hdr->EVENT.POS); fprintf(stdout,"&EVENT.TYP=%p\n",hdr->EVENT.TYP); fprintf(stdout,"&EVENT.DUR=%p\n",hdr->EVENT.DUR); fprintf(stdout,"&EVENT.CHN=%p\n",hdr->EVENT.CHN); fprintf(stdout,"&EVENT.CodeDesc=%p\n",hdr->EVENT.CodeDesc); fprintf(stdout,"&FileName=%p %s\n",&hdr->FileName,hdr->FileName); fprintf(stdout,"&Hospital=%p\n",hdr->ID.Hospital); } */ void destructHDR(HDRTYPE* hdr) { if (hdr==NULL) return; sclose(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR(%s): free HDR.aECG\n",hdr->FileName); #if (BIOSIG_VERSION < 10500) if (hdr->aECG != NULL) { if (((struct aecg*)hdr->aECG)->Section8.NumberOfStatements>0) free(((struct aecg*)hdr->aECG)->Section8.Statements); if (((struct aecg*)hdr->aECG)->Section11.NumberOfStatements>0) free(((struct aecg*)hdr->aECG)->Section11.Statements); free(hdr->aECG); } #endif if (hdr->ID.Technician != NULL) free(hdr->ID.Technician); if (hdr->ID.Hospital != NULL) free(hdr->ID.Hospital); if (hdr->AS.bci2000 != NULL) free(hdr->AS.bci2000); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free HDR.AS.rawdata @%p\n",hdr->AS.rawdata); // in case of SCPv3, rawdata can be loaded into Header if ( (hdr->AS.rawdata < hdr->AS.Header) || (hdr->AS.rawdata > (hdr->AS.Header+hdr->HeadLen)) ) if (hdr->AS.rawdata != NULL) free(hdr->AS.rawdata); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free HDR.data.block @%p\n",hdr->data.block); if (hdr->data.block != NULL) free(hdr->data.block); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free HDR.CHANNEL[] @%p %p\n",hdr->CHANNEL,hdr->rerefCHANNEL); if (hdr->CHANNEL != NULL) free(hdr->CHANNEL); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free HDR.AS.Header\n"); if (hdr->AS.rawEventData != NULL) free(hdr->AS.rawEventData); if (hdr->AS.Header != NULL) free(hdr->AS.Header); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free Event Table %p %p %p %p \n",hdr->EVENT.TYP,hdr->EVENT.POS,hdr->EVENT.DUR,hdr->EVENT.CHN); if (hdr->EVENT.POS != NULL) free(hdr->EVENT.POS); if (hdr->EVENT.TYP != NULL) free(hdr->EVENT.TYP); if (hdr->EVENT.DUR != NULL) free(hdr->EVENT.DUR); if (hdr->EVENT.CHN != NULL) free(hdr->EVENT.CHN); #if (BIOSIG_VERSION >= 10500) if (hdr->EVENT.TimeStamp) free(hdr->EVENT.TimeStamp); #endif if (hdr->EVENT.CodeDesc != NULL) free(hdr->EVENT.CodeDesc); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free HDR.AS.auxBUF\n"); if (hdr->AS.auxBUF != NULL) free(hdr->AS.auxBUF); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free HDR.rerefCHANNEL\n"); #ifdef CHOLMOD_H //if (hdr->Calib) cholmod_print_sparse(hdr->Calib,"destructHDR hdr->Calib",&CHOLMOD_COMMON_VAR); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free hdr->Calib\n"); if (hdr->Calib) cholmod_free_sparse(&hdr->Calib, &CHOLMOD_COMMON_VAR); if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free hdr->rerefCHANNEL %p\n",hdr->rerefCHANNEL); if (hdr->rerefCHANNEL) free(hdr->rerefCHANNEL); #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"destructHDR: free HDR\n"); if (hdr->FileName != NULL) free(hdr->FileName); if (hdr != NULL) free(hdr); return; } /****************************************************************************/ /** INITIALIZE FIELDS OF A SINGLE CHANNEL TO DEFAULT VALUES **/ /****************************************************************************/ void init_channel(struct CHANNEL_STRUCT *hc) { hc->PhysMin = -1e9; hc->PhysMax = +1e9; hc->DigMin = ldexp(-1,15); hc->DigMax = ldexp(1,15)-1; hc->Cal = 1.0; hc->Off = 0.0; hc->Label[0] = '\0'; hc->OnOff = 1; hc->LeadIdCode = 0; hc->Transducer[0] = '\0'; hc->PhysDimCode = 0; #ifdef MAX_LENGTH_PHYSDIM hc->PhysDim[0] = '?'; #endif hc->TOffset = 0.0; hc->HighPass = NAN; hc->LowPass = NAN; hc->Notch = NAN; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; hc->Impedance = NAN; hc->bufptr = NULL; hc->SPR = 1; hc->bi = 0; hc->bi8 = 0; hc->GDFTYP = 3; // int16 } /* http://www.ietf.org/rfc/rfc1952.txt */ const char *MAGIC_NUMBER_GZIP = "\x1f\x8B\x08"; /****************************************************************************/ /** GETFILETYPE **/ /****************************************************************************/ HDRTYPE* getfiletype(HDRTYPE* hdr) /* input: hdr->AS.Header1 contains first block of hdr->HeadLen bytes hdr->TYPE must be unknown, otherwise no FileFormat evaluation is performed output: hdr->TYPE file format hdr->VERSION is defined for some selected formats e.g. ACQ, EDF, BDF, GDF */ { // ToDo: use LEN to detect buffer overflow hdr->TYPE = unknown; if (VERBOSE_LEVEL>7) fprintf(stdout,"[%s line %i]! %i\n", __func__,__LINE__, hdr->HeadLen); #ifndef ONLYGDF const uint8_t MAGIC_NUMBER_FEF1[] = {67,69,78,13,10,0x1a,4,0x84}; const uint8_t MAGIC_NUMBER_FEF2[] = {67,69,78,0x13,0x10,0x1a,4,0x84}; const uint8_t MAGIC_NUMBER_Z[] = {31,157,144}; // const uint8_t MAGIC_NUMBER_ZIP[] = {80,75,3,4}; const uint8_t MAGIC_NUMBER_TIFF_l32[] = {73,73,42,0}; const uint8_t MAGIC_NUMBER_TIFF_b32[] = {77,77,0,42}; const uint8_t MAGIC_NUMBER_TIFF_l64[] = {73,73,43,0,8,0,0,0}; const uint8_t MAGIC_NUMBER_TIFF_b64[] = {77,77,0,43,0,8,0,0}; const uint8_t MAGIC_NUMBER_DICOM[] = {8,0,5,0,10,0,0,0,73,83,79,95,73,82,32,49,48,48}; const uint8_t MAGIC_NUMBER_UNIPRO[] = {40,0,4,1,44,1,102,2,146,3,44,0,190,3}; const uint8_t MAGIC_NUMBER_SYNERGY[] = {83,121,110,101,114,103,121,0,48,49,50,46,48,48,51,46,48,48,48,46,48,48,48,0,28,0,0,0,2,0,0,0}; const char* MAGIC_NUMBER_BRAINVISION = "Brain Vision Data Exchange Header File"; const char* MAGIC_NUMBER_BRAINVISION1 = "Brain Vision V-Amp Data Header File Version"; const char* MAGIC_NUMBER_BRAINVISIONMARKER = "Brain Vision Data Exchange Marker File, Version"; const uint8_t MAGIC_NUMBER_NICOLET_WFT[] = {0x33,0,0x32,0,0x31,0,0x30,0}; /******** read 1st (fixed) header *******/ uint32_t U32 = leu32p(hdr->AS.Header+2); uint32_t MAGIC_EN1064_Section0Length = leu32p(hdr->AS.Header+10); if ((U32>=30) & (U32<=45)) { hdr->VERSION = (float)U32; U32 = leu32p(hdr->AS.Header+6); if ((hdr->VERSION <34.0) && (U32 == 150)) hdr->TYPE = ACQ; else if ((hdr->VERSION <35.0) && (U32 == 164)) hdr->TYPE = ACQ; else if ((hdr->VERSION <36.0) && (U32 == 326)) hdr->TYPE = ACQ; else if ((hdr->VERSION <37.0) && (U32 == 886)) hdr->TYPE = ACQ; else if ((hdr->VERSION <38.0) && (U32 ==1894)) hdr->TYPE = ACQ; else if ((hdr->VERSION <41.0) && (U32 ==1896)) hdr->TYPE = ACQ; else if ((hdr->VERSION <43.0) && (U32 ==1944)) hdr->TYPE = ACQ; //else if ((hdr->VERSION <45.0) && (U32 ==2976)) hdr->TYPE = ACQ; else if ((hdr->VERSION <45.0) && (U32 >=2220)) hdr->TYPE = ACQ; else if ((hdr->VERSION>=45.0) && (U32 ==(12944+160))) hdr->TYPE = ACQ; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s ACQ %f %i\n", __FILE__, __LINE__, __func__, hdr->VERSION, U32); if (hdr->TYPE == ACQ) { hdr->HeadLen = U32; // length of fixed header hdr->FILE.LittleEndian = 1; return(hdr); } } U32 = beu32p(hdr->AS.Header+2); if ((U32==83)) { hdr->VERSION = (float)U32; U32 = beu32p(hdr->AS.Header+6); if ((hdr->VERSION == 83) & (U32 == 1564)) hdr->TYPE = ACQ; if (hdr->TYPE == ACQ) { hdr->HeadLen = U32; // length of fixed header hdr->FILE.LittleEndian = 0; return(hdr); } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s (..): %u %u %u\n", __FILE__,__LINE__,__func__,beu32p(hdr->AS.Header+2),beu32p(hdr->AS.Header+6),beu32p(hdr->AS.Header+10)); #endif //ONLYGDF if (VERBOSE_LEVEL>7) fprintf(stdout,"(%s line %i: %x %x! <%8s> TYPE=<%s>\n",__func__,__LINE__, leu16p(hdr->AS.Header),leu16p(hdr->AS.Header+154),hdr->AS.Header,GetFileTypeString(hdr->TYPE)); if (hdr->TYPE != unknown) return(hdr); #ifndef ONLYGDF else if (!memcmp(hdr->AS.Header, "ABF ", 4)) { // else if (!memcmp(Header1,"ABF \x66\x66\xE6\x3F",4)) { // ABF v1.8 hdr->TYPE = ABF; hdr->VERSION = lef32p(hdr->AS.Header+4); } else if (!memcmp(hdr->AS.Header, "ABF2\x00\x00", 6) && ( hdr->AS.Header[6] < 10 ) && ( hdr->AS.Header[7] < 10 ) ) { hdr->TYPE = ABF2; hdr->VERSION = hdr->AS.Header[7] + ( hdr->AS.Header[6] / 10.0 ); } else if (!memcmp(Header1+20,"ACR-NEMA",8)) hdr->TYPE = ACR_NEMA; else if (strstr(Header1,"ALPHA-TRACE-MEDICAL")) hdr->TYPE = alpha; else if (!memcmp(Header1,"ATES MEDICA SOFT. EEG for Windows",33)) hdr->TYPE = ATES; else if (!memcmp(Header1,"ATF\x09",4)) hdr->TYPE = ATF; else if (!memcmp(Header1,"AxGr",4)) { hdr->TYPE = AXG; hdr->VERSION = bei16p(hdr->AS.Header+4); } else if (!memcmp(Header1,"axgx",4)) { hdr->TYPE = AXG; hdr->VERSION = bei32p(hdr->AS.Header+4); } else if (!memcmp(Header1,"ADU1",4) || !memcmp(Header1,"ADU2",4) ) hdr->TYPE = Axona; else if (!memcmp(Header1,"HeaderLen=",10)) { hdr->TYPE = BCI2000; hdr->VERSION = 1.0; } else if (!memcmp(Header1,"BCI2000V",8)) { hdr->TYPE = BCI2000; hdr->VERSION = 1.1; } else if (!memcmp(Header1+1,"BIOSEMI",7) && (hdr->AS.Header[0]==0xff) && (hdr->HeadLen > 255)) { hdr->TYPE = BDF; hdr->VERSION = -1; } else if (!memcmp(Header1,"#BIOSIG ASCII",13)) hdr->TYPE = ASCII; else if (!memcmp(Header1,"#BIOSIG BINARY",14)) hdr->TYPE = BIN; else if ((leu16p(hdr->AS.Header)==207) && (leu16p(hdr->AS.Header+154)==0)) hdr->TYPE = BKR; else if (!memcmp(Header1+34,"BLSC",4)) hdr->TYPE = BLSC; else if (!memcmp(Header1,"bscs://",7)) hdr->TYPE = BSCS; else if (((beu16p(hdr->AS.Header)==0x0311) && (beu32p(hdr->AS.Header+4)==0x0809B002) && (leu16p(hdr->AS.Header+2) > 240) && (leu16p(hdr->AS.Header+2) < 250)) // v2.40 - v2.50 || !memcmp(hdr->AS.Header+307, "E\x00\x00\x00\x00\x00\x00\x00DAT", 11) ) hdr->TYPE = BLSC; else if (!memcmp(Header1,"#BIOSIGDUMP v1.0",16)) { hdr->TYPE = BiosigDump; hdr->VERSION = 1.0; } else if (!memcmp(Header1,"FileFormat = BNI-1-BALTIMORE",28)) hdr->TYPE = BNI; else if (!memcmp(Header1, MAGIC_NUMBER_NICOLET_WFT, 8)) { // WFT/Nicolet format hdr->TYPE = WFT; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s \n", __FILE__, __LINE__, __func__); } else if (!memcmp(Header1,MAGIC_NUMBER_BRAINVISION,strlen(MAGIC_NUMBER_BRAINVISION)) || ((leu32p(hdr->AS.Header)==0x42bfbbef) && !memcmp(Header1+3, MAGIC_NUMBER_BRAINVISION,38))) hdr->TYPE = BrainVision; else if (!memcmp(Header1,MAGIC_NUMBER_BRAINVISION1,strlen(MAGIC_NUMBER_BRAINVISION1))) hdr->TYPE = BrainVisionVAmp; else if (!memcmp(Header1,MAGIC_NUMBER_BRAINVISIONMARKER,strlen(MAGIC_NUMBER_BRAINVISIONMARKER))) hdr->TYPE = BrainVisionMarker; else if (!memcmp(Header1,"BZh91",5)) hdr->TYPE = BZ2; else if (!memcmp(Header1,"CDF",3)) hdr->TYPE = CDF; else if (!memcmp(Header1,"CEDFILE",7)) hdr->TYPE = CFS; else if (!memcmp(Header1+2,"(C) CED 87",10)) hdr->TYPE = SMR; // CED's SMR/SON format else if (!memcmp(Header1,"CFWB\1\0\0\0",8)) hdr->TYPE = CFWB; else if (!memcmp(Header1,"Version 3.0",11)) hdr->TYPE = CNT; else if (!memcmp(Header1,"MEG4",4)) hdr->TYPE = CTF; else if (!memcmp(Header1,"CTF_MRI_FORMAT VER 2.2",22)) hdr->TYPE = CTF; else if (!memcmp(Header1,"PATH OF DATASET:",16)) hdr->TYPE = CTF; else if (!memcmp(Header1,"DEMG",4)) hdr->TYPE = DEMG; else if (!memcmp(Header1+128,"DICM\x02\x00\x00\x00",8)) hdr->TYPE = DICOM; else if (!memcmp(Header1, MAGIC_NUMBER_DICOM,sizeof(MAGIC_NUMBER_DICOM))) hdr->TYPE = DICOM; else if (!memcmp(Header1+12, MAGIC_NUMBER_DICOM,sizeof(MAGIC_NUMBER_DICOM))) hdr->TYPE = DICOM; else if (!memcmp(Header1+12, MAGIC_NUMBER_DICOM,8)) hdr->TYPE = DICOM; else if (!memcmp(Header1, "SctHdr\0\0Directory\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\xff\xff\xff\xff\xff\xff\xff\0\0\0\0\0\0\0\0", 48) && (leu32p((hdr->AS.Header+0x3C))==0x68) ) { hdr->TYPE = EAS; } else if (!memcmp(Header1,"Easy3File",10)) { hdr->TYPE = EZ3; } else if (!memcmp(Header1,"EBS\x94\x0a\x13\x1a\x0d",8)) hdr->TYPE = EBS; else if (!memcmp(Header1,"0 ",8) && (hdr->HeadLen > 255)) { hdr->TYPE = EDF; hdr->VERSION = 0; } /* Nihon Kohden */ else if (is_nihonkohden_signature((char*)Header1) && is_nihonkohden_signature((char*)(Header1+0x81))) { hdr->TYPE = EEG1100; hdr->VERSION = strtod((char*)Header1+11,NULL); } else if (!memcmp(Header1, "RIFF",4) && !memcmp(Header1+8, "CNT ",4)) hdr->TYPE = EEProbe; else if (!memcmp(Header1, "EEP V2.0",8)) hdr->TYPE = EEProbe; else if (!memcmp(Header1, "\x26\x00\x10\x00",4)) // AVR hdr->TYPE = EEProbe; else if (( bei32p(hdr->AS.Header) == 0x01020304) && ((beu16p(hdr->AS.Header+4) == 0xffff) || (beu16p(hdr->AS.Header+4) == 3)) ) { hdr->TYPE = EGIS; hdr->FILE.LittleEndian = 0; } else if (( lei32p(hdr->AS.Header) == 0x01020304) && ((leu16p(hdr->AS.Header+4) == 0xffff) || (leu16p(hdr->AS.Header+4) == 3)) ) { hdr->TYPE = EGIS; hdr->FILE.LittleEndian = 1; } else if ((beu32p(hdr->AS.Header) > 1) && (beu32p(hdr->AS.Header) < 8) && !hdr->AS.Header[6] && !hdr->AS.Header[8] && !hdr->AS.Header[10] && !hdr->AS.Header[12] && !hdr->AS.Header[14] && !hdr->AS.Header[26] ) { /* sanity check: the high byte of month, day, hour, min, sec and bits must be zero */ hdr->TYPE = EGI; hdr->VERSION = hdr->AS.Header[3]; } else if (*(uint32_t*)(Header1) == htobe32(0x7f454c46)) hdr->TYPE = ELF; else if ( (hdr->HeadLen > 64) && !memcmp(Header1+0x30,"GALNT EEG DATA",14)) hdr->TYPE = EBNEURO; else if ( (hdr->HeadLen > 14) && !memcmp(Header1,"Embla data file",15)) hdr->TYPE = EMBLA; else if ( (hdr->HeadLen > 4) && ( !memcmp(Header1,"PBJ",3) || !memcmp(Header1,"BPC",3) ) ) hdr->TYPE = EMSA; else if (strstr(Header1,"Subject") && strstr(Header1,"Target.OnsetTime") && strstr(Header1,"Target.RTTime") && strstr(Header1,"Target.RESP")) hdr->TYPE = ePrime; else if (!memcmp(Header1,"[Header]",8)) hdr->TYPE = ET_MEG; else if ( (hdr->HeadLen > 19) && !memcmp(Header1,"Header\r\nFile Version'",20)) hdr->TYPE = ETG4000; else if (!memcmp(Header1,"|CF,",4)) hdr->TYPE = FAMOS; else if (!memcmp(Header1,MAGIC_NUMBER_FEF1,sizeof(MAGIC_NUMBER_FEF1)) || !memcmp(Header1,MAGIC_NUMBER_FEF2,sizeof(MAGIC_NUMBER_FEF1))) { hdr->TYPE = FEF; char tmp[9];tmp[8] = 0; memcpy(tmp,hdr->AS.Header+8,8); hdr->VERSION = (float)atol(tmp); } else if (!memcmp(hdr->AS.Header, "\0\0\0\x64\0\0\0\x1f\0\0\0\x14\0\0\0\0\0\1",4) && !memcmp(hdr->AS.Header+36,"\0\0\0\x65\0\0\0\3\0\0\0\4\0\0",14) && !memcmp(hdr->AS.Header+56,"\0\0\0\x6a\0\0\0\3\0\0\0\4\0\0\0\0\xff\xff\xff\xff\0\0",22) ) hdr->TYPE = FIFF; else if (!memcmp(Header1,"fLaC",4)) hdr->TYPE = FLAC; #endif //ONLYGDF else if (!memcmp(Header1,"GDF",3) && (hdr->HeadLen > 255)) { hdr->TYPE = GDF; char tmp[6]; tmp[5] = 0; memcpy(tmp,hdr->AS.Header+3, 5); hdr->VERSION = strtod(tmp,NULL); } #ifndef ONLYGDF else if (!memcmp(Header1,"GIF87a",6)) hdr->TYPE = GIF; else if (!memcmp(Header1,"GIF89a",6)) hdr->TYPE = GIF; else if ( (hdr->HeadLen > 21) && !memcmp(Header1,"GALILEO EEG TRACE FILE",22)) hdr->TYPE = GTF; else if (!memcmp(Header1,MAGIC_NUMBER_GZIP,strlen(MAGIC_NUMBER_GZIP))) { hdr->TYPE = GZIP; // hdr->FILE.COMPRESSION = 1; } else if (!memcmp(Header1,"\x89HDF\x0d\x0a\x1a\x0a",8)) hdr->TYPE = HDF; else if (!memcmp(Header1,"DATA\0\0\0\0",8)) { hdr->TYPE = HEKA; hdr->VERSION = 0; hdr->FILE.LittleEndian = *(uint8_t*)(hdr->AS.Header+52) > 0; } else if (!memcmp(Header1,"DAT1\0\0\0\0",8)) { hdr->TYPE = HEKA; hdr->VERSION = 1; hdr->FILE.LittleEndian = 0; } else if (!memcmp(Header1,"DAT2\0\0\0\0",8)) { hdr->TYPE = HEKA; hdr->VERSION = 2; hdr->FILE.LittleEndian = 1; } else if (!memcmp(Header1,"Tree",4) && (beu32p(Header1+4) < 6) ) { hdr->TYPE = HEKA; hdr->VERSION = 0; hdr->FILE.LittleEndian = 0; } else if (!memcmp(Header1,"eerT",4) && (leu32p(Header1+4) < 6) ) { hdr->TYPE = HEKA; hdr->VERSION = 0; hdr->FILE.LittleEndian = 1; } else if (!memcmp(Header1,"IGOR",4)) hdr->TYPE = ITX; else if (*(int16_t*)Header1==0x0001 || *(int16_t*)Header1==0x0002 || *(int16_t*)Header1==0x0003 || *(int16_t*)Header1==0x0005 ) { /* no swapping */ hdr->TYPE = IBW; hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); hdr->VERSION = *(int16_t*)Header1; } else if (*(int16_t*)Header1==0x0100 || *(int16_t*)Header1==0x0200 || *(int16_t*)Header1==0x0300 || *(int16_t*)Header1==0x0500 ) { /* data need to be swapped */ hdr->TYPE = IBW; hdr->FILE.LittleEndian = (__BYTE_ORDER == __BIG_ENDIAN); hdr->VERSION = bswap_16(*(int16_t*)Header1); } else if (!memcmp(Header1,"ANN 1.0",8)) hdr->TYPE = ISHNE; else if (!memcmp(Header1,"ISHNE1.0",8)) hdr->TYPE = ISHNE; else if (!memcmp(Header1,"@ MFER ",8)) hdr->TYPE = MFER; else if (!memcmp(Header1,"@ MFR ",6)) hdr->TYPE = MFER; else if (!memcmp(Header1,"MATLAB 5.0 MAT-file, ",7) && !memcmp(Header1+10," MAT-file, ",11) ) { hdr->TYPE = Matlab; hdr->VERSION = (Header1[7]-'0') + (Header1[9]-'0')/10.0; } else if (!memcmp(Header1,"%%MatrixMarket",14)) hdr->TYPE = MM; /* else if (!memcmp(Header1,"MThd\000\000\000\001\000",9)) hdr->TYPE = MIDI; */ else if (!memcmp(Header1,"\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x03\x00\xFE\xFF\x09\x00\x06",0x21)) hdr->TYPE = MSI; else if (!strcmp(Header1,"(*This is a Mathematica binary dump file. It can be loaded with Get.*)")) hdr->TYPE = MX; else if ( (hdr->HeadLen>346) && (Header1[344]=='n') && (Header1[347]=='\0') && \ ((Header1[345]=='i') || (Header1[345]=='+') ) && \ (Header1[346]>'0') && (Header1[346]<='9') ) { hdr->TYPE = NIFTI; hdr->VERSION = Header1[346]-'0'; } else if ( (hdr->HeadLen > 344) && (!memcmp(Header1+344,"ni1",4) || !memcmp(Header1+344,"n+1",4) ) ) hdr->TYPE = NIFTI; else if (!memcmp(Header1,"NEURALEV",8) || !memcmp(Header1,"N.EV.",6) ) hdr->TYPE = NEV; else if (!memcmp(Header1,"NEX1",3)) hdr->TYPE = NEX1; else if ( (hdr->HeadLen > 31) && !memcmp(Header1,"Logging Start\x0aLogger SW Version: ",31)) hdr->TYPE = NeuroLoggerHEX; else if (!memcmp(Header1,"Neuron",6)) hdr->TYPE = NEURON; else if (!memcmp(Header1,"\x93NUMPY",6)) { hdr->TYPE = NUMPY; } else if (!memcmp(Header1,"[FileInfo]",10)) hdr->TYPE = Persyst; else if (!memcmp(Header1,"SXDF",4)) hdr->TYPE = OpenXDF; else if (!memcmp(Header1,"PLEX",4)) { hdr->TYPE = PLEXON; hdr->VERSION=1.0; } else if (!memcmp(Header1+10,"PLEXON",6)) { hdr->TYPE = PLEXON; hdr->VERSION=2.0; } else if (!memcmp(Header1,"\x02\x27\x91\xC6",4)) { hdr->TYPE = RHD2000; // Intan RHD2000 format hdr->FILE.LittleEndian = 1; } else if (!memcmp(Header1,"\xAC\x27\x91\xD6",4)) { hdr->TYPE = RHS2000; // Intan RHS2000 format hdr->FILE.LittleEndian = 1; } else if (!memcmp(Header1,"\x81\xa4\xb1\xf3",4) & (leu16p(Header1+8) < 2)) { hdr->TYPE = IntanCLP; // Intan CLP format, we'll use same read for now hdr->FILE.LittleEndian = 1; } else if (!memcmp(Header1,"\x55\xAA\x00\xb0",2)) { hdr->TYPE = RDF; // UCSD ERPSS aquisition system hdr->FILE.LittleEndian = 1; } else if (!memcmp(Header1,"\xAA\x55\xb0\x00",2)) { hdr->TYPE = RDF; // UCSD ERPSS aquisition system hdr->FILE.LittleEndian = 0; } else if (!memcmp(Header1,"RIFF",4)) { hdr->TYPE = RIFF; if (!memcmp(Header1+8,"WAVE",4)) hdr->TYPE = WAV; if (!memcmp(Header1+8,"AIF",3)) hdr->TYPE = AIFF; if (!memcmp(Header1+8,"AVI ",4)) hdr->TYPE = AVI; } // general SCP else if ( (hdr->HeadLen>32) && ( MAGIC_EN1064_Section0Length > 120) && ( MAGIC_EN1064_Section0Length < 16+10*1024) && ((MAGIC_EN1064_Section0Length%10)== 6) && (*(uint16_t*)(hdr->AS.Header+ 8) == 0x0000) && (leu32p(hdr->AS.Header+10) == leu32p(hdr->AS.Header+24)) && ( (!memcmp(hdr->AS.Header+16,"SCPECG\0\0",8)) || (*(uint64_t*)(hdr->AS.Header+16) == 0) ) && (leu32p(hdr->AS.Header+28) == (uint32_t)0x00000007) && (leu16p(hdr->AS.Header+32) == (uint16_t)0x0001) ) { hdr->TYPE = SCP_ECG; } /* // special SCP files - header is strange, files can be decoded else if ( (leu32p(hdr->AS.Header+10) == 136) && (*(uint16_t*)(hdr->AS.Header+ 8) == 0x0000) && ( (!memcmp(hdr->AS.Header+14,"\x0A\x01\x25\x01\x99\x01\xE7\x49\0\0",10)) || (!memcmp(hdr->AS.Header+14,"\x0A\x00\x90\x80\0\0\x78\x80\0\0",10)) || (!memcmp(hdr->AS.Header+14,"\x0A\xCD\xCD\xCD\xCD\xCD\xCD\xCD\0\0",10)) ) && (leu32p(hdr->AS.Header+24) == 136) && (leu32p(hdr->AS.Header+28) == 0x0007) && (leu16p(hdr->AS.Header+32) == 0x0001) ) { hdr->TYPE = SCP_ECG; hdr->VERSION = -2; } else if ( (leu32p(hdr->AS.Header+10) == 136) && (*(uint16_t*)(hdr->AS.Header+ 8) == 0x0000) && (*(uint8_t*) (hdr->AS.Header+14) == 0x0A) && (*(uint8_t*) (hdr->AS.Header+15) == 0x0B) && (*(uint32_t*)(hdr->AS.Header+16) == 0) && (*(uint32_t*)(hdr->AS.Header+20) == 0) && (*(uint32_t*)(hdr->AS.Header+24) == 0) && (*(uint32_t*)(hdr->AS.Header+28) == 0) && (leu16p(hdr->AS.Header+32) == 0x0001) ) { hdr->TYPE = SCP_ECG; hdr->VERSION = -3; } */ /* // special SCP files - header is strange, files cannot be decoded else if ( (leu32p(hdr->AS.Header+10) == 136) && (*(uint16_t*)(hdr->AS.Header+ 8) == 0x0000) && (leu16p(hdr->AS.Header+14) == 0x0b0b) && (!memcmp(hdr->AS.Header+16,"x06SCPECG",7)) ) { hdr->TYPE = SCP_ECG; hdr->VERSION = -1; } else if ( (leu32p(hdr->AS.Header+10) == 136) && (*(uint16_t*)(hdr->AS.Header+ 8) == 0x0000) && (leu16p(hdr->AS.Header+14) == 0x0d0d) && (!memcmp(hdr->AS.Header+16,"SCPEGC\0\0",8)) && (leu32p(hdr->AS.Header+24) == 136) && (leu32p(hdr->AS.Header+28) == 0x0007) && (leu16p(hdr->AS.Header+32) == 0x0001) ) { hdr->TYPE = SCP_ECG; hdr->VERSION = -4; } */ else if ((hdr->HeadLen > 78) && !memcmp(Header1,"HEADER RECORD*******LIBRARY HEADER RECORD!!!!!!!000000000000000000000000000000",78)) hdr->TYPE = SASXPT; // SAS Transport file format (XPORT) else if (!memcmp(Header1,"$FL2@(#) SPSS DATA FILE",8)) { hdr->TYPE = SPSS; // SPSS file format switch (*(uint32_t*)(Header1+64)) { case 0x00000002: case 0x00000003: hdr->FILE.LittleEndian = 1; break; case 0x02000000: case 0x03000000: hdr->FILE.LittleEndian = 0; break; default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "invalid/unsupported file type"); break; } } else if ((Header1[0]==0x71 || Header1[0]==0x72) && (Header1[1]==1 || Header1[1]==2) && Header1[2]==1 && Header1[3]==0 ) hdr->TYPE = STATA; else if (!memcmp(Header1,"IAvSFo",6)) hdr->TYPE = SIGIF; else if (!memcmp(Header1,"position,duration,channel,type,name\n",35)) hdr->TYPE = SigViewerEventsCSV; else if ((hdr->HeadLen>23) && !memcmp(Header1,"SQLite format 3\000",16) && Header1[21]==64 && Header1[22]==32 && Header1[23]==32 ) hdr->TYPE = SQLite; else if ((hdr->HeadLen>23) && !memcmp(Header1,"\"Snap-Master Data File\"",24)) hdr->TYPE = SMA; else if (!memcmp(Header1,".snd",5)) hdr->TYPE = SND; else if (!memcmp(Header1,".snd",5)) hdr->TYPE = SND; else if (!memcmp(Header1,"TDSm",4)) hdr->TYPE = TDMS; // http://www.ni.com/white-paper/5696/en else if ((hdr->HeadLen>30) && !memcmp(Header1,"POLY SAMPLE FILEversion ",24) && !memcmp(Header1+28, "\x0d\x0a\x1a",3)) hdr->TYPE = TMS32; else if ((hdr->HeadLen>35) && !memcmp(Header1,"FileId=TMSi PortiLab sample log file\x0a\x0dVersion=",35)) hdr->TYPE = TMSiLOG; else if (!memcmp(Header1,MAGIC_NUMBER_TIFF_l32,4)) hdr->TYPE = TIFF; else if (!memcmp(Header1,MAGIC_NUMBER_TIFF_b32,4)) hdr->TYPE = TIFF; else if (!memcmp(Header1,MAGIC_NUMBER_TIFF_l64,8)) hdr->TYPE = TIFF; else if (!memcmp(Header1,MAGIC_NUMBER_TIFF_b64,8)) hdr->TYPE = TIFF; else if (!memcmp(Header1,"#VRML",5)) hdr->TYPE = VRML; else if ((hdr->HeadLen > 17) && !memcmp(hdr->AS.Header+4,MAGIC_NUMBER_UNIPRO,14)) hdr->TYPE = UNIPRO; else if (!memcmp(Header1,MAGIC_NUMBER_SYNERGY,sizeof(MAGIC_NUMBER_SYNERGY)) && !strncmp(Header1+63,"CRawDataElement",15) && !strncmp(Header1+85,"CRawDataBuffer",14) ) { hdr->TYPE = SYNERGY; } else if ((hdr->HeadLen > 23) && !memcmp(Header1,"# vtk DataFile Version ",23)) { hdr->TYPE = VTK; char tmp[4]; tmp[3]=0; memcpy(tmp,(char*)Header1+23,3); hdr->VERSION = strtod(tmp,NULL); } else if (!strncmp(Header1,"Serial number",13)) hdr->TYPE = ASCII_IBI; else if (!memcmp(Header1,"VER=9\r\nCTIME=",13)) hdr->TYPE = WCP; else if (!memcmp(Header1,"\xAF\xFE\xDA\xDA",4) || !memcmp(Header1,"\xDA\xDA\xFE\xAF",4) || !memcmp(Header1,"\x55\x55\xFE\xAF",4) ) hdr->TYPE = WG1; // Walter Graphtek else if (!memcmp(Header1,MAGIC_NUMBER_Z,3)) hdr->TYPE = Z; else if (!strncmp(Header1,"PK\003\004",4)) hdr->TYPE = ZIP; else if (!strncmp(Header1,"PK\005\006",4)) hdr->TYPE = ZIP; else if (!strncmp(Header1,"!\n",8)) hdr->TYPE = MSVCLIB; /* else if (!strncmp(Header1,"XDF",3)) hdr->TYPE = XDF; */ else if (!strncmp(Header1,"ZIP2",4)) hdr->TYPE = ZIP2; else if ((hdr->HeadLen>13) && !memcmp(Header1,"TYPE = HL7aECG; else if ( (leu32p(hdr->AS.Header) & 0x00FFFFFFL) == 0x00BFBBEFL && !memcmp(Header1+3,"TYPE = HL7aECG; // UTF8 else if (leu16p(hdr->AS.Header)==0xFFFE) { hdr->TYPE = XML; // UTF16 BigEndian hdr->FILE.LittleEndian = 0; } else if (leu16p(hdr->AS.Header)==0xFEFF) { hdr->TYPE = XML; // UTF16 LittleEndian hdr->FILE.LittleEndian = 1; } else if ((hdr->HeadLen>40) && !memcmp(hdr->AS.Header,"V3.0 ",16) && !memcmp(hdr->AS.Header+32,"[PatInfo]",9)) { hdr->TYPE = Sigma; hdr->VERSION = 3.0; } else if ((hdr->HeadLen > 175) && (hdr->AS.Header[175] < 5)) { hdr->TYPE = TRC; // Micromed *.TRC format hdr->FILE.LittleEndian = 1; } else if (!memcmp(hdr->AS.Header,"\x4c\x00\x00\x00\x01\x14\x02\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x46",20)) { hdr->TYPE = MS_LNK; // Microsoft *.LNK format hdr->FILE.LittleEndian = 1; } else if ((hdr->HeadLen > 175) && (hdr->AS.Header[175] < 5)) { hdr->TYPE = TRC; // Micromed *.TRC format hdr->FILE.LittleEndian = 1; } else { // if the first 4 bytes represent the file length struct stat FileBuf; if (stat(hdr->FileName,&FileBuf)==0 && (leu32p(hdr->AS.Header+2)==FileBuf.st_size) && (leu16p(hdr->AS.Header)==0) ) { // Cardioview 3000 generates such SCP files hdr->TYPE = SCP_ECG; hdr->FILE.LittleEndian = 1; fprintf(stderr,"Warning SOPEN (SCP): this kind of an SCP file predates the official SCP (EN1064) standard and is not fully implemented.\n" ); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): %i %s %s \n",__FILE__,__LINE__,hdr->TYPE,GetFileTypeString(hdr->TYPE),hdr->FileName); } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): 0x%x 0x%x \n",__FILE__,__LINE__,leu32p(hdr->AS.Header),(int)FileBuf.st_size); } #endif //ONLYGDF if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): %i %s endian:%c %s \n",__FILE__,__LINE__,hdr->TYPE,GetFileTypeString(hdr->TYPE), hdr->FILE.LittleEndian?'L':'B', hdr->FileName); return(hdr); } const struct FileFormatStringTable_t FileFormatStringTable[] = { { unknown, "unknown" }, { alpha, "alpha" }, { ABF, "ABF" }, { ABF2, "ABF2" }, { ACQ, "ACQ" }, { ACR_NEMA, "ACR_NEMA" }, { AINF, "AINF" }, { AIFC, "AIFC" }, { AIFF, "AIFF" }, { ARC, "ARC(Cadwell)" }, { ARFF, "ARFF" }, { ASCII, "ASCII" }, { ATES, "ATES" }, { ATF, "ATF" }, { AU, "AU" }, { AXG, "AXG" }, { Axona, "Axona" }, { BCI2000, "BCI2000" }, { BDF, "BDF" }, { BESA, "BESA" }, { BIN, "BINARY" }, { BiosigDump, "BIOSIGDUMP" }, { BKR, "BKR" }, { BLSC, "BLSC" }, { BMP, "BMP" }, { BNI, "BNI-1-Baltimore/Nicolet" }, { BrainVision, "BrainVision" }, { BrainVisionVAmp, "BrainVision" }, { BrainVisionMarker, "BrainVision" }, { BZ2, "BZ2" }, { CDF, "CDF" }, { CFS, "CFS" }, { CFWB, "CFWB" }, { CNT, "CNT" }, { CTF, "CTF" }, { DEMG, "DEMG" }, { DICOM, "DICOM" }, { EAS, "EAS(Cadwell)" }, { EBNEURO, "EBNEURO"}, { EBS, "EBS" }, { EDF, "EDF" }, { EEG1100, "EEG1100" }, { EEProbe, "EEProbe" }, { EGI, "EGI" }, { EGIS, "EGIS" }, { ELF, "ELF" }, { EMBLA, "EMBLA" }, { EMSA, "EMSA" }, { ePrime, "ePrime" }, { ET_MEG, "ET-MEG" }, { ETG4000, "ETG4000" }, { EVENT, "EVENT" }, { EXIF, "EXIF" }, { EZ3, "EZ3(Cadwell)" }, { FAMOS, "FAMOS" }, { FEF, "FEF" }, { FIFF, "FIFF" }, { FITS, "FITS" }, { FLAC, "FLAC" }, { GDF, "GDF" }, { GIF, "GIF" }, { GTF, "GTF" }, { GZIP, "GZIP" }, { HDF, "HDF" }, { HEKA, "HEKA" }, { HL7aECG, "HL7aECG" }, { IBW, "IBW" }, { ITX, "ITX" }, { ISHNE, "ISHNE" }, { JPEG, "JPEG" }, { JSON, "JSON" }, { Matlab, "MAT" }, { MFER, "MFER" }, { MIDI, "MIDI" }, { MIT, "MIT" }, { MM, "MatrixMarket" }, { MSI, "MSI" }, { MS_LNK, ".LNK" }, { MSVCLIB, "MS VC++ Library" }, { MX, "Mathematica serialized package format" }, { native, "native" }, { NeuroLoggerHEX, "NeuroLoggerHEX"}, { NetCDF, "NetCDF" }, { NEV, "NEV" }, { NEX1, "NEX" }, { NIFTI, "NIFTI" }, { NEURON, "NEURON" }, { NUMPY, "NUMPY" }, { Persyst, "Persyst" }, { OGG, "OGG" }, { PDP, "PDP" }, { PLEXON, "PLEXON" }, { RDF, "RDF" }, { IntanCLP, "IntanCLP" }, { RHD2000, "RHD2000" }, { RHS2000, "RHS2000" }, { RIFF, "RIFF" }, { SASXPT, "SAS_XPORT" }, { SCP_ECG, "SCP" }, { SIGIF, "SIGIF" }, { Sigma, "Sigma" }, { SigViewerEventsCSV, "SigViewer's CSV event table"}, { SMA, "SMA" }, { SMR, "SON/SMR" }, { SND, "SND" }, { SPSS, "SPSS" }, { SQLite, "SQLite" }, { STATA, "STATA" }, { SVG, "SVG" }, { SYNERGY, "SYNERGY"}, { TDMS, "TDMS (NI)" }, { TIFF, "TIFF" }, { TMS32, "TMS32" }, { TMSiLOG, "TMSiLOG" }, { TRC, "TRC" }, { UNIPRO, "UNIPRO" }, { VRML, "VRML" }, { VTK, "VTK" }, { WAV, "WAV" }, { WCP, "WCP" }, { WFT, "WFT/Nicolet" }, { WG1, "Walter Graphtek" }, { WMF, "WMF" }, { XDF, "XDF" }, { XML, "XML" }, { ZIP, "ZIP" }, { ZIP2, "ZIP2" }, { Z, "Z" }, { noFile, NULL } } ; /* ------------------------------------------ * returns string of file type * ------------------------------------------- */ const char* GetFileTypeString(enum FileFormat FMT) { uint16_t k; for (k=0; ; k++) { if (FMT==FileFormatStringTable[k].fmt) return (FileFormatStringTable[k].FileTypeString); if (noFile==FileFormatStringTable[k].fmt) // stopping criteria: last element in FileFormatStringTable return (NULL); } } /* ------------------------------------------ * returns file type from type string * ------------------------------------------- */ enum FileFormat GetFileTypeFromString(const char *FileTypeString) { uint16_t k; for (k=0; ; k++) { if (FileFormatStringTable[k].FileTypeString == NULL) // stopping criteria: last element in FileFormatStringTable return (noFile); if (!strcmp(FileFormatStringTable[k].FileTypeString, FileTypeString)) return (FileFormatStringTable[k].fmt); } } /****************************************************************************/ /** struct2gdfbin **/ /****************************************************************************/ void struct2gdfbin(HDRTYPE *hdr) { size_t k; char tmp[81]; uint32_t Dur[2]; // NS number of channels selected for writing typeof(hdr->NS) NS = 0; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (hc->OnOff) NS++; hc->Cal = (hc->PhysMax-hc->PhysMin)/(hc->DigMax-hc->DigMin); hc->Off = hc->PhysMin-hc->Cal*hc->DigMin; } hdr->HeadLen = (NS+1)*256; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %p\n", __func__, __LINE__, hdr->HeadLen, hdr->EVENT.LenCodeDesc, hdr->EVENT.CodeDesc); /****** * The size of Header 3 is computed by going through all TLV triples, * and compute HeadLen to allocate sufficient amount of memory * Header 3 is filled later in a 2nd scan below ******/ /* writing header 3, in Tag-Length-Value from */ uint32_t TagNLen[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint8_t tag=1; if (hdr->EVENT.LenCodeDesc > 1) { // first entry is always empty - no need to save tag1 for (k=0; kEVENT.LenCodeDesc; k++) TagNLen[tag] += strlen(hdr->EVENT.CodeDesc[k])+1; TagNLen[tag] += 1; // acounts for terminating \0 hdr->HeadLen += 4+TagNLen[tag]; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 2; if (hdr->AS.bci2000 != NULL) { TagNLen[tag] = strlen(hdr->AS.bci2000)+1; hdr->HeadLen += 4+TagNLen[tag]; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 3; if ((hdr->ID.Manufacturer.Name != NULL) || (hdr->ID.Manufacturer.Model != NULL) || (hdr->ID.Manufacturer.Version != NULL) || (hdr->ID.Manufacturer.SerialNumber != NULL)) { if (hdr->ID.Manufacturer.Name == NULL) hdr->ID.Manufacturer.Name=""; if (hdr->ID.Manufacturer.Model == NULL) hdr->ID.Manufacturer.Model=""; if (hdr->ID.Manufacturer.Version == NULL) hdr->ID.Manufacturer.Version=""; if (hdr->ID.Manufacturer.SerialNumber == NULL) hdr->ID.Manufacturer.SerialNumber=""; TagNLen[tag] = strlen(hdr->ID.Manufacturer.Name)+strlen(hdr->ID.Manufacturer.Model)+strlen(hdr->ID.Manufacturer.Version)+strlen(hdr->ID.Manufacturer.SerialNumber)+4; hdr->HeadLen += 4+TagNLen[tag]; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 4; /* OBSOLETE char FLAG_SENSOR_ORIENTATION = 0; for (k=0; kNS; k++) { FLAG_SENSOR_ORIENTATION |= hdr->CHANNEL[k].Orientation[0] != (float)0.0; FLAG_SENSOR_ORIENTATION |= hdr->CHANNEL[k].Orientation[1] != (float)0.0; FLAG_SENSOR_ORIENTATION |= hdr->CHANNEL[k].Orientation[2] != (float)0.0; FLAG_SENSOR_ORIENTATION |= hdr->CHANNEL[k].Area != (float)0.0; } if (FLAG_SENSOR_ORIENTATION) TagNLen[tag] = hdr->NS*sizeof(float)*4; hdr->HeadLen += 4+TagNLen[tag]; */ if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 5; for (k=0; k<16; k++) { if (hdr->IPaddr[k]) { if (k<4) TagNLen[tag] = 4; else TagNLen[tag] = 16; } hdr->HeadLen += 4+TagNLen[tag]; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 6; TagNLen[tag] = hdr->ID.Technician==NULL ? 0 : strlen(hdr->ID.Technician); if (TagNLen[tag]) { TagNLen[tag]++; hdr->HeadLen += 4+TagNLen[tag]; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 7; if (hdr->ID.Hospital!=NULL) { TagNLen[tag] = strlen(hdr->ID.Hospital); if (TagNLen[tag]) { TagNLen[tag]++; hdr->HeadLen += 4+TagNLen[tag]; } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); #if (BIOSIG_VERSION >= 10500) tag = 9; if (hdr->SCP.Section7 != NULL) { TagNLen[tag] = hdr->SCP.Section7Length; // leu32p(hdr->SCP.Section7+4); if (TagNLen[tag]) { hdr->HeadLen += 4+TagNLen[tag]; } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 10; if (hdr->SCP.Section8 != NULL) { TagNLen[tag] = hdr->SCP.Section8Length; // leu32p(hdr->SCP.Section8+4); if (TagNLen[tag]) { hdr->HeadLen += 4+TagNLen[tag]; } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 11; if (hdr->SCP.Section9 != NULL) { TagNLen[tag] = hdr->SCP.Section9Length; // leu32p(hdr->SCP.Section9+4); if (TagNLen[tag]) { hdr->HeadLen += 4+TagNLen[tag]; } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 12; if (hdr->SCP.Section10 != NULL) { TagNLen[tag] = hdr->SCP.Section10Length; // leu32p(hdr->SCP.Section10+4); if (TagNLen[tag]) { hdr->HeadLen += 4+TagNLen[tag]; } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); tag = 13; if (hdr->SCP.Section11 != NULL) { TagNLen[tag] = hdr->SCP.Section11Length; // leu32p(hdr->SCP.Section11+4); if (TagNLen[tag]) { hdr->HeadLen += 4+TagNLen[tag]; } } #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); /* end */ if (hdr->TYPE==GDF) { if (0.0 < hdr->VERSION && hdr->VERSION < 1.9) { hdr->VERSION = 1.25; } else if (hdr->VERSION < 3.0) { // this is currently still the default version #if (BIOSIG_VERSION >= 10500) hdr->VERSION = 2.51; #else hdr->VERSION = 2.22; #endif } else { hdr->VERSION = 3.0; } // in case of GDF v2, make HeadLen a multiple of 256. if ((hdr->VERSION > 2.0) && (hdr->HeadLen & 0x00ff)) hdr->HeadLen = (hdr->HeadLen & 0xff00) + 256; } else if (hdr->TYPE==GDF1) { fprintf(stderr,"libbiosig@sopen(hdr,\"w\") with hdr->TYPE=GDF1 is deprecated. Use hdr->TYPE=GDF and hdr->VERSION=1.25 instead\n"); hdr->VERSION = 1.25; hdr->TYPE = GDF; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, 1, hdr->HeadLen, TagNLen[1]); if (hdr->SCP.Section7 || hdr->SCP.Section8 || hdr->SCP.Section9 || hdr->SCP.Section10 || hdr->SCP.Section11) { // use auxillary pointer in order to keep SCP sections in memory if (hdr->aECG) free(hdr->aECG); hdr->aECG = hdr->AS.Header; hdr->AS.Header = (uint8_t*) realloc(NULL, hdr->HeadLen); } else { hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, hdr->HeadLen); } if (hdr->AS.Header == NULL) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Memory allocation failed"); return; } memset(Header1, 0, 256*(1+hdr->NS)); sprintf((char*)hdr->AS.Header,"GDF %4.2f",hdr->VERSION); uint8_t* Header2 = hdr->AS.Header+256; uint16_t maxlen = 66; if (hdr->VERSION < 1.90) maxlen = 80; size_t l1 = (hdr->Patient.Id==NULL) ? 0 : strlen(hdr->Patient.Id); size_t l2 = (hdr->Patient.Name==NULL) ? 0 : strlen(hdr->Patient.Name); if (0 < l1 && l1 < maxlen) { for (k=0; hdr->Patient.Id[k]; k++) if (isspace(hdr->Patient.Id[k])) hdr->Patient.Id[k] = '_'; strncpy(Header1+8, hdr->Patient.Id, l1+1); } else { strncpy(Header1+8, "X X",4); l1 = 1; } if (!hdr->FLAG.ANONYMOUS && (0 < l2) && (l1+l2+1 < maxlen) ) { Header1[8+l1] = ' '; strcpy(Header1+8+1+l1, hdr->Patient.Name); /* Flawfinder: ignore *** length is already checked with l1+l2+1 */ } else if (l1+3 < maxlen) strcpy(Header1+8+l1, " X"); if (hdr->VERSION>1.90) { Header1[84] = (hdr->Patient.Smoking%4) + ((hdr->Patient.AlcoholAbuse%4)<<2) + ((hdr->Patient.DrugAbuse%4)<<4) + ((hdr->Patient.Medication%4)<<6); Header1[85] = hdr->Patient.Weight; Header1[86] = hdr->Patient.Height; Header1[87] = (hdr->Patient.Sex%4) + ((hdr->Patient.Handedness%4)<<2) + ((hdr->Patient.Impairment.Visual%4)<<4) + ((hdr->Patient.Impairment.Heart%4)<<6); } size_t len = strlen(hdr->ID.Recording); memcpy(Header1+88, hdr->ID.Recording, min(len,80)); Header1[88 + min(len,80)] = 0; if (hdr->VERSION>1.90) { memcpy(Header1+152, &hdr->LOC, 16); #if __BYTE_ORDER == __BIG_ENDIAN *(uint32_t*) (Header1+152) = htole32( *(uint32_t*) (Header1+152) ); *(uint32_t*) (Header1+156) = htole32( *(uint32_t*) (Header1+156) ); *(uint32_t*) (Header1+160) = htole32( *(uint32_t*) (Header1+160) ); *(uint32_t*) (Header1+164) = htole32( *(uint32_t*) (Header1+164) ); #endif } if (hdr->VERSION<1.90) { struct tm *t = gdf_time2tm_time(hdr->T0); sprintf(tmp,"%04i%02i%02i%02i%02i%02i00",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); memcpy(hdr->AS.Header+168,tmp,max(strlen(tmp),16)); leu32a(hdr->HeadLen, hdr->AS.Header+184); memcpy(Header1+192, &hdr->ID.Equipment, 8); // FIXME: 200: LabId, 208 TechId, 216, Serial No // } else { //memcpy(Header1+168, &hdr->T0, 8); leu64a(hdr->T0, hdr->AS.Header+168); //memcpy(Header1+176, &hdr->Patient.Birthday, 8); leu64a(hdr->Patient.Birthday, hdr->AS.Header+176); // *(uint16_t*)(Header1+184) = (hdr->HeadLen>>8)+(hdr->HeadLen%256>0); leu32a(hdr->HeadLen>>8, hdr->AS.Header+184); memcpy(hdr->AS.Header+192, &hdr->ID.Equipment, 8); memcpy(hdr->AS.Header+200, &hdr->IPaddr, 6); memcpy(hdr->AS.Header+206, &hdr->Patient.Headsize, 6); lef32a(hdr->ELEC.REF[0], hdr->AS.Header+212); lef32a(hdr->ELEC.REF[1], hdr->AS.Header+216); lef32a(hdr->ELEC.REF[2], hdr->AS.Header+220); lef32a(hdr->ELEC.GND[0], hdr->AS.Header+224); lef32a(hdr->ELEC.GND[1], hdr->AS.Header+228); lef32a(hdr->ELEC.GND[2], hdr->AS.Header+232); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %x\n", __func__, __LINE__, hdr->HeadLen,leu32p(hdr->AS.Header+184)); leu64a(hdr->NRec, hdr->AS.Header+236); /* FIXME: this part should make the records as small as possible size_t DIV = 1, div; for (k=0; kNS; k++) { div = hdr->SPR/hdr->CHANNEL[k].SPR; if (div>DIV) DIV=div; } for (k=0; kNS; k++) { hdr->CHANNEL[k].SPR = (hdr->CHANNEL[k].SPR*DIV)/hdr->SPR; } hdr->NRec *= hdr->SPR/DIV; hdr->SPR = DIV; */ double fDur = hdr->SPR/hdr->SampleRate; if (hdr->NS==0 && 0.0 < hdr->EVENT.SampleRate && hdr->EVENT.SampleRate < INFINITY) fDur = 1.0 / hdr->EVENT.SampleRate; if (hdr->VERSION < 2.21) { /* Duration is expressed as an fraction of integers */ double dtmp1, dtmp2; dtmp2 = modf(fDur, &dtmp1); // approximate real with rational number if (fabs(dtmp2) < DBL_EPSILON) { Dur[0] = lround(fDur); Dur[1] = 1; } else { Dur[1] = lround(1.0 / dtmp2 ); Dur[0] = lround(1.0 + dtmp1 * Dur[1]); } leu32a(Dur[0], hdr->AS.Header+244); leu32a(Dur[1], hdr->AS.Header+248); } else lef64a(fDur, hdr->AS.Header+244); leu16a(NS, hdr->AS.Header + 252); if (hdr->VERSION > 2.4) { lei16a(hdr->tzmin, hdr->AS.Header+254); } /* define HDR.Header2 this requires checking the arguments in the fields of the struct HDR.CHANNEL and filling in the bytes in HDR.Header2. */ typeof(k) k2=0; for (k=0; kNS; k++) if (hdr->CHANNEL[k].OnOff) { const char *tmpstr; CHANNEL_TYPE *hc = hdr->CHANNEL+k; if ( (0 < hc->LeadIdCode) && (hc->LeadIdCode * sizeof(&LEAD_ID_TABLE[0]) < sizeof(LEAD_ID_TABLE) ) ) tmpstr = LEAD_ID_TABLE[hc->LeadIdCode]; else tmpstr = hc->Label; len = strlen(tmpstr)+1; memcpy(Header2+16*k2,tmpstr,min(len,16)); Header2[16*k2+min(len,16)] = 0; len = strlen(hdr->CHANNEL[k].Transducer); memcpy(Header2+80*k2 + 16*NS, hdr->CHANNEL[k].Transducer, min(len,80)); Header2[80*k2 + min(len,80) + 16*NS] = 0; tmpstr = PhysDim3(hdr->CHANNEL[k].PhysDimCode); len = strlen(tmpstr)+1; if (hdr->VERSION < 1.9) memcpy(Header2+ 8*k2 + 96*NS, tmpstr, min(8,len)); else { memcpy(Header2+ 6*k2 + 96*NS, tmpstr, min(6,len)); leu16a(hdr->CHANNEL[k].PhysDimCode, Header2+ 2*k2 + 102*NS); }; lef64a(hdr->CHANNEL[k].PhysMin, Header2 + 8*k2 + 104*NS); lef64a(hdr->CHANNEL[k].PhysMax, Header2 + 8*k2 + 112*NS); if (hdr->VERSION < 1.9) { lei64a((int64_t)hdr->CHANNEL[k].DigMin, Header2 + 8*k2 + 120*NS); lei64a((int64_t)hdr->CHANNEL[k].DigMax, Header2 + 8*k2 + 128*NS); // FIXME // memcpy(Header2 + 80*k + 136*hdr->NS,hdr->CHANNEL[k].PreFilt,max(80,strlen(hdr->CHANNEL[k].PreFilt))); } else { lef64a(hdr->CHANNEL[k].DigMin, Header2 + 8*k2 + 120*NS); lef64a(hdr->CHANNEL[k].DigMax, Header2 + 8*k2 + 128*NS); if (hdr->VERSION >= 2.22) lef32a(hdr->CHANNEL[k].TOffset, Header2 + 4*k2 + 200*NS); // GDF222 lef32a(hdr->CHANNEL[k].LowPass, Header2 + 4*k2 + 204*NS); lef32a(hdr->CHANNEL[k].HighPass, Header2 + 4*k2 + 208*NS); lef32a(hdr->CHANNEL[k].Notch, Header2 + 4*k2 + 212*NS); lef32a(hdr->CHANNEL[k].XYZ[0], Header2 + 4*k2 + 224*NS); lef32a(hdr->CHANNEL[k].XYZ[1], Header2 + 4*k2 + 228*NS); lef32a(hdr->CHANNEL[k].XYZ[2], Header2 + 4*k2 + 232*NS); if (hdr->VERSION < (float)2.19) Header2[k2+236*NS] = (uint8_t)ceil(log10(min(39e8,hdr->CHANNEL[k].Impedance))/log10(2.0)*8.0-0.5); else switch (hdr->CHANNEL[k].PhysDimCode & 0xFFE0) { // context-specific header 2 area case 4256: lef32a((float)hdr->CHANNEL[k].Impedance, Header2+236*NS+20*k2); break; case 4288: lef32a((float)hdr->CHANNEL[k].fZ, Header2+236*NS+20*k2); break; // default: // reserved area } } leu32a(hdr->CHANNEL[k].SPR, Header2 + 4*k2 + 216*NS); leu32a(hdr->CHANNEL[k].GDFTYP, Header2 + 4*k2 + 220*NS); k2++; } if (errno==34) errno = 0; // reset numerical overflow error if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %d %s\n", __func__, __LINE__, errno, strerror(errno)); /***** * This is the 2nd scan of Header3 - memory is allocated, now H3 is filled in with content *****/ Header2 = hdr->AS.Header+(NS+1)*256; tag = 1; if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=1 & Length of Tag 1 size_t pos = 4; for (k=0; kEVENT.LenCodeDesc; k++) { strcpy((char*)(Header2+pos),hdr->EVENT.CodeDesc[k]); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ pos += strlen(hdr->EVENT.CodeDesc[k])+1; } Header2[pos]=0; // terminating NULL Header2 += pos+1; } tag = 2; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=2 & Length of Tag 2 strcpy((char*)(Header2+4),hdr->AS.bci2000); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ Header2 += 4+TagNLen[tag]; } tag = 3; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=3 & Length of Tag 3 if (VERBOSE_LEVEL>8) fprintf(stdout,"SOPEN(GDF)w: tag=%i,len=%i\n",tag,TagNLen[tag]); memset(Header2+4,0,TagNLen[tag]); size_t len = 0; strcpy((char*)(Header2+4), hdr->ID.Manufacturer.Name); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ if (hdr->ID.Manufacturer.Name != NULL) len += strlen(hdr->ID.Manufacturer.Name); strcpy((char*)(Header2+5+len), hdr->ID.Manufacturer.Model); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ if (hdr->ID.Manufacturer.Model != NULL) len += strlen(hdr->ID.Manufacturer.Model); strcpy((char*)(Header2+6+len), hdr->ID.Manufacturer.Version); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ if (hdr->ID.Manufacturer.Version != NULL) len += strlen(hdr->ID.Manufacturer.Version); strcpy((char*)(Header2+7+len), hdr->ID.Manufacturer.SerialNumber); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ if (hdr->ID.Manufacturer.SerialNumber != NULL) len += strlen(hdr->ID.Manufacturer.SerialNumber); Header2 += 4+TagNLen[tag]; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); /* tag = 4; if (TagNLen[tag]>0) { *(uint32_t*)(Header2) = htole32(tag + (TagNLen[tag]<<8)); // Tag=4 & Length of Tag 4 Header2 += 4; for (k=0; kNS; k++) { *(uint32_t*)(Header2 + 4*k) = le32toh(*(uint32_t*)(hdr->CHANNEL[k].Orientation+0)); *(uint32_t*)(Header2 + 4*k + 4*hdr->NS) = le32toh(*(uint32_t*)(hdr->CHANNEL[k].Orientation+1)); *(uint32_t*)(Header2 + 4*k + 8*hdr->NS) = le32toh(*(uint32_t*)(hdr->CHANNEL[k].Orientation+2)); *(uint32_t*)(Header2 + 4*k +12*hdr->NS) = le32toh(*(uint32_t*)(&(hdr->CHANNEL[k].Area)); } Header2 += 4*sizeof(float)*hdr->NS; } */ tag = 5; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=5 & Length of Tag 5 memcpy(Header2+4,hdr->IPaddr,TagNLen[tag]); Header2 += 4+TagNLen[tag]; } tag = 6; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=6 & Length of Tag 6 strcpy((char*)(Header2+4),hdr->ID.Technician); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ Header2 += 4+TagNLen[tag]; } tag = 7; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=7 & Length of Tag 7 strcpy((char*)(Header2+4),hdr->ID.Hospital); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ Header2 += 4+TagNLen[tag]; } #if (BIOSIG_VERSION >= 10500) tag = 9; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=9 & Length of Tag 9 memcpy((char*)(Header2+4),hdr->SCP.Section7, TagNLen[tag]); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ hdr->SCP.Section7 = Header2+4; Header2 += 4+TagNLen[tag]; } tag = 10; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=10 & Length of Tag 10 memcpy((char*)(Header2+4),hdr->SCP.Section8, TagNLen[tag]); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ hdr->SCP.Section8 = Header2+4; Header2 += 4+TagNLen[tag]; } tag = 11; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=11 & Length of Tag 11 memcpy((char*)(Header2+4),hdr->SCP.Section9, TagNLen[tag]); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ hdr->SCP.Section9 = Header2+4; Header2 += 4+TagNLen[tag]; } tag = 12; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=12 & Length of Tag 12 memcpy((char*)(Header2+4),hdr->SCP.Section10, TagNLen[tag]); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ hdr->SCP.Section10 = Header2+4; Header2 += 4+TagNLen[tag]; } tag = 13; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i %i\n", __func__, __LINE__, tag, hdr->HeadLen, TagNLen[tag]); if (TagNLen[tag]>0) { leu32a(tag + (TagNLen[tag]<<8), Header2); // Tag=13 & Length of Tag 13 memcpy((char*)(Header2+4),hdr->SCP.Section11, TagNLen[tag]); /* Flawfinder: ignore *** memory is allocated after 1st H3 scan above */ hdr->SCP.Section11 = Header2+4; Header2 += 4+TagNLen[tag]; } #endif while (Header2 < (hdr->AS.Header + hdr->HeadLen) ) { *Header2 = 0; Header2++; } if (hdr->aECG) { free(hdr->aECG); hdr->aECG=NULL; } if (VERBOSE_LEVEL>8) fprintf(stdout,"GDFw [339] %p %p\n", Header1,Header2); } /**************************************************************************** gdfbin2struct converts flat file into hdr structure ****************************************************************************/ int gdfbin2struct(HDRTYPE *hdr) { unsigned int k; char tmp[81]; double Dur; // char* ptr_str; struct tm tm_time; // time_t tt; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %p\n",__func__,__LINE__,hdr->AS.Header); if (!memcmp("GDF",(char*)(hdr->AS.Header+3),3)) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Only GDF is supported"); return (hdr->AS.B4C_ERRNUM); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i \n",__func__,__LINE__, (int)hdr->NS); strncpy(tmp,(char*)(hdr->AS.Header+3),5); tmp[5]=0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i Ver=<%s>\n",__func__,__LINE__, (int)hdr->NS,tmp); hdr->VERSION = atof(tmp); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i Ver=<%s>\n",__func__,__LINE__, (int)hdr->NS,tmp); hdr->NRec = lei64p(hdr->AS.Header+236); hdr->NS = leu16p(hdr->AS.Header+252); hdr->tzmin = (hdr->VERSION > 2.4) ? lei16p(hdr->AS.Header+254) : 0; if (hdr->VERSION < 2.21) Dur = (double)leu32p(hdr->AS.Header+244)/(double)leu32p(hdr->AS.Header+248); else Dur = lef64p(hdr->AS.Header+244); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i Ver=%g\n",__func__,__LINE__, hdr->NS, hdr->VERSION); if (hdr->VERSION > 1.90) { hdr->HeadLen = leu16p(hdr->AS.Header+184)<<8; int len = min(66,MAX_LENGTH_PID); strncpy(hdr->Patient.Id,(const char*)hdr->AS.Header+8,len); hdr->Patient.Id[len]=0; len = min(64,MAX_LENGTH_RID); strncpy(hdr->ID.Recording,(const char*)hdr->AS.Header+88,len); hdr->ID.Recording[len]=0; strtok(hdr->Patient.Id," "); char *tmpptr = strtok(NULL," "); if ((!hdr->FLAG.ANONYMOUS) && (tmpptr != NULL)) { // strncpy(hdr->Patient.Name,tmpptr,Header1+8-tmpptr); strncpy(hdr->Patient.Name,tmpptr,MAX_LENGTH_NAME); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__func__,__LINE__, GetFileTypeString(hdr->TYPE), hdr->VERSION); hdr->Patient.Smoking = Header1[84]%4; hdr->Patient.AlcoholAbuse = (Header1[84]>>2)%4; hdr->Patient.DrugAbuse = (Header1[84]>>4)%4; hdr->Patient.Medication = (Header1[84]>>6)%4; hdr->Patient.Weight = Header1[85]; hdr->Patient.Height = Header1[86]; hdr->Patient.Sex = Header1[87]%4; hdr->Patient.Handedness = (Header1[87]>>2)%4; hdr->Patient.Impairment.Visual = (Header1[87]>>4)%4; hdr->Patient.Impairment.Heart = (Header1[87]>>6)%4; #if __BYTE_ORDER == __BIG_ENDIAN *(uint32_t*)(hdr->AS.Header+156) = bswap_32(*(uint32_t*)(hdr->AS.Header+156)); *(uint32_t*)(hdr->AS.Header+160) = bswap_32(*(uint32_t*)(hdr->AS.Header+160)); *(uint32_t*)(hdr->AS.Header+164) = bswap_32(*(uint32_t*)(hdr->AS.Header+164)); #endif if (hdr->AS.Header[156]) { hdr->LOC[0] = 0x00292929; memcpy(&hdr->LOC[1], hdr->AS.Header+156, 12); } else { #if __BYTE_ORDER == __BIG_ENDIAN *(uint32_t*) (hdr->AS.Header+152) = bswap_32(*(uint32_t*)(hdr->AS.Header+152)); #endif memcpy(&hdr->LOC, hdr->AS.Header+152, 16); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__func__,__LINE__, GetFileTypeString(hdr->TYPE), hdr->VERSION); hdr->T0 = lei64p(hdr->AS.Header+168); hdr->Patient.Birthday = lei64p(hdr->AS.Header+176); // memcpy(&hdr->T0, Header1+168,8); // memcpy(&hdr->Patient.Birthday, Header1+176, 8); hdr->ID.Equipment = lei64p(hdr->AS.Header+192); if (hdr->VERSION < (float)2.10) memcpy(hdr->IPaddr, Header1+200,4); hdr->Patient.Headsize[0]= leu16p(hdr->AS.Header+206); hdr->Patient.Headsize[1]= leu16p(hdr->AS.Header+208); hdr->Patient.Headsize[2]= leu16p(hdr->AS.Header+210); //memcpy(&hdr->ELEC.REF, Header1+212,12); //memcpy(&hdr->ELEC.GND, Header1+224,12); hdr->ELEC.REF[0] = lef32p(hdr->AS.Header+212); hdr->ELEC.REF[1] = lef32p(hdr->AS.Header+216); hdr->ELEC.REF[2] = lef32p(hdr->AS.Header+220); hdr->ELEC.GND[0] = lef32p(hdr->AS.Header+224); hdr->ELEC.GND[1] = lef32p(hdr->AS.Header+228); hdr->ELEC.GND[2] = lef32p(hdr->AS.Header+232); if (hdr->VERSION > 100000.0) { fprintf(stdout,"%e \nb4c %c %i %c. %c%c%c%c%c%c%c\n",hdr->VERSION,169,2007,65,83,99,104,108,246,103,108); FILE *fid = fopen("/tmp/b4c_tmp","wb"); if (fid != NULL) { fprintf(fid,"\nb4c %f \n%c %i %c.%c%c%c%c%c%c%c\n",hdr->VERSION,169,2007,65,83,99,104,108,246,103,108); fclose(fid); } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__func__,__LINE__, GetFileTypeString(hdr->TYPE), hdr->VERSION); } else if (hdr->VERSION > 0.0) { strncpy(hdr->Patient.Id,Header1+8,min(80,MAX_LENGTH_PID)); hdr->Patient.Id[min(80,MAX_LENGTH_PID)] = 0; strncpy(hdr->ID.Recording,(const char*)Header1+88,min(80,MAX_LENGTH_RID)); hdr->ID.Recording[min(80,MAX_LENGTH_RID)] = 0; strtok(hdr->Patient.Id," "); char *tmpptr = strtok(NULL," "); if ((!hdr->FLAG.ANONYMOUS) && (tmpptr != NULL)) { // strncpy(hdr->Patient.Name,tmpptr,Header1+8-tmpptr); strncpy(hdr->Patient.Name,tmpptr,MAX_LENGTH_NAME); } memset(tmp,0,5); strncpy(tmp,Header1+168+12,2); tm_time.tm_sec = atoi(tmp); strncpy(tmp,Header1+168+10,2); tm_time.tm_min = atoi(tmp); strncpy(tmp,Header1+168+ 8,2); tm_time.tm_hour = atoi(tmp); strncpy(tmp,Header1+168+ 6,2); tm_time.tm_mday = atoi(tmp); strncpy(tmp,Header1+168+ 4,2); tm_time.tm_mon = atoi(tmp)-1; strncpy(tmp,Header1+168 ,4); tm_time.tm_year = atoi(tmp)-1900; tm_time.tm_isdst= -1; hdr->T0 = tm_time2gdf_time(&tm_time); hdr->HeadLen = leu64p(hdr->AS.Header+184); } else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error SOPEN(GDF); invalid version number."); return (hdr->AS.B4C_ERRNUM); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i Ver=%4.2f\n",__func__,__LINE__, hdr->NS, hdr->VERSION); if (hdr->HeadLen < (256u * (hdr->NS + 1u))) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "(GDF) Length of Header is too small"); return (hdr->AS.B4C_ERRNUM); } hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); uint8_t *Header2 = hdr->AS.Header+256; hdr->AS.bpb=0; size_t bpb8 = 0; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i/%i\n",__func__,__LINE__, k, hdr->NS); hc->LeadIdCode = 0; size_t len = min(16, MAX_LENGTH_LABEL); strncpy(hc->Label,(char*)Header2 + 16*k, len); hc->Label[len] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"#%2i: <%s> %i %i\n",k,hc->Label,(int)len,(int)strlen(hc->Label)); len = min(MAX_LENGTH_TRANSDUCER, 80); memcpy(hc->Transducer, (char*)Header2 + 16*hdr->NS + 80*k, len); hc->Transducer[len] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"[GDF 212] #=%i/%i %s\n",k,hdr->NS,hc->Label); hc->PhysMin = lef64p(Header2+ 8*k + 104*hdr->NS); hc->PhysMax = lef64p(Header2+ 8*k + 112*hdr->NS); hc->SPR = leu32p(Header2+ 4*k + 216*hdr->NS); hc->GDFTYP = leu16p(Header2+ 4*k + 220*hdr->NS); hc->OnOff = 1; hc->bi = bpb8>>3; hc->bi8 = bpb8; size_t nbits = (GDFTYP_BITS[hc->GDFTYP]*(size_t)hc->SPR); bpb8 += nbits; if (hdr->VERSION < 1.90) { char p[9]; strncpy(p, (char*)Header2 + 8*k + 96*hdr->NS,8); p[8] = 0; // remove trailing blanks int k1; for (k1=7; (k1>0) && isspace(p[k1]); p[k1--] = 0) {}; hc->PhysDimCode = PhysDimCode(p); hc->DigMin = (double) lei64p(Header2 + 8*k + 120*hdr->NS); hc->DigMax = (double) lei64p(Header2 + 8*k + 128*hdr->NS); char *PreFilt = (char*)(Header2+ 68*k + 136*hdr->NS); hc->LowPass = NAN; hc->HighPass = NAN; hc->Notch = NAN; hc->TOffset = NAN; float lf,hf; if (sscanf(PreFilt,"%f - %f Hz",&lf,&hf)==2) { hc->LowPass = hf; hc->HighPass = lf; } } else { hc->PhysDimCode = leu16p(Header2+ 2*k + 102*hdr->NS); hc->DigMin = lef64p(Header2+ 8*k + 120*hdr->NS); hc->DigMax = lef64p(Header2+ 8*k + 128*hdr->NS); hc->LowPass = lef32p(Header2+ 4*k + 204*hdr->NS); hc->HighPass = lef32p(Header2+ 4*k + 208*hdr->NS); hc->Notch = lef32p(Header2+ 4*k + 212*hdr->NS); hc->XYZ[0] = lef32p(Header2+ 4*k + 224*hdr->NS); hc->XYZ[1] = lef32p(Header2+ 4*k + 228*hdr->NS); hc->XYZ[2] = lef32p(Header2+ 4*k + 232*hdr->NS); // memcpy(&hc->XYZ,Header2 + 4*k + 224*hdr->NS,12); hc->Impedance= ldexp(1.0, (uint8_t)Header2[k + 236*hdr->NS]/8); if (hdr->VERSION < 2.22) hc->TOffset = NAN; else hc->TOffset = lef32p(Header2 + 4 * k + 200 * hdr->NS); if (hdr->VERSION < (float)2.19) hc->Impedance = ldexp(1.0, (uint8_t)Header2[k + 236*hdr->NS]/8); else switch(hdr->CHANNEL[k].PhysDimCode & 0xFFE0) { // context-specific header 2 area case 4256: hc->Impedance = *(float*)(Header2+236*hdr->NS+20*k); break; case 4288: hc->fZ = *(float*)(Header2+236*hdr->NS+20*k); break; // default: // reserved area } } hc->Cal = (hc->PhysMax-hc->PhysMin)/(hc->DigMax-hc->DigMin); hc->Off = hc->PhysMin-hc->Cal*hc->DigMin; } hdr->AS.bpb = bpb8>>3; if (bpb8 & 0x07) { // each block must use whole number of bytes hdr->AS.bpb++; hdr->AS.bpb8 = hdr->AS.bpb<<3; } if (VERBOSE_LEVEL>8) fprintf(stdout,"[213] FMT=%s Ver=%4.2f\n",GetFileTypeString(hdr->TYPE),hdr->VERSION); for (k=0, hdr->SPR=1; kNS;k++) { if (VERBOSE_LEVEL>8) fprintf(stdout,"[GDF 214] #=%i\n",k); if (hdr->CHANNEL[k].SPR) hdr->SPR = lcm(hdr->SPR,hdr->CHANNEL[k].SPR); if (GDFTYP_BITS[hdr->CHANNEL[k].GDFTYP]==0) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "GDF: Invalid or unsupported GDFTYP"); return(hdr->AS.B4C_ERRNUM); } } hdr->SampleRate = ((double)(hdr->SPR))/Dur; if (VERBOSE_LEVEL>8) fprintf(stdout,"[219] FMT=%s Ver=%4.2f\n",GetFileTypeString(hdr->TYPE),hdr->VERSION); /* read GDF Header 3 - experimental */ if ((hdr->HeadLen > 256u*(hdr->NS+1u)) && (hdr->VERSION>=(float)2.10)) { uint8_t *Header2 = hdr->AS.Header + 256*(hdr->NS+1); uint8_t tag = 0xff; size_t pos=0,len=0; tag = (uint8_t)Header2[0]; if (VERBOSE_LEVEL>8) fprintf(stdout,"[220] GDFr3: %i %i Tag=%i\n",hdr->HeadLen,hdr->NS,tag); while ((pos < (hdr->HeadLen-256*(hdr->NS+1)-4)) && (tag>0)) { len = leu32p(Header2+pos)>>8; if (VERBOSE_LEVEL>8) fprintf(stdout,"GDFr3: Tag=%i Len=%i pos=%i\n",tag,(int)len,(int)pos); if (0) {} else if (tag==1) { // user-specific events i.e. free text annotations if (VERBOSE_LEVEL>6) fprintf(stdout,"user-specific events defined\n"); hdr->AS.auxBUF = (uint8_t*) realloc(hdr->AS.auxBUF,len); memcpy(hdr->AS.auxBUF, Header2+pos+4, len); hdr->EVENT.CodeDesc = (typeof(hdr->EVENT.CodeDesc)) realloc(hdr->EVENT.CodeDesc,257*sizeof(*hdr->EVENT.CodeDesc)); hdr->EVENT.CodeDesc[0] = ""; // typ==0, is always empty hdr->EVENT.LenCodeDesc = 1; k = 1; while (hdr->AS.auxBUF[k]) { hdr->EVENT.CodeDesc[hdr->EVENT.LenCodeDesc++] = (char*)(hdr->AS.auxBUF+k); k += strlen((char*)(hdr->AS.auxBUF+k))+1; } } else if (tag==2) { /* BCI 2000 information */ hdr->AS.bci2000 = (char*) realloc(hdr->AS.bci2000,len+1); memcpy(hdr->AS.bci2000,Header2+pos+4,len); hdr->AS.bci2000[len]=0; } else if (tag==3) { /* manufacture information */ if (len > MAX_LENGTH_MANUF) { fprintf(stderr,"Warning: length of Manufacturer information (%i) exceeds length of %i bytes\n", (int)len, MAX_LENGTH_MANUF); len = MAX_LENGTH_MANUF; } memcpy(hdr->ID.Manufacturer._field,Header2+pos+4,len); hdr->ID.Manufacturer._field[MAX_LENGTH_MANUF]=0; hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field; hdr->ID.Manufacturer.Model= hdr->ID.Manufacturer.Name+strlen(hdr->ID.Manufacturer.Name)+1; hdr->ID.Manufacturer.Version = hdr->ID.Manufacturer.Model+strlen(hdr->ID.Manufacturer.Model)+1; hdr->ID.Manufacturer.SerialNumber = hdr->ID.Manufacturer.Version+strlen(hdr->ID.Manufacturer.Version)+1; } else if (0) { // (tag==4) { /* sensor orientation */ /* // OBSOLETE for (k=0; kNS; k++) { hdr->CHANNEL[k].Orientation[0] = lef32p(Header2+pos+4+4*k); hdr->CHANNEL[k].Orientation[1] = lef32p(Header2+pos+4+4*k+hdr->NS*4); hdr->CHANNEL[k].Orientation[2] = lef32p(Header2+pos+4+4*k+hdr->NS*8); // if (len >= 12*hdr->NS) hdr->CHANNEL[k].Area = lef32p(Header2+pos+4+4*k+hdr->NS*12); if (VERBOSE_LEVEL>8) fprintf(stdout,"GDF tag=4 #%i pos=%i/%i: %f\n",k,pos,len,hdr->CHANNEL[k].Area); } */ } else if (tag==5) { /* IP address */ memcpy(hdr->IPaddr,Header2+pos+4,len); } else if (tag==6) { /* Technician */ hdr->ID.Technician = (char*)realloc(hdr->ID.Technician,len+1); memcpy(hdr->ID.Technician,Header2+pos+4, len); hdr->ID.Technician[len]=0; } else if (tag==7) { // recording institution // hdr->ID.Hospital = strndup((char*)(Header2+pos+4),len); hdr->ID.Hospital = malloc(len+1); if (hdr->ID.Hospital) { hdr->ID.Hospital[len] = 0; strncpy(hdr->ID.Hospital,(char*)Header2+pos+4,len); } } #if (BIOSIG_VERSION >= 10500) else if (tag==9) { hdr->SCP.Section7 = Header2+pos+4; hdr->SCP.Section7Length = len; } else if (tag==10) { hdr->SCP.Section8 = Header2+pos+4; hdr->SCP.Section8Length = len; } else if (tag==11) { hdr->SCP.Section9 = Header2+pos+4; hdr->SCP.Section9Length = len; } else if (tag==12) { hdr->SCP.Section10 = Header2+pos+4; hdr->SCP.Section10Length = len; } else if (tag==13) { hdr->SCP.Section11 = Header2+pos+4; hdr->SCP.Section11Length = len; } #endif /* further tags may include - Manufacturer: SCP, MFER, GDF1 - Orientation of MEG channels - Study ID - BCI: session, run */ pos+= 4+len; tag = (uint8_t)Header2[pos]; if (VERBOSE_LEVEL>8) fprintf(stdout,"GDFr3: next Tag=%i pos=%i\n",tag,(int)pos); } } // if (VERBOSE_LEVEL>8) fprintf(stdout,"[GDF 217] #=%li\n",iftell(hdr)); return(hdr->AS.B4C_ERRNUM); } /********************************************************************************* hdrEVT2rawEVT(HDRTYPE *hdr) converts structure HDR.EVENT into raw event data (hdr->AS.rawEventData) TODO: support of EVENT.TimeStamp *********************************************************************************/ size_t hdrEVT2rawEVT(HDRTYPE *hdr) { size_t k32u; char flag = (hdr->EVENT.DUR != NULL) && (hdr->EVENT.CHN != NULL) ? 3 : 1; if (flag==3) // any DUR or CHN is larger than 0 for (k32u=0, flag=1; k32u < hdr->EVENT.N; k32u++) if (hdr->EVENT.CHN[k32u] || hdr->EVENT.DUR[k32u]) { flag = 3; break; } #if (BIOSIG_VERSION >= 10500) if (hdr->EVENT.TimeStamp != NULL) { flag = flag | 0x04; } #endif int sze; sze = (flag & 2) ? 12 : 6; sze += (flag & 4) ? 8 : 0; size_t len = 8+hdr->EVENT.N*sze; hdr->AS.rawEventData = (uint8_t*) realloc(hdr->AS.rawEventData,len); uint8_t *buf = hdr->AS.rawEventData; buf[0] = flag; if (hdr->VERSION < 1.94) { k32u = lround(hdr->EVENT.SampleRate); buf[1] = k32u & 0x000000FF; buf[2] = (k32u>>8 ) & 0x000000FF; buf[3] = (k32u>>16) & 0x000000FF; leu32a(hdr->EVENT.N, buf+4); } else { k32u = hdr->EVENT.N; buf[1] = k32u & 0x000000FF; buf[2] = (k32u>>8 ) & 0x000000FF; buf[3] = (k32u>>16) & 0x000000FF; lef32a(hdr->EVENT.SampleRate, buf+4); }; uint8_t *buf1=hdr->AS.rawEventData+8; uint8_t *buf2=hdr->AS.rawEventData+8+hdr->EVENT.N*4; for (k32u=0; k32uEVENT.N; k32u++) { *(uint32_t*)(buf1+k32u*4) = htole32(hdr->EVENT.POS[k32u]+1); // convert from 0-based (biosig4c++) to 1-based (GDF) indexing *(uint16_t*)(buf2+k32u*2) = htole16(hdr->EVENT.TYP[k32u]); } if (flag & 2) { buf1 = hdr->AS.rawEventData+8+hdr->EVENT.N*6; buf2 = hdr->AS.rawEventData+8+hdr->EVENT.N*8; for (k32u=0; k32uEVENT.N; k32u++) { *(uint16_t*)(buf1+k32u*2) = htole16(hdr->EVENT.CHN[k32u]); *(uint32_t*)(buf2+k32u*4) = htole32(hdr->EVENT.DUR[k32u]); } } #if (BIOSIG_VERSION >= 10500) if (flag & 4) { buf1 = hdr->AS.rawEventData+8+hdr->EVENT.N*(sze-8); for (k32u=0; k32uEVENT.N; k32u++) { *(uint64_t*)(buf1+k32u*8) = htole64(hdr->EVENT.TimeStamp[k32u]); } } #endif return(len); } /********************************************************************************* rawEVT2hdrEVT(HDRTYPE *hdr) converts raw event data (hdr->AS.rawEventData) into structure HDR.EVENT TODO: support of EVENT.TimeStamp *********************************************************************************/ void rawEVT2hdrEVT(HDRTYPE *hdr, size_t length_rawEventData) { // TODO: avoid additional copying size_t k; uint8_t *buf = hdr->AS.rawEventData; if ((buf==NULL) || (length_rawEventData < 8)) { hdr->EVENT.N = 0; return; } if (hdr->VERSION < 1.94) { if (buf[1] | buf[2] | buf[3]) hdr->EVENT.SampleRate = buf[1] + (buf[2] + buf[3]*256.0)*256.0; else { fprintf(stdout,"Warning GDF v1: SampleRate in Eventtable is not set in %s !!!\n",hdr->FileName); hdr->EVENT.SampleRate = hdr->SampleRate; } hdr->EVENT.N = leu32p(buf + 4); } else { hdr->EVENT.N = buf[1] + (buf[2] + buf[3]*256)*256; hdr->EVENT.SampleRate = lef32p(buf + 4); } char flag = buf[0]; int sze = (flag & 2) ? 12 : 6; if (flag & 4) sze+=8; if (sze*hdr->EVENT.N+8 < length_rawEventData) { hdr->EVENT.N = 0; biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error GDF: event table is corrupted"); return; } if (hdr->NS==0 && !isfinite(hdr->SampleRate)) hdr->SampleRate = hdr->EVENT.SampleRate; hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, hdr->EVENT.N*sizeof(*hdr->EVENT.POS) ); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, hdr->EVENT.N*sizeof(*hdr->EVENT.TYP) ); uint8_t *buf1 = hdr->AS.rawEventData+8; uint8_t *buf2 = hdr->AS.rawEventData+8+4*hdr->EVENT.N; for (k=0; k < hdr->EVENT.N; k++) { // POS & TYP hdr->EVENT.POS[k] = leu32p(buf1 + k*4)-1; // convert from 1-based (GDF) to 0-based (biosig4c++) indexing hdr->EVENT.TYP[k] = leu16p(buf2 + k*2); } if (flag & 2) { // DUR & CHN hdr->EVENT.DUR = (uint32_t*) realloc(hdr->EVENT.DUR,hdr->EVENT.N*sizeof(*hdr->EVENT.DUR)); hdr->EVENT.CHN = (uint16_t*) realloc(hdr->EVENT.CHN,hdr->EVENT.N*sizeof(*hdr->EVENT.CHN)); buf1 = hdr->AS.rawEventData+8+6*hdr->EVENT.N; buf2 = hdr->AS.rawEventData+8+8*hdr->EVENT.N; for (k=0; k < hdr->EVENT.N; k++) { hdr->EVENT.CHN[k] = leu16p(buf1 + k*2); hdr->EVENT.DUR[k] = leu32p(buf2 + k*4); } } else { hdr->EVENT.DUR = NULL; hdr->EVENT.CHN = NULL; } #if (BIOSIG_VERSION >= 10500) if (flag & 4) { // TimeStamp hdr->EVENT.TimeStamp = (gdf_time*) realloc(hdr->EVENT.TimeStamp, hdr->EVENT.N*sizeof(*hdr->EVENT.TimeStamp)); buf1 = hdr->AS.rawEventData+8+hdr->EVENT.N*(sze-8); for (k=0; k < hdr->EVENT.N; k++) { hdr->EVENT.TimeStamp[k] = leu64p(buf1 + k*8); } } else { hdr->EVENT.TimeStamp = NULL; } #endif } int NumberOfChannels(HDRTYPE *hdr) { unsigned int k,NS; for (k=0, NS=0; kNS; k++) if (hdr->CHANNEL[k].OnOff==1) NS++; #ifdef CHOLMOD_H if (hdr->Calib == NULL) return (NS); if (NS == hdr->Calib->nrow) return (hdr->Calib->ncol); #endif return(hdr->NS); } int RerefCHANNEL(HDRTYPE *hdr, void *arg2, char Mode) { #ifndef CHOLMOD_H if (!arg2 || !Mode) return(0); // do nothing biosigERROR(hdr, B4C_REREF_FAILED, "Error RerefCHANNEL: cholmod library is missing"); return(1); #else if (arg2==NULL) Mode = 0; // do nothing cholmod_sparse *ReRef=NULL; uint16_t flag,NS; size_t i,j,k; long r; char flagLabelIsSet = 0; switch (Mode) { case 1: { HDRTYPE *RR = sopen((const char*)arg2,"r",NULL); ReRef = RR->Calib; if (RR->rerefCHANNEL != NULL) { flagLabelIsSet = 1; if (hdr->rerefCHANNEL) free(hdr->rerefCHANNEL); hdr->rerefCHANNEL = RR->rerefCHANNEL; RR->rerefCHANNEL = NULL; } RR->Calib = NULL; // do not destroy ReRef destructHDR(RR); RR = NULL; break; } case 2: ReRef = (cholmod_sparse*) arg2; CSstart(); break; } if ((ReRef==NULL) || !Mode) { // reset rereferencing if (hdr->Calib != NULL) cholmod_free_sparse(&hdr->Calib, &CHOLMOD_COMMON_VAR); hdr->Calib = ReRef; if (hdr->rerefCHANNEL) free(hdr->rerefCHANNEL); hdr->rerefCHANNEL = NULL; return(0); } cholmod_sparse *A = ReRef; // check dimensions for (k=0, NS=0; kNS; k++) if (hdr->CHANNEL[k].OnOff) NS++; if (NS - A->nrow) { biosigERROR(hdr, B4C_REREF_FAILED, "Error REREF_CHAN: size of data does not fit ReRef-matrix"); return(1); } // allocate memory if (hdr->Calib != NULL) cholmod_free_sparse(&hdr->Calib, &CHOLMOD_COMMON_VAR); if (VERBOSE_LEVEL>8) { CHOLMOD_COMMON_VAR.print = 5; cholmod_print_sparse(ReRef,"HDR.Calib", &CHOLMOD_COMMON_VAR); } hdr->Calib = ReRef; if (hdr->rerefCHANNEL==NULL) hdr->rerefCHANNEL = (CHANNEL_TYPE*) realloc(hdr->rerefCHANNEL, A->ncol*sizeof(CHANNEL_TYPE)); CHANNEL_TYPE *NEWCHANNEL = hdr->rerefCHANNEL; hdr->FLAG.ROW_BASED_CHANNELS = 1; // check each component for (i=0; incol; i++) // i .. column index { flag = 0; int mix = -1, oix = -1, pix = -1; double m = 0.0; double v; for (j = *((unsigned*)(A->p)+i); j < *((unsigned*)(A->p)+i+1); j++) { v = *(((double*)A->x)+j); r = *(((int*)A->i)+j); // r .. row index if (v>m) { m = v; mix = r; } if (v==1.0) { if (oix<0) oix = r; else fprintf(stderr,"Warning: ambiguous channel information (in new #%i,%i more than one scaling factor of 1.0 is used.) \n",(int)i,(int)j); } if (v) { if (pix == -1) { //memcpy(NEWCHANNEL+i, hdr->CHANNEL+r, sizeof(CHANNEL_TYPE)); NEWCHANNEL[i].PhysDimCode = hdr->CHANNEL[r].PhysDimCode; NEWCHANNEL[i].LowPass = hdr->CHANNEL[r].LowPass; NEWCHANNEL[i].HighPass = hdr->CHANNEL[r].HighPass; NEWCHANNEL[i].Notch = hdr->CHANNEL[r].Notch; NEWCHANNEL[i].SPR = hdr->CHANNEL[r].SPR; NEWCHANNEL[i].GDFTYP = hdr->CHANNEL[r].GDFTYP; NEWCHANNEL[i].Impedance = fabs(v)*hdr->CHANNEL[r].Impedance; NEWCHANNEL[i].OnOff = 1; NEWCHANNEL[i].LeadIdCode = 0; if (!flagLabelIsSet) memcpy(NEWCHANNEL[i].Label, hdr->CHANNEL[r].Label, MAX_LENGTH_LABEL); pix = 0; } else { if (NEWCHANNEL[i].PhysDimCode != hdr->CHANNEL[r].PhysDimCode) NEWCHANNEL[i].PhysDimCode = 0; if (NEWCHANNEL[i].LowPass != hdr->CHANNEL[r].LowPass) NEWCHANNEL[i].LowPass = NAN; if (NEWCHANNEL[i].HighPass != hdr->CHANNEL[r].HighPass) NEWCHANNEL[i].HighPass = NAN; if (NEWCHANNEL[i].Notch != hdr->CHANNEL[r].Notch) NEWCHANNEL[i].Notch = NAN; if (NEWCHANNEL[i].SPR != hdr->CHANNEL[r].SPR) NEWCHANNEL[i].SPR = lcm(NEWCHANNEL[i].SPR, hdr->CHANNEL[r].SPR); if (NEWCHANNEL[i].GDFTYP != hdr->CHANNEL[r].GDFTYP) NEWCHANNEL[i].GDFTYP = max(NEWCHANNEL[i].GDFTYP, hdr->CHANNEL[r].GDFTYP); NEWCHANNEL[i].Impedance += fabs(v)*NEWCHANNEL[r].Impedance; NEWCHANNEL[i].GDFTYP = 16; } } if (r >= hdr->NS) { flag = 1; fprintf(stderr,"Error: index (%i) in channel (%i) exceeds number of channels (%i)\n",(int)r,(int)i,hdr->NS); } } // heuristic to determine hdr->CHANNEL[k].Label; if (oix>-1) r=oix; // use the info from channel with a scaling of 1.0 ; else if (mix>-1) r=mix; // use the info from channel with the largest scale; else r = -1; if (flagLabelIsSet) ; else if (!flag && (rNS) && (r>=0)) { // if successful memcpy(NEWCHANNEL[i].Label, hdr->CHANNEL[r].Label, MAX_LENGTH_LABEL); } else { sprintf(NEWCHANNEL[i].Label,"component #%i",(int)i); } } return(0); #endif } /**************************************************************************** * READ_HEADER_1 * * ****************************************************************************/ int read_header(HDRTYPE *hdr) { /* input: hdr must be an open file able to read from hdr->TYPE must be unknown, otherwise no FileFormat evaluation is performed hdr->FILE.size output: defines whole header structure and event table return value: 0 no error -1 error reading header 1 -2 error reading header 2 -3 error reading event table */ if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %f\n",__func__,__LINE__, (int)hdr->FILE.size, (int)hdr->HeadLen, hdr->VERSION); size_t count = hdr->HeadLen; if (hdr->HeadLen<=512) { ifseek(hdr, count, SEEK_SET); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, 513); count += ifread(hdr->AS.Header+hdr->HeadLen, 1, 512-count, hdr); getfiletype(hdr); } char tmp[6]; strncpy(tmp,(char*)hdr->AS.Header+3,5); tmp[5]=0; hdr->VERSION = atof(tmp); // currently, only GDF is supported if ( (hdr->TYPE != GDF) || (hdr->VERSION < 0.01) ) return ( -1 ); if (hdr->VERSION > 1.90) hdr->HeadLen = leu16p(hdr->AS.Header+184)<<8; else hdr->HeadLen = leu64p(hdr->AS.Header+184); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i %f\n", __func__, __LINE__,(int)hdr->FILE.size, (int)hdr->HeadLen, (int)count, hdr->VERSION); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); if (count < hdr->HeadLen) { ifseek(hdr, count, SEEK_SET); count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i %f\n",__func__, __LINE__, (int)hdr->FILE.size, (int)hdr->HeadLen, (int)count, hdr->VERSION); if (count < hdr->HeadLen) { if (VERBOSE_LEVEL>7) fprintf(stdout,"ambiguous GDF header size: %i %i\n",(int)count,hdr->HeadLen); biosigERROR(hdr, B4C_INCOMPLETE_FILE, "reading GDF header failed"); return(-2); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i %f\n",__func__, __LINE__, (int)hdr->FILE.size, (int)hdr->HeadLen, (int)count, hdr->VERSION); if ( gdfbin2struct(hdr) ) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i %f\n",__func__, __LINE__, (int)hdr->FILE.size, (int)hdr->HeadLen, (int)count, hdr->VERSION); return(-2); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i %f\n",__func__, __LINE__, (int)hdr->FILE.size, (int)hdr->HeadLen, (int)count, hdr->VERSION); hdr->EVENT.N = 0; hdr->EVENT.POS = NULL; hdr->EVENT.TYP = NULL; hdr->EVENT.DUR = NULL; hdr->EVENT.CHN = NULL; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = NULL; #endif if (hdr->NRec < 0) { hdr->NRec = (hdr->FILE.size - hdr->HeadLen)/hdr->AS.bpb; if (hdr->AS.rawEventData!=NULL) { free(hdr->AS.rawEventData); hdr->AS.rawEventData=NULL; } } else if (hdr->FILE.size > hdr->HeadLen + hdr->AS.bpb*(size_t)hdr->NRec + 8) { if (VERBOSE_LEVEL > 7) fprintf(stdout,"GDF EVENT: %i,%i %i,%i,%i\n",(int)hdr->FILE.size, (int)(hdr->HeadLen + hdr->AS.bpb*hdr->NRec + 8), hdr->HeadLen, hdr->AS.bpb, (int)hdr->NRec); ifseek(hdr, hdr->HeadLen + hdr->AS.bpb*hdr->NRec, SEEK_SET); // READ EVENTTABLE hdr->AS.rawEventData = (uint8_t*)realloc(hdr->AS.rawEventData,8); size_t c = ifread(hdr->AS.rawEventData, sizeof(uint8_t), 8, hdr); uint8_t *buf = hdr->AS.rawEventData; if (c<8) { hdr->EVENT.N = 0; } else if (hdr->VERSION < 1.94) { hdr->EVENT.N = leu32p(buf + 4); } else { hdr->EVENT.N = buf[1] + (buf[2] + buf[3]*256)*256; } if (VERBOSE_LEVEL > 7) fprintf(stdout,"EVENT.N = %i,%i\n",hdr->EVENT.N,(int)c); char flag = buf[0]; int sze = (flag & 2) ? 12 : 6; if (flag & 4) sze+=8; hdr->AS.rawEventData = (uint8_t*)realloc(hdr->AS.rawEventData,8+hdr->EVENT.N*sze); c = ifread(hdr->AS.rawEventData+8, sze, hdr->EVENT.N, hdr); ifseek(hdr, hdr->HeadLen, SEEK_SET); if (c < hdr->EVENT.N) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, "reading GDF eventtable failed"); return(-3); } rawEVT2hdrEVT(hdr, 8+hdr->EVENT.N*sze); } else hdr->EVENT.N = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"[228] FMT=%s Ver=%4.2f\n",GetFileTypeString(hdr->TYPE),hdr->VERSION); return (0); } /****************************************************************************/ /** SOPEN **/ /****************************************************************************/ HDRTYPE* sopen(const char* FileName, const char* MODE, HDRTYPE* hdr) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): sopen(%s,%s)\n",__func__,__LINE__, FileName, MODE); return sopen_extended(FileName, MODE, hdr, NULL); } HDRTYPE* sopen_extended(const char* FileName, const char* MODE, HDRTYPE* hdr, biosig_options_type *biosig_options) { /* MODE="r" reads file and returns HDR MODE="w" writes HDR into file */ // unsigned int k2; // uint32_t k32u; size_t count; #ifndef ONLYGDF // double Dur; char* ptr_str; struct tm tm_time; // time_t tt; const char GENDER[] = "XMFX"; const uint16_t CFWB_GDFTYP[] = {17,16,3}; const float CNT_SETTINGS_NOTCH[] = {0.0, 50.0, 60.0}; const float CNT_SETTINGS_LOWPASS[] = {30, 40, 50, 70, 100, 200, 500, 1000, 1500, 2000, 2500, 3000}; const float CNT_SETTINGS_HIGHPASS[] = {NAN, 0, .05, .1, .15, .3, 1, 5, 10, 30, 100, 150, 300}; uint16_t BCI2000_StatusVectorLength=0; // specific for BCI2000 format #endif //ONLYGDF biosig_options_type default_options; default_options.free_text_event_limiter="\0"; if (biosig_options==NULL) biosig_options = &default_options; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(%s,%s) (line %d): --delimiter=<%s> %p\n",__func__, FileName, MODE, __LINE__, biosig_options->free_text_event_limiter, biosig_options); if (FileName == NULL) { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "no filename specified"); return (hdr); } if (hdr==NULL) hdr = constructHDR(0,0); // initializes fields that may stay undefined during SOPEN if (FileName != NULL) { if (hdr->FileName) free(hdr->FileName); hdr->FileName = strdup(FileName); } if (VERBOSE_LEVEL>6) fprintf(stdout,"SOPEN( %s, %s) open=%i\n",FileName, MODE, hdr->FILE.OPEN); setlocale(LC_NUMERIC,"C"); // hdr->FLAG.SWAP = (__BYTE_ORDER == __BIG_ENDIAN); // default: most data formats are little endian hdr->FILE.LittleEndian = 1; if (!strncmp(MODE,"a",1)) { /***** SOPEN APPEND *****/ HDRTYPE *hdr2 = NULL; struct stat FileBuf; if (stat(FileName, &FileBuf)==0) hdr->FILE.size = FileBuf.st_size; else hdr->FILE.size = 0; if (hdr->FILE.size==0) { if (hdr->FILE.OPEN) ifclose(hdr); return( sopen(FileName, "w", hdr) ); } else if (hdr->FILE.size < 256) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error SOPEN(APPEND); file format not supported."); return (hdr); } else { // read header of existing file hdr2 = sopen(FileName, "r", hdr2); sclose(hdr2); }; if (hdr2->TYPE != GDF) { // currently only GDF is tested and supported biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error SOPEN(APPEND); file format not supported."); destructHDR(hdr2); return (hdr); } // test for additional restrictions if ( hdr2->EVENT.N > 0 && hdr2->FILE.COMPRESSION ) { // gzopen does not support "rb+" (simultaneous read/write) but can only append at the end of file biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error SOPEN(GDF APPEND); cannot append to compressed GDF file containing event table."); destructHDR(hdr2); return (hdr); } // use header of existing file, sopen does hdr=hdr2, and open files for writing. destructHDR(hdr); if (hdr2->FILE.COMPRESSION) hdr = ifopen(hdr2, "ab"); else { hdr = ifopen(hdr2, "rb+"); ifseek(hdr, hdr->HeadLen + hdr->NRec*hdr->AS.bpb, SEEK_SET); } if (!hdr->FILE.OPEN) { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "Error SOPEN(APPEND); Cannot open file."); return(hdr); } hdr->FILE.OPEN = 2; } else if (!strncmp(MODE,"r",1)) { /***** SOPEN READ *****/ #ifndef WITHOUT_NETWORK if (!memcmp(hdr->FileName,"bscs://",7)) { uint64_t ID; char *hostname = (char*)hdr->FileName+7; char *t = strrchr(hostname,'/'); if (t==NULL) { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "SOPEN-NETWORK: file identifier not specifed"); return(hdr); } *t=0; cat64(t+1, &ID); int sd,s; sd = bscs_connect(hostname); if (sd<0) { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "could not connect to server"); return(hdr); } hdr->FILE.Des = sd; s = bscs_open(sd, &ID); if (VERBOSE_LEVEL>7) fprintf(stdout,"%i = bscs_open\n",s); s = bscs_requ_hdr(sd,hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"%i = bscs_requ_hdr\n",s); s = bscs_requ_evt(sd,hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"%i = bscs_requ_evt\n",s); hdr->FILE.OPEN = 1; return(hdr); } #endif // modern cpu's have cache lines of 4096 bytes, so for performance reasons we use this size as well. const size_t PAGESIZE=4096; /* reading some formats may imply that at least 512 bytes are read, if you want to use a smaller page size, double check whether your format(s) are correctly handled. */ assert(PAGESIZE >= 512); hdr->AS.Header = (uint8_t*)malloc(PAGESIZE+1); size_t k; #ifndef ONLYGDF size_t name=0,ext=0; for (k=0; hdr->FileName[k]; k++) { if (hdr->FileName[k]==FILESEP) name = k+1; if (hdr->FileName[k]=='.') ext = k+1; } const char *FileExt = hdr->FileName+ext; const char *FileName = hdr->FileName+name; #endif //ONLYGDF #ifdef __CURL_CURL_H if (! strncmp(hdr->FileName,"file://", 7) || ! strncmp(hdr->FileName,"ftp://", 6) || ! strncmp(hdr->FileName,"http://", 7) || ! strncmp(hdr->FileName,"https://", 8) ) { CURL *curl; char errbuffer[CURL_ERROR_SIZE]; if ((curl = curl_easy_init()) != NULL) { FILE *tmpfid = tmpfile(); curl_easy_setopt(curl, CURLOPT_URL, hdr->FileName); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuffer); if (VERBOSE_LEVEL > 6) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); curl_easy_setopt(curl, CURLOPT_WRITEDATA, tmpfid); if (curl_easy_perform(curl) != CURLE_OK) { fprintf(stderr,"CURL ERROR: %s\n",errbuffer); biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "Error SOPEN(READ); file download failed."); fclose(tmpfid); return(hdr); } /* associate temporary file with input stream channeling everything through zlib ensures that *.gz files are automatically decompressed According to http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.12.html#tmpfile, the tmpfile will be removed when stream is closed */ fseek(tmpfid,0,SEEK_SET); hdr->FILE.gzFID = gzdopen(fileno(tmpfid), "r"); hdr->FILE.COMPRESSION = 1; curl_easy_cleanup(curl); /* */ count = ifread(hdr->AS.Header, 1, PAGESIZE, hdr); hdr->AS.Header[count]=0; } } else #endif { if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN 101: <%s>\n",hdr->FileName); #ifndef ONLYGDF /* AINF */ if (!strcmp(FileExt, "ainf")) { if (VERBOSE_LEVEL>8) fprintf(stdout,"getfiletype ainf1 %s %i\n",hdr->FileName,(int)ext); char* AINF_RAW_FILENAME = (char*)calloc(strlen(hdr->FileName)+5,sizeof(char)); strncpy(AINF_RAW_FILENAME, hdr->FileName,ext); strcpy(AINF_RAW_FILENAME+ext, "raw"); FILE* fid1=fopen(AINF_RAW_FILENAME,"rb"); if (fid1) { fclose(fid1); hdr->TYPE = AINF; } free(AINF_RAW_FILENAME); } else if (!strcmp(FileExt, "raw")) { char* AINF_RAW_FILENAME = (char*)calloc(strlen(hdr->FileName)+5,sizeof(char)); strncpy(AINF_RAW_FILENAME, hdr->FileName,ext); strcpy(AINF_RAW_FILENAME+ext, "ainf"); FILE* fid1=fopen(AINF_RAW_FILENAME,"r"); if (fid1) { fclose(fid1); hdr->TYPE = AINF; } free(AINF_RAW_FILENAME); } #endif //ONLYGDF hdr->FILE.COMPRESSION = 0; hdr = ifopen(hdr,"rb"); if (!hdr->FILE.OPEN) { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "Error SOPEN(READ); Cannot open file."); return(hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN 101:\n"); count = ifread(hdr->AS.Header, 1, PAGESIZE, hdr); if (count<25) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...) count = %d\n",__FILE__,__LINE__,__func__,count); biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "Error SOPEN(READ); file is empty (or too short)"); ifclose(hdr); return(hdr); } hdr->AS.Header[count]=0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) count=%i\n", __func__, __LINE__,(int)count); if (!memcmp(Header1,MAGIC_NUMBER_GZIP,strlen(MAGIC_NUMBER_GZIP))) { #ifdef ZLIB_H if (VERBOSE_LEVEL>7) fprintf(stdout,"[221] %i\n",(int)count); ifseek(hdr, 0, SEEK_SET); hdr->FILE.gzFID = gzdopen(fileno(hdr->FILE.FID),"r"); hdr->FILE.COMPRESSION = (uint8_t)1; hdr->FILE.FID = NULL; count = ifread(hdr->AS.Header, 1, PAGESIZE, hdr); hdr->AS.Header[count]=0; #else biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error SOPEN(READ); *.gz file not supported because not linked with zlib."); #endif } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...): count%i\n",__FILE__,__LINE__,__func__,(int)count); hdr->HeadLen = count; getfiletype(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION); #ifndef ONLYGDF if (hdr->TYPE != unknown) ; else if (!memcmp(Header1,FileName,strspn(FileName,".")) && (!strcmp(FileExt,"HEA") || !strcmp(FileExt,"hea") )) hdr->TYPE = MIT; else if (count < 512) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error SOPEN(READ): file is too short\n"); return(hdr); } #endif //ONLYGDF if (hdr->TYPE == unknown) { biosigERROR(hdr, B4C_FORMAT_UNKNOWN, "ERROR BIOSIG4C++ SOPEN(read): Dataformat not known.\n"); ifclose(hdr); return(hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION); count = iftell(hdr); hdr->AS.first = 0; hdr->AS.length = 0; hdr->AS.bpb = -1; // errorneous value: ensures that hdr->AS.bpb will be defined #ifndef WITHOUT_NETWORK if (!memcmp(hdr->AS.Header,"bscs://",7)) { hdr->AS.Header[count]=0; uint64_t ID; char *hostname = Header1+7; Header1[6]=0; char *t = strrchr(hostname,'/'); if (t==NULL) { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "SOPEN-NETWORK: file identifier not specifed"); return(hdr); } t[0]=0; cat64(t+1, &ID); int sd,s; sd = bscs_connect(hostname); if (sd<0) { fprintf(stderr,"could not connect to %s\n",hostname); biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "could not connect to server"); return(hdr); } hdr->FILE.Des = sd; s = bscs_open(sd, &ID); s = bscs_requ_hdr(sd,hdr); s = bscs_requ_evt(sd,hdr); hdr->FILE.OPEN = 1; return(hdr); } else #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION); if (hdr->TYPE == GDF) { struct stat FileBuf; if (stat(hdr->FileName,&FileBuf)==0) hdr->FILE.size = FileBuf.st_size; if ( read_header(hdr) ) { return (hdr); } } #ifndef ONLYGDF else if ((hdr->TYPE == EDF) || (hdr->TYPE == BDF)) { if (count < 256) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, "reading BDF/EDF fixed header failed"); return(hdr); } typeof(hdr->NS) StatusChannel = 0; int annotStartBi=-1; int annotEndBi=-1; int annotNumBytesPerBlock=0; int last = min(MAX_LENGTH_PID, 80); strncpy(hdr->Patient.Id, Header1+8, last); while ((0 <= last) && (isspace(hdr->Patient.Id[--last]))); hdr->Patient.Id[last+1]=0; last = min(MAX_LENGTH_RID, 80); memcpy(hdr->ID.Recording, Header1+88, last); while ((0 <= last) && (isspace(hdr->ID.Recording[--last]))); hdr->ID.Recording[last+1]=0; if (VERBOSE_LEVEL>8) fprintf(stdout,"[EDF 211] #=%li\nT0=<%16s>",iftell(hdr),Header1+168); // TODO: sanity check of T0 char tmp[81]; memset(tmp,0,9); strncpy(tmp,Header1+168+14,2); tm_time.tm_sec = atoi(tmp); strncpy(tmp,Header1+168+11,2); tm_time.tm_min = atoi(tmp); strncpy(tmp,Header1+168+8,2); tm_time.tm_hour = atoi(tmp); strncpy(tmp,Header1+168,2); tm_time.tm_mday = atoi(tmp); strncpy(tmp,Header1+168+3,2); tm_time.tm_mon = atoi(tmp)-1; strncpy(tmp,Header1+168+6,2); tm_time.tm_year = atoi(tmp); tm_time.tm_year+= (tm_time.tm_year < 70 ? 100 : 0); hdr->EVENT.N = 0; memset(tmp,0,9); hdr->NS = atoi(memcpy(tmp,Header1+252,4)); hdr->HeadLen = atoi(memcpy(tmp,Header1+184,8)); if (hdr->HeadLen < ((hdr->NS+1u)*256)) { biosigERROR(hdr, B4C_UNSPECIFIC_ERROR, "EDF/BDF corrupted: HDR.NS and HDR.HeadLen do not fit"); if (VERBOSE_LEVEL > 7) fprintf(stdout,"HeadLen=%i,%i\n",hdr->HeadLen ,(hdr->NS+1)<<8); }; hdr->NRec = atoi(strncpy(tmp,Header1+236,8)); //Dur = atof(strncpy(tmp,Header1+244,8)); if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211b] #=%li\nT0=%s\n",iftell(hdr),asctime(&tm_time)); if (!strncmp(Header1+192,"EDF+",4)) { if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211c+] <%s>\n",hdr->Patient.Id); strtok(hdr->Patient.Id," "); ptr_str = strtok(NULL," "); if (ptr_str!=NULL) { // define Id, Sex, Birthday, Name if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211c+] <%p>\n",ptr_str); hdr->Patient.Sex = (ptr_str[0]=='f')*2 + (ptr_str[0]=='F')*2 + (ptr_str[0]=='M') + (ptr_str[0]=='m'); ptr_str = strtok(NULL," "); // startdate char *tmpptr = strtok(NULL," "); if ((!hdr->FLAG.ANONYMOUS) && (tmpptr != NULL)) { strncpy(hdr->Patient.Name,tmpptr,MAX_LENGTH_NAME); hdr->Patient.Name[MAX_LENGTH_NAME]=0; } if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211c] #=%li\n",iftell(hdr)); if (strlen(ptr_str)==11) { struct tm t1; char *strMDay=strtok(ptr_str,"-"); char *strMonth=strtok(NULL,"-"); char *strYear=strtok(NULL,"-"); for (k=0; strMonth[k]>0; ++k) strMonth[k]= toupper(strMonth[k]); // convert to uppper case t1.tm_mday = atoi(strMDay); t1.tm_mon = month_string2int(strMonth); t1.tm_year = atoi(strYear) - 1900; t1.tm_sec = 0; t1.tm_min = 0; t1.tm_hour = 12; t1.tm_isdst= -1; hdr->Patient.Birthday = tm_time2gdf_time(&t1); }} if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211d] <%s>\n",hdr->ID.Recording); if (!strncmp(Header1+88,"Startdate ",10)) { size_t pos = strcspn(Header1+88+10," ")+10; strncpy(hdr->ID.Recording, Header1+88+pos+1, 80-pos); hdr->ID.Recording[80-pos-1] = 0; if (strtok(hdr->ID.Recording," ")!=NULL) { char *tech = strtok(NULL," "); if (hdr->ID.Technician) free(hdr->ID.Technician); hdr->ID.Technician = (tech != NULL) ? strdup(tech) : NULL; hdr->ID.Manufacturer.Name = strtok(NULL," "); } Header1[167]=0; strtok(Header1+88," "); ptr_str = strtok(NULL," "); // check EDF+ Startdate against T0 if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211e-] <%s>\n",ptr_str); /* TODO: fix "Startdate X ..." */ if (strcmp(ptr_str,"X")) { int d,m,y; d = atoi(strtok(ptr_str,"-")); if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211e] <%s>\n",ptr_str); ptr_str = strtok(NULL,"-"); if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211f] <%s>\n",ptr_str); strcpy(tmp,ptr_str); for (k=0; k7) fprintf(stdout,"[EDF 211g] <%s>\n",tmp); y = atoi(strtok(NULL,"-")) - 1900; if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211h] <%i>\n",tm_time.tm_year); if ((tm_time.tm_mday == d) && (tm_time.tm_mon == m)) { tm_time.tm_year = y; tm_time.tm_isdst= -1; } else { fprintf(stderr,"Error SOPEN(EDF+): recording dates do not match %i/%i <> %i/%i\n",d,m,tm_time.tm_mday,tm_time.tm_mon); } } } if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 211z] #=%li\n",iftell(hdr)); } hdr->T0 = tm_time2gdf_time(&tm_time); // note: sub-second information will be extracted from first annotation if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 212] #=%li\n",iftell(hdr)); if (hdr->NS==0) return(hdr); hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); hdr->AS.Header = (uint8_t*) realloc(Header1,hdr->HeadLen); char *Header2 = (char*)hdr->AS.Header+256; if (hdr->HeadLen > count) count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); if (count < hdr->HeadLen) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, "reading BDF/EDF variable header failed"); return(hdr); } /* identify buggy NeuroLoggerEDF export with bytes 236-257 EDF requires that the fields are left-justified, thus the first byte should be different than a space Therefore, the probability of a false positive detection is highly unlikely. */ char FLAG_BUGGY_NEUROLOGGER_EDF = !strncmp(Header1+236," 1 0 8 ",21) && Header1[0x180]==' ' && Header1[0x7c0]==' ' && Header1[0x400]==' ' && Header1[0x440]==' ' && Header1[0x480]==' ' && Header1[0x4c0]==' ' && Header1[0x500]==' '; if (FLAG_BUGGY_NEUROLOGGER_EDF) for (k=236; k<9*256; k++) Header1[k-1]=Header1[k]; char p[9]; hdr->AS.bpb = 0; size_t BitsPerBlock = 0; for (k=0, hdr->SPR = 1; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 213] #%i/%i\n",(int)k,hdr->NS); hc->LeadIdCode = 0; last = min(MAX_LENGTH_LABEL, 16); strncpy(hc->Label, Header2 + 16*k, last); while ((0 <= last) && (isspace(hc->Label[--last]))) ; hc->Label[last+1]=0; last = min(80,MAX_LENGTH_TRANSDUCER); strncpy(hc->Transducer, Header2+80*k+16*hdr->NS, last); while ((0 <= last) && (isspace(hc->Transducer[--last]))); hc->Transducer[last+1]=0; // PhysDim -> PhysDimCode last = 8; memcpy(p,Header2 + 8*k + 96*hdr->NS, last); while ((0 <= last) && (isspace(p[--last]))); p[last+1]=0; hc->PhysDimCode = PhysDimCode(p); tmp[8] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 215a] #%i/%i\n",(int)k,hdr->NS); hc->PhysMin = atof(strncpy(tmp,Header2 + 8*k + 104*hdr->NS,8)); hc->PhysMax = atof(strncpy(tmp,Header2 + 8*k + 112*hdr->NS,8)); hc->DigMin = atof(strncpy(tmp,Header2 + 8*k + 120*hdr->NS,8)); hc->DigMax = atof(strncpy(tmp,Header2 + 8*k + 128*hdr->NS,8)); if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 215b] #%i/%i\n",(int)k,hdr->NS); hc->Cal = (hc->PhysMax - hc->PhysMin) / (hc->DigMax-hc->DigMin); hc->Off = hc->PhysMin - hc->Cal*hc->DigMin; if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 215c] #%i: NS=%i NRec=%i \n",(int)k,hdr->NS,(int)hdr->NRec); hc->LeadIdCode = 0; hc->SPR = atol(strncpy(tmp, Header2 + 8*k + 216*hdr->NS, 8)); hc->GDFTYP = ((hdr->TYPE != BDF) ? 3 : 255+24); hc->OnOff = 1; hc->bi = hdr->AS.bpb; hc->bi8 = BitsPerBlock; size_t nbits = GDFTYP_BITS[hc->GDFTYP]*(size_t)hc->SPR; BitsPerBlock += nbits; uint32_t nbytes = nbits>>3; hdr->AS.bpb += nbytes; if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 216] #%i/%i/%i/%i/%i/%i\n",(int)k,hdr->NS,nbytes,hdr->AS.bpb,hc->SPR,hdr->SPR); hc->LowPass = NAN; hc->HighPass = NAN; hc->Notch = NAN; hc->TOffset = NAN; hc->Impedance = NAN; // decode filter information into hdr->Filter.{Lowpass, Highpass, Notch} uint8_t kk; char PreFilt[81]; strncpy(PreFilt, Header2+ 80*k + 136*hdr->NS, 80); for (kk=0; kk<80; kk++) PreFilt[kk] = toupper(PreFilt[kk]); PreFilt[80] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"#%i# <%s>\n",(int)k,PreFilt); char *s1; s1 = strstr(PreFilt,"HP:"); if (s1) hc->HighPass = strtod(s1+3, &s1); s1 = strstr(PreFilt,"LP:"); if (s1) hc->LowPass = strtod(s1+3, &s1); s1 = strstr(PreFilt,"NOTCH:"); if (s1) hc->Notch = strtod(s1+6, &s1); if (VERBOSE_LEVEL>7) fprintf(stdout,"#%i# HP: %fHz LP:%fHz NOTCH=%f\n",(int)k,hc->HighPass,hc->LowPass,hc->Notch); if ((hdr->TYPE==EDF) && !strcmp(hc->Label,"EDF Annotations")) { hc->OnOff = 0; if (annotStartBi < 0) annotStartBi = hc->bi; annotEndBi = hdr->AS.bpb; annotNumBytesPerBlock += nbytes; } else if ((hdr->TYPE==BDF) && !strcmp(hc->Label,"BDF Annotations")) { hc->OnOff = 0; if (annotStartBi < 0) annotStartBi = hc->bi; annotEndBi = hdr->AS.bpb; annotNumBytesPerBlock += nbytes; } if ((hdr->TYPE==BDF) && !strcmp(hc->Label,"Status")) { hc->OnOff = 0; StatusChannel = k+1; } if (hc->OnOff) { // common sampling rate is based only on date channels but not annotation channels hdr->SPR = lcm(hdr->SPR, hc->SPR); } if (VERBOSE_LEVEL>7) fprintf(stdout,"[EDF 219] #%i/%i/%i\n",(int)k,hdr->NS,hdr->SPR); } hdr->FLAG.OVERFLOWDETECTION = 0; // EDF does not support automated overflow and saturation detection double Dur = atof(strncpy(tmp,Header1+244,8)); if (Dur==0.0 && FLAG_BUGGY_NEUROLOGGER_EDF) Dur = hdr->SPR/496.0; hdr->SampleRate = hdr->SPR/Dur; if (VERBOSE_LEVEL>8) fprintf(stdout,"[EDF 220] #=%i SPR=%i Dur=%g\n",(int)iftell(hdr),(int)hdr->SPR, Dur); if (hdr->NRec <= 0) { struct stat FileBuf; stat(hdr->FileName,&FileBuf); hdr->NRec = (FileBuf.st_size - hdr->HeadLen)/hdr->AS.bpb; } if (annotStartBi + annotNumBytesPerBlock - annotEndBi) fprintf(stdout, "WARNING: this file has multiple non-contigous blocks of EDF+/BDF+ annotations channels - annotation channels are not decoded"); else { /* read Annotation and Status channel and extract event information */ size_t bpb = annotNumBytesPerBlock; size_t len = bpb * hdr->NRec; uint8_t *Marker = (uint8_t*)malloc(len + 1); size_t skip = hdr->AS.bpb - bpb; ifseek(hdr, hdr->HeadLen + annotStartBi, SEEK_SET); nrec_t k3; for (k3=0; k3NRec; k3++) { ifread(Marker+k3*bpb, 1, bpb, hdr); ifseek(hdr, skip, SEEK_CUR); } Marker[hdr->NRec*bpb] = 20; // terminating marker size_t N_EVENT = 0; hdr->EVENT.SampleRate = hdr->SampleRate; /* convert EDF+/BDF+ annotation channel into event table */ char flag_subsec_isset = 0; for (k3 = 0; k3 < hdr->NRec; k3++) { double timeKeeping = 0; char *line = (char*)(Marker + k3 * bpb); char flag = !strncmp(Header1+193,"DF+D",4); // no time keeping for EDF+C while (line < (char*)(Marker + (k3+1) * bpb)) { // loop through all annotations within a segment if (VERBOSE_LEVEL>7) fprintf(stdout,"EDF+ line<%s>\n",line); char *next = strchr(line,0); // next points to end of annotation char *s1 = strtok(line,"\x14"); char *s2 = strtok(NULL,"\x14"); char *s3 = strtok(NULL,"\x14"); char *tstr = strtok(s1,"\x14\x15"); char *durstr = strtok(NULL,"\x14\x15"); if (tstr==NULL) { // TODO: check whether this is needed based on the EDF+ specs or whether it is an incorrect fprintf(stderr,"Warning EDF+ events: tstr not defined\n"); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i): EDF+ line<%s>\n",__FILE__,__LINE__,line); break; } double t = atof(tstr); /* set sub-second start time: see also https://github.com/mne-tools/mne-python/pull/7875 https://www.edfplus.info/specs/edfplus.html#tal */ if ( !flag_subsec_isset && (s2==NULL) && (tstr[0]=='+' || tstr[0]=='-' ) ) { // first t contains subsecond information of starttime if (VERBOSE_LEVEL>7) fprintf(stdout,"T0=%20f + %f s\n",ldexp(hdr->T0,-32)*24*3600,t); hdr->T0 += ldexp(t / (24 * 3600.0), +32); if (VERBOSE_LEVEL>7) fprintf(stdout,"T0=%20f\n", ldexp(hdr->T0,-32) * 24 * 3600); } flag_subsec_isset = 1; if (flag>0 || s2!=NULL) { if (N_EVENT <= hdr->EVENT.N+1) { N_EVENT = reallocEventTable(hdr, max(6,hdr->EVENT.N*2)); if (N_EVENT == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } /* This is a workaround to read BDF data with large number of free text events containing meta information Free text is limited to the first occurence of limiter character, default is "\0" which does not remove anything */ s2 = strtok(s2, biosig_options->free_text_event_limiter); switch (flag) { case 0: // EDF+C FreeTextEvent(hdr, hdr->EVENT.N, s2); // set hdr->EVENT.TYP hdr->EVENT.POS[hdr->EVENT.N] = round(t * hdr->EVENT.SampleRate); break; case 1: // EDF+D: marker for beginning of segment hdr->EVENT.TYP[hdr->EVENT.N] = 0x7ffe; hdr->EVENT.POS[hdr->EVENT.N] = k3 * hdr->SPR; timeKeeping = t; flag = 2; break; default: // EDF+D: real annotation FreeTextEvent(hdr, hdr->EVENT.N, s2); // set hdr->EVENT.TYP hdr->EVENT.POS[hdr->EVENT.N] = k3 * hdr->SPR + round((t-timeKeeping) * hdr->EVENT.SampleRate); break; } #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = hdr->T0 + ldexp(t/(24*3600),32); #endif hdr->EVENT.DUR[hdr->EVENT.N] = durstr ? (atof(durstr)*hdr->EVENT.SampleRate) : 0; hdr->EVENT.CHN[hdr->EVENT.N] = 0; hdr->EVENT.N++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"EDF+ event\n\ts1:\t<%s>\n\ts2:\t<%s>\n\ts3:\t<%s>\n\tsdelay:\t<%s>\n\tdur:\t<%s>\n\t\n",s1,s2,s3,tstr,durstr); for (line=next; *line==0; line++) {}; // skip \0's and set line to start of next annotation } } hdr->AS.auxBUF = Marker; // contains EVENT.CodeDesc strings } /* End reading if Annotation channel */ if (StatusChannel) { /* read Status channel and extract event information */ CHANNEL_TYPE *hc = hdr->CHANNEL+StatusChannel-1; size_t sz = GDFTYP_BITS[hc->GDFTYP]>>3; size_t len = hc->SPR * hdr->NRec * sz; uint8_t *Marker = (uint8_t*)malloc(len + 1); size_t skip = hdr->AS.bpb - hc->SPR * sz; ifseek(hdr, hdr->HeadLen + hc->bi, SEEK_SET); nrec_t k3; for (k3=0; k3NRec; k3++) { ifread(Marker+k3*hc->SPR * sz, 1, hc->SPR * sz, hdr); ifseek(hdr, skip, SEEK_CUR); } size_t N_EVENT = 0; hdr->EVENT.SampleRate = hdr->SampleRate; /* convert BDF status channel into event table*/ uint32_t d1, d0; for (d0=0, k=0; k < len/3; d0 = d1, k++) { d1 = ((uint32_t)Marker[3*k+2]<<16) + ((uint32_t)Marker[3*k+1]<<8) + (uint32_t)Marker[3*k]; /* count raising edges */ if (d1 & 0x010000) d1 = 0; else d1 &= 0x00ffff; if (d0 < d1) ++N_EVENT; /* raising and falling edges if ((d1 & 0x010000) != (d0 & 0x010000)) ++N_EVENT; if ((d1 & 0x00ffff) != (d0 & 0x00ffff)) ++N_EVENT; */ } hdr->EVENT.POS = (uint32_t*)realloc(hdr->EVENT.POS, (hdr->EVENT.N + N_EVENT) * sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*)realloc(hdr->EVENT.TYP, (hdr->EVENT.N + N_EVENT) * sizeof(*hdr->EVENT.TYP)); if (hdr->EVENT.POS==NULL || hdr->EVENT.TYP==NULL) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); } for (d0=0, k=0; k < len/3; d0=d1, k++) { d1 = ((uint32_t)Marker[3*k+2]<<16) + ((uint32_t)Marker[3*k+1]<<8) + (uint32_t)Marker[3*k]; /* raising edges */ if (d1 & 0x010000) d1 = 0; else d1 &= 0x00ffff; if (d0 < d1) { hdr->EVENT.POS[hdr->EVENT.N] = k; // 0-based indexing hdr->EVENT.TYP[hdr->EVENT.N] = d1; ++hdr->EVENT.N; } /* raising and falling edges if ((d1 & 0x010000) != (d0 & 0x010000)) { hdr->EVENT.POS[hdr->EVENT.N] = k; // 0-based indexing hdr->EVENT.TYP[hdr->EVENT.N] = 0x7ffe; ++hdr->EVENT.N; } if ((d1 & 0x00ffff) != (d0 & 0x00ffff)) { hdr->EVENT.POS[hdr->EVENT.N] = k; // 0-based indexing uint16_t d2 = d1 & 0x00ffff; if (!d2) d2 = (uint16_t)(d0 & 0x00ffff) | 0x8000; hdr->EVENT.TYP[hdr->EVENT.N] = d2; ++hdr->EVENT.N; if (d2==0x7ffe) fprintf(stdout,"Warning: BDF file %s uses ambiguous code 0x7ffe; For details see file eventcodes.txt. \n",hdr->FileName); } */ } free(Marker); } /* End reading BDF Status channel */ ifseek(hdr, hdr->HeadLen, SEEK_SET); } else if (hdr->TYPE==ABF) { hdr->HeadLen = count; sopen_abf_read(hdr); } else if (hdr->TYPE==ABF2) { hdr->HeadLen = count; sopen_abf2_read(hdr); } else if (hdr->TYPE==ATF) { // READ ATF hdr->HeadLen = count; hdr->VERSION = atof((char*)(hdr->AS.Header+4)); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION); if (hdr->FILE.COMPRESSION) { biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "compressed ATF file format not supported"); return hdr; } sopen_atf_read(hdr); } else if (hdr->TYPE==ACQ) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: try loading ACQ header \n", __FILE__, __LINE__, __func__); if ( !hdr->FILE.LittleEndian ) { hdr->NS = bei16p(hdr->AS.Header + 10); hdr->HeadLen += hdr->NS*1714; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s (..): v%g noChan=%u HeadLen=%u\n", \ __FILE__, __LINE__, __func__, hdr->VERSION, hdr->NS, hdr->HeadLen); biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "BigEndian ACQ file format is currently not supported"); return(hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s \n", __FILE__, __LINE__, __func__); /* defined in http://biopac.com/AppNotes/app156FileFormat/FileFormat.htm */ hdr->NS = lei16p(hdr->AS.Header+10); hdr->SampleRate = 1000.0/lef64p(hdr->AS.Header+16); hdr->NRec = 1; hdr->SPR = 1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s \n", __FILE__, __LINE__, __func__); // add "per channel data section" if (hdr->VERSION<38.0) // Version 3.0+ hdr->HeadLen += hdr->NS*122; else if (hdr->VERSION<39.0) // Version 3.7.0+ hdr->HeadLen += hdr->NS*252; else if (hdr->VERSION<42.0) // Version 3.7.3+ hdr->HeadLen += hdr->NS*254; else if (hdr->VERSION<43.0) // Version 3.7.3+ hdr->HeadLen += hdr->NS*256; else // Version 3.8.2+ hdr->HeadLen += hdr->NS*262; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s \n", __FILE__, __LINE__, __func__); hdr->HeadLen += 4; // read header up to nLenght and nID of foreign data section hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, hdr->HeadLen); if (hdr->HeadLen > count) count += ifread(Header1+count, 1, hdr->HeadLen-count, hdr); uint32_t POS = hdr->HeadLen; // read "foreign data section" and "per channel data types section" hdr->HeadLen += leu16p(hdr->AS.Header + hdr->HeadLen-4) - 4; // read "foreign data section" and "per channel data types section" hdr->HeadLen += 4*hdr->NS; hdr->AS.Header = (uint8_t*)realloc(Header1, hdr->HeadLen+8); if (hdr->HeadLen > POS) count += ifread(Header1+POS, 1, hdr->HeadLen-POS, hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s %i/%i %i/%i %i/%i %i/%i %i/%i \n", \ __FILE__, __LINE__, __func__, \ leu16p(hdr->AS.Header+hdr->HeadLen-20), leu16p(hdr->AS.Header+hdr->HeadLen-18), \ leu16p(hdr->AS.Header+hdr->HeadLen-16), leu16p(hdr->AS.Header+hdr->HeadLen-14), \ leu16p(hdr->AS.Header+hdr->HeadLen-12), leu16p(hdr->AS.Header+hdr->HeadLen-10), \ leu16p(hdr->AS.Header+hdr->HeadLen-8), leu16p(hdr->AS.Header+hdr->HeadLen-6), \ leu16p(hdr->AS.Header+hdr->HeadLen-4), leu16p(hdr->AS.Header+hdr->HeadLen-2) \ ); // define channel specific header information hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); uint32_t* ACQ_NoSamples = (uint32_t*) calloc(hdr->NS, sizeof(uint32_t)); //uint16_t CHAN; POS = leu32p(hdr->AS.Header+6); size_t minBufLenXVarDiv = -1; // maximum integer value for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; uint8_t* Header2 = hdr->AS.Header+POS; hc->LeadIdCode = 0; hc->Transducer[0] = '\0'; //CHAN = leu16p(Header2+4); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: #%i %i %i %i %i\n", \ __FILE__, __LINE__, __func__, (int)k, (int)leu32p(Header2), (int)leu16p(Header2+4), (int)leu32p(Header2+88), (int)leu16p(Header2+250)); int len=min(MAX_LENGTH_LABEL,40); strncpy(hc->Label,(char*)Header2+6,len); hc->Label[len]=0; char tmp[21]; strncpy(tmp,(char*)Header2+68,20); tmp[20]=0; /* ACQ uses none-standard way of encoding physical units Convert to ISO/IEEE 11073-10101 */ if (!strcmp(tmp,"Volts")) hc->PhysDimCode = 4256; else if (!strcmp(tmp,"Seconds")) hc->PhysDimCode = 2176; else if (!strcmp(tmp,"deg C")) hc->PhysDimCode = 6048; else if (!strcmp(tmp,"microsiemen")) hc->PhysDimCode = 8307; else hc->PhysDimCode = PhysDimCode(tmp); hc->Off = lef64p(Header2+52); hc->Cal = lef64p(Header2+60); hc->OnOff = 1; hc->SPR = 1; if (hdr->VERSION >= 38.0) { hc->SPR = leu16p(Header2+250); // used here as Divider if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: %i:%i\n", __FILE__, __LINE__, __func__, (int)hdr->SPR, (int)hc->SPR); if (hc->SPR > 1) hdr->SPR = lcm(hdr->SPR, hc->SPR); else hc->SPR = 1; } ACQ_NoSamples[k] = leu32p(Header2+88); size_t tmp64 = leu32p(Header2+88) * hc->SPR; if (minBufLenXVarDiv > tmp64) minBufLenXVarDiv = tmp64; POS += leu32p((uint8_t*)Header2); } hdr->NRec = minBufLenXVarDiv; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i\n", __FILE__, __LINE__, __func__, POS); /// foreign data section - skip POS += leu16p(hdr->AS.Header+POS); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); if (POS+2 > count) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, POS+2); count += ifread(Header1+count, 1, POS+2-count, hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i\n", __FILE__, __LINE__, __func__, POS); size_t DataLen=0; for (k=0, hdr->AS.bpb=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if ((hdr->VERSION>=38.0) && (hc->SPR > 1)) hc->SPR = hdr->SPR/hc->SPR; // convert DIVIDER into SPR uint16_t u16 = leu16p(hdr->AS.Header+POS+2); switch (u16) { case 1: hc->GDFTYP = 17; // double DataLen += ACQ_NoSamples[k]<<3; hc->DigMax = 1e9; hc->DigMin = -1e9; break; case 2: hc->GDFTYP = 3; // int DataLen += ACQ_NoSamples[k]<<1; hc->DigMax = 32767; hc->DigMin = -32678; break; default: if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: #%i type=%i \n", __FILE__, __LINE__, __func__, (int)k, (int)u16); biosigERROR(hdr, B4C_UNSPECIFIC_ERROR, "SOPEN(ACQ-READ): invalid channel type."); }; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->bi = hdr->AS.bpb; hdr->AS.bpb += (GDFTYP_BITS[hc->GDFTYP]*hc->SPR)>>3; POS +=4; } free(ACQ_NoSamples); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); /// Markers header section - skip POS += leu16p(hdr->AS.Header+POS); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); if (POS+2 > count) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, POS+2); count += ifread(Header1+count, 1, POS+2-count, hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); /// Markers header section - skip POS += leu16p(hdr->AS.Header+POS); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); if (POS+2 > count) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i,%i\n", __FILE__, __LINE__, __func__, (int)POS, (int)count); hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, POS+2); count += ifread(Header1+count, 1, POS+2-count, hdr); } // hdr->HeadLen = count + 1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s: POS=%i HeadLen=%i\n", __FILE__, __LINE__, __func__, POS, (int)hdr->HeadLen); /* ### FIXME ### reading Marker section POS = hdr->HeadLen; #ifdef ZLIB_H gzseek(hdr->FILE.FID, hdr->HeadLen+DataLen, SEEK_SET); // start of markers header section count = gzread(hdr->FILE.FID, Header1+POS, 8); #else fseek(hdr->FILE.FID, hdr->HeadLen+DataLen, SEEK_SET); // start of markers header section count = fread(Header1+POS, 1, 8, hdr->FILE.FID); #endif size_t LengthMarkerItemSection = (leu32p(Header1+POS)); hdr->EVENT.N = (leu32p(Header1+POS+4)); Header1 = (char*)realloc(Header1,hdr->HeadLen+8+LengthMarkerItemSection); POS += 8; #ifdef ZLIB_H count = gzread(hdr->FILE.FID, Header1+POS, LengthMarkerItemSection); #else count = fread(Header1+POS, 1, LengthMarkerItemSection, hdr->FILE.FID); #endif hdr->EVENT.TYP = (uint16_t*)calloc(hdr->EVENT.N,2); hdr->EVENT.POS = (uint32_t*)calloc(hdr->EVENT.N,4); for (k=0; kEVENT.N; k++) { fprintf(stdout,"ACQ EVENT: %i POS: %i\n",k,POS); hdr->EVENT.POS[k] = leu32p(Header1+POS); POS += 12 + leu16p(Header1+POS+10); } */ ifseek(hdr, hdr->HeadLen, SEEK_SET); } else if (hdr->TYPE==AINF) { ifclose(hdr); char *filename = hdr->FileName; // keep input file name char* tmpfile = (char*)calloc(strlen(hdr->FileName)+5,1); strcpy(tmpfile, hdr->FileName); // Flawfinder: ignore char* ext = strrchr(tmpfile,'.')+1; /* open and read header file */ strcpy(ext,"ainf"); hdr->FileName = tmpfile; hdr = ifopen(hdr,"rb"); count = 0; while (!ifeof(hdr)) { size_t bufsiz = max(2*count, PAGESIZE); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); char *t1= NULL; char *t = strtok((char*)hdr->AS.Header,"\xA\xD"); while ((t) && !strncmp(t,"#",1)) { char* p; if ((p = strstr(t,"sfreq ="))) t1 = p; t = strtok(NULL,"\xA\xD"); } hdr->SampleRate = atof(strtok(t1+7," ")); hdr->SPR = 1; hdr->NS = 0; hdr->AS.bpb = 4; while (t) { int chno1=-1, chno2=-1; double f1,f2; char *label = NULL; #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L sscanf(t,"%d %as %d %lf %lf",&chno1,&label,&chno2,&f1,&f2); #else sscanf(t,"%d %ms %d %lf %lf",&chno1,&label,&chno2,&f1,&f2); #endif k = hdr->NS++; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); CHANNEL_TYPE *hc = hdr->CHANNEL+k; snprintf(hc->Label, MAX_LENGTH_LABEL+1, "%s %03i",label, chno2); hc->Transducer[0] = 0; hc->LeadIdCode = 0; hc->SPR = 1; hc->Cal = f1*f2; hc->Off = 0.0; hc->OnOff = 1; hc->GDFTYP = 3; hc->DigMax = 32767; hc->DigMin = -32678; hc->PhysMax= hc->DigMax * hc->Cal + hc->Off; hc->PhysMin= hc->DigMin * hc->Cal + hc->Off; hc->bi = hdr->AS.bpb; hdr->AS.bpb += 2; if (strcmp(label,"MEG")==0) hc->PhysDimCode = 1446; // "T/m" else hc->PhysDimCode = 4256; // "V" if (label) free(label); t = strtok(NULL,"\x0a\x0d"); } /* open data file */ strcpy(ext,"raw"); struct stat FileBuf; stat(hdr->FileName,&FileBuf); hdr = ifopen(hdr,"rb"); hdr->NRec = FileBuf.st_size/hdr->AS.bpb; hdr->HeadLen = 0; // hdr->FLAG.SWAP = (__BYTE_ORDER == __LITTLE_ENDIAN); // AINF is big endian hdr->FILE.LittleEndian = 0; /* restore input file name, and free temporary file name */ hdr->FileName = filename; free(tmpfile); } else if (hdr->TYPE==alpha) { ifclose(hdr); // close already opened file (typically its .../alpha.alp) sopen_alpha_read(hdr); } else if (hdr->TYPE==AXG) { sopen_axg_read(hdr); } else if (hdr->TYPE==Axona) { fprintf(stdout, "Axona: alpha version. \n"); hdr->AS.bpb = 12 + 20 + 2 * 192 + 16; hdr->NS = 4 + 64; hdr->SPR = 3; hdr->SampleRate = 24e3; struct stat FileBuf; if (stat(hdr->FileName, &FileBuf)==0) hdr->FILE.size = FileBuf.st_size; hdr->NRec = hdr->FILE.size / hdr->AS.bpb; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); CHANNEL_TYPE *hc; for (k = 0; k < hdr->NS; k++) { hc = hdr->CHANNEL + k; // hc->PhysDimCode = 4256; // "V" hc->PhysDimCode = 0; hc->Transducer[0] = 0; hc->LeadIdCode = 0; hc->SPR = hdr->SPR; hc->Cal = 1.0; hc->Off = 0.0; hc->OnOff = 1; hc->LeadIdCode = 0; hc->Notch = NAN; hc->LowPass = NAN; hc->HighPass = NAN; } for (k = 0; k+4 < hdr->NS; k++) { hc = hdr->CHANNEL + k + 4; sprintf(hc->Label, "#%02i", (int)k+1); hc->PhysDimCode = 4256; // "V" hc->PhysDimCode = 4274; // "mV" hc->PhysDimCode = 4275; // "uV" hc->GDFTYP = 3; hc->DigMax = 32767; hc->DigMin = -32678; hc->bi = 32 + 2*k; } hc = hdr->CHANNEL; strcpy(hc->Label, "PacketNumber"); hc->SPR = 1; hc->GDFTYP = 6; // uint32 hc->DigMin = 0.0; hc->DigMax = ldexp(1.0, 32) - 1.0; hc->bi = 4; hc = hdr->CHANNEL + 1; strcpy(hc->Label, "Digital I/O"); hc->SPR = 1; hc->GDFTYP = 6; // uint32 hc->DigMin = 0.0; hc->DigMax = ldexp(1.0, 32) - 1.0; hc->bi = 8; hc = hdr->CHANNEL + 2; strcpy(hc->Label, "FunKey"); hc->SPR = 1; hc->GDFTYP = 2; // uint8 hc->DigMin = 0.0; hc->DigMax = 255.0; hc->bi = 416; hc = hdr->CHANNEL + 3; strcpy(hc->Label, "Key Code"); hc->SPR = 1; hc->GDFTYP = 2; // uint8 hc->DigMin = 0.0; hc->DigMax = 255.0; hc->bi = 417; for (k = 0; k < hdr->NS; k++) { hc = hdr->CHANNEL + k; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; } hdr->HeadLen = 0; ifseek(hdr, 0, SEEK_SET); HDRTYPE H1; H1.FILE.COMPRESSION = 1; // try always with zlib, libz reverts to no compression anyway. H1.FileName = malloc(strlen(hdr->FileName)+5); strcpy(H1.FileName, hdr->FileName); // Flawfinder: ignore char *e = strrchr(H1.FileName,'.'); if (e==NULL) e = H1.FileName+strlen(H1.FileName); strcpy(e,".set"); ifopen(&H1, "r"); unsigned MaxLineLen = 1000; char *line = malloc(MaxLineLen); double PhysMax = NAN; //char* ifgets(char *str, int n, HDRTYPE* hdr) { while (!ifeof(&H1)) { ifgets(line, MaxLineLen, &H1); if (MaxLineLen <= strlen(line)) { fprintf(stderr,"Warning (Axona): line ## in file <%s> exceeds maximum length\n",H1.FileName); } char *tag = strtok(line," \t\n\r"); char *val = strtok(NULL,"\n\r"); if (tag==NULL || val==NULL) ; else if (!strcmp(tag,"trial date")) ; else if (!strcmp(tag,"trial time")) ; else if (!strcmp(tag,"experimenter")) hdr->ID.Technician = strdup(val); else if (!strcmp(tag,"sw_version")) ; else if (!strcmp(tag,"ADC_fullscale_mv")) { char *e; PhysMax = strtod(val, &e); if (e==NULL) continue; // ignore value because its invalid } else if (!strncmp(tag,"gain_ch_",4)) { char *e; size_t ch = strtol(tag+8, &e, 10); if (e==NULL || ch >= hdr->NS) continue; // ignore value because its invalid double Cal = strtod(val, &e); if (e==NULL) continue; // ignore value because its invalid hdr->CHANNEL[ch].Cal = 1.0/Cal; hdr->CHANNEL[ch].Off = 0.0; hdr->CHANNEL[ch].PhysMax = +PhysMax; hdr->CHANNEL[ch].PhysMin = -PhysMax; hdr->CHANNEL[ch].DigMax = +PhysMax/Cal; hdr->CHANNEL[ch].DigMin = -PhysMax/Cal; } else if (!strcmp(tag,"rawRate")) { char *e; double fs = strtod(val, &e); if (e==NULL) continue; // ignore value because its invalid hdr->SampleRate = fs; } else if (!strcmp(tag,"")) { ; } } free(line); ifclose(&H1); free(H1.FileName); } else if ((hdr->TYPE==ASCII) || (hdr->TYPE==BIN)) { while (!ifeof(hdr)) { size_t bufsiz = 65536; hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,count+bufsiz+1); count += ifread(hdr->AS.Header+count,1,bufsiz,hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); hdr->NS = 0; hdr->NRec = 1; hdr->SPR = 1; hdr->AS.bpb = 0; double Fs = 1.0; size_t N = 0; char status = 0; char *val = NULL; const char sep[] = " =\x09"; double duration = 0; size_t lengthRawData = 0; uint8_t FLAG_NUMBER_OF_FIELDS_READ; // used to trigger consolidation of channel info CHANNEL_TYPE *cp = NULL; char *datfile = NULL; uint16_t gdftyp = 0; char *line = strtok((char*)hdr->AS.Header,"\x0a\x0d"); while (line!=NULL) { if (VERBOSE_LEVEL>7) fprintf(stdout,"ASCII read line [%i]: <%s>\n",status,line); if (!strncmp(line,"[Header 1]",10)) status = 1; else if (!strncmp(line,"[Header 2]",10)) { status = 2; hdr->NS = 0; FLAG_NUMBER_OF_FIELDS_READ=0; } else if (!strncmp(line,"[EVENT TABLE]",13)) { status = 3; hdr->EVENT.SampleRate = hdr->SampleRate; N = 0; } val = strchr(line,'='); if ((val != NULL) && (status<3)) { val += strspn(val,sep); size_t c; c = strspn(val,"#"); if (c) val[c] = 0; // remove comments c = strcspn(line,sep); if (c) line[c] = 0; // deblank FLAG_NUMBER_OF_FIELDS_READ++; } if (VERBOSE_LEVEL>8) fprintf(stdout,"BIN <%s>=<%s> \n",line,val); if (status==1) { if (!strcmp(line,"Duration")) duration = atof(val); //else if (!strncmp(line,"NumberOfChannels")) else if (!strcmp(line,"Patient.Id")) strncpy(hdr->Patient.Id,val,MAX_LENGTH_PID); else if (!strcmp(line,"Patient.Birthday")) { struct tm t; sscanf(val,"%04i-%02i-%02i %02i:%02i:%02i",&t.tm_year,&t.tm_mon,&t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); t.tm_year -=1900; t.tm_mon--; t.tm_isdst = -1; hdr->Patient.Birthday = tm_time2gdf_time(&t); } else if (!strcmp(line,"Patient.Weight")) hdr->Patient.Weight = atoi(val); else if (!strcmp(line,"Patient.Height")) hdr->Patient.Height = atoi(val); else if (!strcmp(line,"Patient.Gender")) hdr->Patient.Sex = atoi(val); else if (!strcmp(line,"Patient.Handedness")) hdr->Patient.Handedness = atoi(val); else if (!strcmp(line,"Patient.Smoking")) hdr->Patient.Smoking = atoi(val); else if (!strcmp(line,"Patient.AlcoholAbuse")) hdr->Patient.AlcoholAbuse = atoi(val); else if (!strcmp(line,"Patient.DrugAbuse")) hdr->Patient.DrugAbuse = atoi(val); else if (!strcmp(line,"Patient.Medication")) hdr->Patient.Medication = atoi(val); else if (!strcmp(line,"Recording.ID")) strncpy(hdr->ID.Recording,val,MAX_LENGTH_RID); else if (!strcmp(line,"Recording.Time")) { struct tm t; sscanf(val,"%04i-%02i-%02i %02i:%02i:%02i",&t.tm_year,&t.tm_mon,&t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); t.tm_year -= 1900; t.tm_mon--; t.tm_isdst = -1; hdr->T0 = tm_time2gdf_time(&t); } else if (!strcmp(line,"Timezone")) { int m; if (sscanf(val,"%i min", &m) > 0) hdr->tzmin = m; } else if (!strcmp(line,"Recording.IPaddress")) { #ifndef WITHOUT_NETWORK #ifdef _WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(1,1), &wsadata); #endif biosig_set_hdr_ipaddr(hdr, val); #ifdef _WIN32 WSACleanup(); #endif #endif // not WITHOUT_NETWORK } else if (!strcmp(line,"Recording.Technician")) { if (hdr->ID.Technician) free(hdr->ID.Technician); hdr->ID.Technician = strdup(val); } else if (!strcmp(line,"Manufacturer.Name")) hdr->ID.Manufacturer.Name = val; else if (!strcmp(line,"Manufacturer.Model")) hdr->ID.Manufacturer.Model = val; else if (!strcmp(line,"Manufacturer.Version")) hdr->ID.Manufacturer.Version = val; else if (!strcmp(line,"Manufacturer.SerialNumber")) hdr->ID.Manufacturer.SerialNumber = val; } else if (status==2) { if (!strcmp(line,"Filename")) { // add next channel ++hdr->NS; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); cp = hdr->CHANNEL+hdr->NS-1; cp->Transducer[0] = 0; cp->bi = hdr->AS.bpb; cp->PhysDimCode = 0; cp->HighPass = NAN; cp->LowPass = NAN; cp->Notch = NAN; cp->Impedance= NAN; cp->fZ = NAN; cp->LeadIdCode = 0; datfile = val; FLAG_NUMBER_OF_FIELDS_READ = 1; } else if (!strcmp(line,"Label")) strncpy(cp->Label,val,MAX_LENGTH_LABEL); else if (!strcmp(line,"GDFTYP")) { if (!strcmp(val,"int8")) gdftyp = 1; else if (!strcmp(val,"uint8")) gdftyp = 2; else if (!strcmp(val,"int16")) gdftyp = 3; else if (!strcmp(val,"uint16")) gdftyp = 4; else if (!strcmp(val,"int32")) gdftyp = 5; else if (!strcmp(val,"uint32")) gdftyp = 6; else if (!strcmp(val,"int64")) gdftyp = 7; else if (!strcmp(val,"uint64")) gdftyp = 8; else if (!strcmp(val,"float32")) gdftyp = 16; else if (!strcmp(val,"float64")) gdftyp = 17; else if (!strcmp(val,"float128")) gdftyp = 18; else if (!strcmp(val,"ascii")) gdftyp = 0xfffe; else gdftyp = atoi(val); } else if (!strcmp(line,"PhysicalUnits")) cp->PhysDimCode = PhysDimCode(val); else if (!strcmp(line,"PhysDimCode")) { // If PhysicalUnits and PhysDimCode conflict, PhysicalUnits gets the preference if (!cp->PhysDimCode) cp->PhysDimCode = atoi(val); } else if (!strcmp(line,"Transducer")) strncpy(cp->Transducer,val,MAX_LENGTH_TRANSDUCER); else if (!strcmp(line,"SamplingRate")) Fs = atof(val); else if (!strcmp(line,"NumberOfSamples")) { cp->SPR = atol(val); if (cp->SPR>0) hdr->SPR = lcm(hdr->SPR,cp->SPR); if ((gdftyp>0) && (gdftyp<256)) { cp->GDFTYP = gdftyp; FILE *fid = fopen(datfile,"rb"); if (fid != NULL) { size_t bufsiz = (size_t)cp->SPR*GDFTYP_BITS[cp->GDFTYP]>>3; hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata,lengthRawData+bufsiz+1); count = fread(hdr->AS.rawdata+lengthRawData,1,bufsiz+1,fid); if (count != bufsiz) fprintf(stderr,"Warning SOPEN(BIN) #%i: mismatch between sample number and file size (%i,%i)\n",hdr->NS-1,(int)count,(int)bufsiz); lengthRawData += bufsiz; fclose(fid); } else if (cp->SPR > 0) { cp->SPR = 0; fprintf(stderr,"Warning SOPEN(BIN) #%i: data file (%s) not found\n",hdr->NS,datfile); } } else if (gdftyp==0xfffe) { cp->GDFTYP = 17; // double struct stat FileBuf; stat(datfile, &FileBuf); FILE *fid = fopen(datfile,"rb"); if (fid != NULL) { char *buf = (char*)malloc(FileBuf.st_size+1); count = fread(buf, 1, FileBuf.st_size, fid); fclose(fid); buf[count] = 0; size_t sz = GDFTYP_BITS[cp->GDFTYP]>>3; const size_t bufsiz = cp->SPR * sz; hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata, lengthRawData+bufsiz); char *bufbak = buf; // backup copy char **endptr = &bufbak; for (k = 0; k < cp->SPR; k++) { double d = strtod(*endptr,endptr); *(double*)(hdr->AS.rawdata+lengthRawData+sz*k) = d; } lengthRawData += bufsiz; free(buf); } else if (cp->SPR > 0) { cp->SPR = 0; fprintf(stderr,"Warning SOPEN(BIN) #%i: data file (%s) not found\n",hdr->NS,datfile); } } else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "ASCII/BIN: data type unsupported"); } hdr->AS.bpb = lengthRawData; } else if (!strcmp(line,"HighPassFilter")) cp->HighPass = atof(val); else if (!strcmp(line,"LowPassFilter")) cp->LowPass = atof(val); else if (!strcmp(line,"NotchFilter")) cp->Notch = atof(val); else if (!strcmp(line,"DigMax")) cp->DigMax = atof(val); else if (!strcmp(line,"DigMin")) cp->DigMin = atof(val); else if (!strcmp(line,"PhysMax")) cp->PhysMax = atof(val); else if (!strcmp(line,"PhysMin")) cp->PhysMin = atof(val); else if (!strcmp(line,"Impedance")) cp->Impedance = atof(val); else if (!strcmp(line,"freqZ")) cp->fZ = atof(val); else if (!strncmp(line,"Position",8)) { sscanf(val,"%f \t%f \t%f",cp->XYZ,cp->XYZ+1,cp->XYZ+2); // consolidate previous channel if ((((size_t)cp->SPR*GDFTYP_BITS[cp->GDFTYP] >> 3) != (hdr->AS.bpb-cp->bi)) && (hdr->TYPE==BIN)) { fprintf(stdout,"Warning SOPEN(BIN): problems with channel %i - filesize %i does not fit header info %"PRIiPTR"\n",(int)k+1, hdr->AS.bpb-hdr->CHANNEL[k].bi, (GDFTYP_BITS[hdr->CHANNEL[k].GDFTYP]*(size_t)hdr->CHANNEL[k].SPR) >> 3); } hdr->SampleRate = hdr->SPR/duration; cp->LeadIdCode = 0; cp->OnOff = 1; cp->Cal = (cp->PhysMax - cp->PhysMin) / (cp->DigMax - cp->DigMin); cp->Off = cp->PhysMin - cp->Cal*cp->DigMin; } } else if (status==3) { if (!strncmp(line,"0x",2)) { if (hdr->EVENT.N+1 >= N) { N = max(PAGESIZE, 2*N); if (N != reallocEventTable(hdr, N)) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } val = line+2; int i; sscanf(val,"%04x",&i); if (i>0xffff) fprintf(stdout,"Warning: Type %i of event %i does not fit in 16bit\n",i,hdr->EVENT.N); else hdr->EVENT.TYP[hdr->EVENT.N] = (typeof(hdr->EVENT.TYP[0]))i; double d; val = strchr(val,'\t')+1; sscanf(val,"%lf",&d); hdr->EVENT.POS[hdr->EVENT.N] = (typeof(*hdr->EVENT.POS))round(d*hdr->EVENT.SampleRate); // 0-based indexing #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif val = strchr(val,'\t')+1; if (val[0]!='\t') { sscanf(val,"%lf",&d); hdr->EVENT.DUR[hdr->EVENT.N] = (typeof(*hdr->EVENT.POS))round(d*hdr->EVENT.SampleRate); } else hdr->EVENT.DUR[hdr->EVENT.N] = 0; val = strchr(val,'\t')+1; if (val[0]!='\t') { sscanf(val,"%d",&i); if (i>0xffff) fprintf(stdout,"Warning: channel number %i of event %i does not fit in 16bit\n",i,hdr->EVENT.N); else hdr->EVENT.CHN[hdr->EVENT.N] = i; } else hdr->EVENT.CHN[hdr->EVENT.N] = 0; val = strchr(val,'\t')+1; if ((hdr->EVENT.TYP[hdr->EVENT.N]==0x7fff) && (hdr->EVENT.CHN[hdr->EVENT.N]>0) && (!hdr->CHANNEL[hdr->EVENT.CHN[hdr->EVENT.N]-1].SPR)) { sscanf(val,"%d",&hdr->EVENT.DUR[hdr->EVENT.N]); } ++hdr->EVENT.N; } } line = strtok(NULL,"\x0a\x0d"); } hdr->AS.length = hdr->NRec; } else if (hdr->TYPE==BCI2000) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) FMT=%s Ver=%4.2f\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION); char *ptr, *t1; /* decode header length */ hdr->HeadLen = 0; ptr = strstr((char*)hdr->AS.Header,"HeaderLen="); if (ptr==NULL) biosigERROR(hdr, B4C_FORMAT_UNKNOWN, "not a BCI2000 format"); else { /* read whole header */ hdr->HeadLen = (typeof(hdr->HeadLen)) strtod(ptr+10,&ptr); if (count <= hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, hdr->HeadLen+1); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } else ifseek(hdr,hdr->HeadLen,SEEK_SET); } hdr->AS.Header[hdr->HeadLen]=0; hdr->AS.bci2000 = (char*)realloc(hdr->AS.bci2000, hdr->HeadLen+1); memcpy(hdr->AS.bci2000, hdr->AS.Header, hdr->HeadLen+1); /* decode number of channels */ t1 = strtok((char*)hdr->AS.Header,"\x0a\x0d"); ptr = strstr(t1,"SourceCh="); if (ptr==NULL) biosigERROR(hdr, B4C_FORMAT_UNKNOWN, "not a BCI2000 format"); else hdr->NS = (typeof(hdr->NS)) strtod(ptr+9,&ptr); /* decode length of state vector */ ptr = strstr(t1,"StatevectorLen="); if (ptr==NULL) biosigERROR(hdr, B4C_FORMAT_UNKNOWN, "not a BCI2000 format"); else BCI2000_StatusVectorLength = (size_t) strtod(ptr+15,&ptr); /* decode data format */ ptr = strstr(ptr,"DataFormat="); uint16_t gdftyp=3; if (ptr == NULL) gdftyp = 3; else if (!strncmp(ptr+12,"int16",3)) gdftyp = 3; else if (!strncmp(ptr+12,"int32",5)) gdftyp = 5; else if (!strncmp(ptr+12,"float32",5)) gdftyp = 16; else if (!strncmp(ptr+12,"int24",5)) gdftyp = 255+24; else if (!strncmp(ptr+12,"uint16",3)) gdftyp = 4; else if (!strncmp(ptr+12,"uint32",5)) gdftyp = 6; else if (!strncmp(ptr+12,"uint24",5)) gdftyp = 511+24; else if (!strncmp(ptr+12,"float64",6)) gdftyp = 17; else biosigERROR(hdr, B4C_FORMAT_UNKNOWN, "SOPEN(BCI2000): invalid file format"); if (hdr->AS.B4C_ERRNUM) { return(hdr); } if (hdr->FLAG.OVERFLOWDETECTION) { fprintf(stderr,"WARNING: Automated overflowdetection not supported in BCI2000 file %s\n",hdr->FileName); hdr->FLAG.OVERFLOWDETECTION = 0; } hdr->SPR = 1; double gain=0.0, offset=0.0, digmin=0.0, digmax=0.0; size_t tc_len=0,tc_pos=0, rs_len=0,rs_pos=0, fb_len=0,fb_pos=0; char TargetOrientation=0; hdr->AS.bpb = 0; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Transducer[0] = 0; sprintf(hc->Label,"#%03i",(int)k+1); hc->Cal = gain; hc->Off = offset; hc->PhysDimCode = 4275; // uV hc->LeadIdCode = 0; hc->OnOff = 1; hc->SPR = 1; hc->GDFTYP = gdftyp; hc->bi = hdr->AS.bpb; hdr->AS.bpb += (GDFTYP_BITS[hc->GDFTYP] * (size_t)hc->SPR)>>3; } if (hdr->TYPE==BCI2000) hdr->AS.bpb += BCI2000_StatusVectorLength; int status = 0; ptr = strtok(NULL,"\x0a\x0d"); while (ptr != NULL) { if (VERBOSE_LEVEL>8) fprintf(stdout,"[203] %i: %s !\n",status,ptr); if (!strncmp(ptr,"[ State Vector Definition ]",26)) status = 1; else if (!strncmp(ptr,"[ Parameter Definition ]",24)) status = 2; else if (!strncmp(ptr,"[ ",2)) status = 3; else if (status==1) { int i[4]; char *item = NULL; #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L sscanf(ptr,"%as %i %i %i %i",&item,i,i+1,i+2,i+3); #else sscanf(ptr,"%ms %i %i %i %i",&item,i,i+1,i+2,i+3); #endif if (!strcmp(item,"TargetCode")) { tc_pos = i[2]*8 + i[3]; tc_len = i[0]; } else if (!strcmp(item,"ResultCode")) { rs_pos = i[2]*8 + i[3]; rs_len = i[0]; } else if (!strcmp(item,"Feedback")) { fb_pos = i[2]*8 + i[3]; fb_len = i[0]; } if (item) free(item); } else if (status==2) { t1 = strstr(ptr,"ChannelNames="); if (t1 != NULL) { unsigned NS = (unsigned)strtod(t1+13,&ptr); for (k=0; kMAX_LENGTH_LABEL) k1=MAX_LENGTH_LABEL; strncpy(hdr->CHANNEL[k].Label,ptr-k1,k1); hdr->CHANNEL[k].Label[k1]=0; // terminating 0 } } t1 = strstr(ptr,"SamplingRate="); if (t1 != NULL) hdr->SampleRate = strtod(t1+14,&ptr); t1 = strstr(ptr,"SourceChGain="); if (t1 != NULL) { unsigned NS = (unsigned) strtod(t1+13,&ptr); for (k=0; kCHANNEL[k].Cal = strtod(ptr,&ptr); for (; kNS; k++) hdr->CHANNEL[k].Cal = hdr->CHANNEL[k-1].Cal; } t1 = strstr(ptr,"SourceChOffset="); if (t1 != NULL) { unsigned NS = (unsigned) strtod(t1+15,&ptr); for (k=0; kCHANNEL[k].Off = strtod(ptr,&ptr); for (; kNS; k++) hdr->CHANNEL[k].Off = hdr->CHANNEL[k-1].Off; } t1 = strstr(ptr,"SourceMin="); if (t1 != NULL) digmin = strtod(t1+10,&ptr); t1 = strstr(ptr,"SourceMax="); if (t1 != NULL) digmax = strtod(t1+10,&ptr); t1 = strstr(ptr,"StorageTime="); if (t1 != NULL) { char *t2 = strstr(t1,"%20"); while (t2!=NULL) { memset(t2,' ',3); t2 = strstr(t1,"%20"); } char tmp[20]; int c=sscanf(t1+12,"%03s %03s %2u %2u:%2u:%2u %4u",tmp+10,tmp,&tm_time.tm_mday,&tm_time.tm_hour,&tm_time.tm_min,&tm_time.tm_sec,&tm_time.tm_year); if (c==7) { tm_time.tm_isdst = -1; tm_time.tm_year -= 1900; tm_time.tm_mon = month_string2int(tmp); hdr->T0 = tm_time2gdf_time(&tm_time); } } t1 = strstr(ptr,"TargetOrientation="); if (t1 != NULL) TargetOrientation = (char) strtod(t1+18, &ptr); // else if (status==3); } ptr = strtok(NULL,"\x0a\x0d"); } for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->DigMax = digmax; hc->DigMin = digmin; hc->PhysMax= hc->DigMax * hc->Cal + hc->Off; hc->PhysMin= hc->DigMin * hc->Cal + hc->Off; } hdr->AS.bpb = (hdr->NS * (GDFTYP_BITS[gdftyp]>>3) + BCI2000_StatusVectorLength); /* decode state vector into event table */ hdr->EVENT.SampleRate = hdr->SampleRate; size_t skip = hdr->NS * (GDFTYP_BITS[gdftyp]>>3); size_t N = 0; count = 0; uint8_t *StatusVector = (uint8_t*) malloc(BCI2000_StatusVectorLength*2); uint32_t b0=0,b1=0,b2=0,b3,b4=0,b5; while (!ifeof(hdr)) { ifseek(hdr, skip, SEEK_CUR); ifread(StatusVector + BCI2000_StatusVectorLength*(count & 1), 1, BCI2000_StatusVectorLength, hdr); if (memcmp(StatusVector, StatusVector+BCI2000_StatusVectorLength, BCI2000_StatusVectorLength)) { if (N+4 >= hdr->EVENT.N) { hdr->EVENT.N += 1024; if (SIZE_MAX == reallocEventTable(hdr, hdr->EVENT.N)) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[N] = 0; #endif /* event codes according to http://www.bci2000.org/wiki/index.php/User_Reference:GDFFileWriter http://biosig.cvs.sourceforge.net/biosig/biosig/doc/eventcodes.txt?view=markup */ /* decode ResultCode */ b3 = *(uint32_t*)(StatusVector + BCI2000_StatusVectorLength*(count & 1) + (rs_pos>>3)); b3 = (b3 >> (rs_pos & 7)) & ((1<b2) hdr->EVENT.TYP[N] = ( b3==b1 ? 0x0381 : 0x0382); else hdr->EVENT.TYP[N] = ( b2==b0 ? 0x8381 : 0x8382); hdr->EVENT.POS[N] = count; // 0-based indexing N++; b2 = b3; } /* decode TargetCode */ b1 = *(uint32_t*)(StatusVector + BCI2000_StatusVectorLength*(count & 1) + (tc_pos>>3)); b1 = (b1 >> (tc_pos & 7)) & ((1<EVENT.TYP[N] = 0x030c; break; case 2: hdr->EVENT.TYP[N] = 0x0306; break; case -1: hdr->EVENT.TYP[N] = 0x830c; break; case -2: hdr->EVENT.TYP[N] = 0x8306; break; default: if (b1>b0) hdr->EVENT.TYP[N] = 0x0300 + b1 - b0; else hdr->EVENT.TYP[N] = 0x8300 + b0 - b1; } } else { if (b1>b0) hdr->EVENT.TYP[N] = 0x0300 + b1 - b0; else hdr->EVENT.TYP[N] = 0x8300 + b0 - b1; } hdr->EVENT.POS[N] = count; // 0-based indexing N++; b0 = b1; } /* decode Feedback */ b5 = *(uint32_t*)(StatusVector + BCI2000_StatusVectorLength*(count & 1) + (fb_pos>>3)); b5 = (b5 >> (fb_pos & 7)) & ((1< b4) hdr->EVENT.TYP[N] = 0x030d; else if (b5 < b4) hdr->EVENT.TYP[N] = 0x830d; if (b5 != b4) { hdr->EVENT.POS[N] = count; // 0-based indexing N++; b4 = b5; } } count++; } hdr->EVENT.N = N; free(StatusVector); hdr->NRec = (iftell(hdr) - hdr->HeadLen) / hdr->AS.bpb; ifseek(hdr, hdr->HeadLen, SEEK_SET); if (VERBOSE_LEVEL>8) fprintf(stdout,"[209] header finished!\n"); } else if (hdr->TYPE==BKR) { if (VERBOSE_LEVEL>8) fprintf(stdout,"libbiosig/sopen (BKR)\n"); hdr->HeadLen = 1024; hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, hdr->HeadLen); if (hdr->HeadLen > count) count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); hdr->NS = leu16p(hdr->AS.Header+2); hdr->NRec = leu32p(hdr->AS.Header+6); hdr->SPR = leu32p(hdr->AS.Header+10); hdr->NRec *= hdr->SPR; hdr->SPR = 1; hdr->T0 = 0; // Unknown; hdr->SampleRate = leu16p(hdr->AS.Header+4); /* extract more header information */ hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; sprintf(hc->Label,"# %02i",(int)k); hc->Transducer[0] = '\0'; hc->GDFTYP = 3; hc->SPR = 1; // *(int32_t*)(Header1+56); hc->LowPass = lef32p(hdr->AS.Header+22); hc->HighPass = lef32p(hdr->AS.Header+26); hc->Notch = -1.0; // unknown hc->PhysMax = (double)leu16p(hdr->AS.Header+14); hc->DigMax = (double)leu16p(hdr->AS.Header+16); hc->PhysMin = -hc->PhysMax; hc->DigMin = -hc->DigMax; hc->Cal = hc->PhysMax/hc->DigMax; hc->Off = 0.0; hc->OnOff = 1; hc->PhysDimCode = 4275; // uV hc->LeadIdCode = 0; hc->bi = k*2; } hdr->AS.bpb = hdr->NS*2; hdr->FLAG.OVERFLOWDETECTION = 0; // BKR does not support automated overflow and saturation detection } else if (hdr->TYPE==BLSC) { hdr->HeadLen = hdr->AS.Header[1]<<7; if (countHeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, hdr->HeadLen); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } hdr->VERSION = leu16p(hdr->AS.Header+2)/100.0; hdr->SampleRate = 128; hdr->SPR = 1; hdr->NS = hdr->AS.Header[346]; const uint32_t GAIN[] = { 0,50000,75000,100000,150000,200000,250000,300000, //0-7 0,5000,7500,10000,15000,20000,25000,30000, //8-15 0,500,750,1000,1500,2000,2500,3000, //16-23 10,50,75,100,150,200,250,300 //24-31 }; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Label[0] = 0; hc->Transducer[0] = '\0'; hc->GDFTYP = 2; hc->SPR = hdr->SPR; // *(int32_t*)(Header1+56); hc->LowPass = -1.0; hc->HighPass = -1.0; hc->Notch = -1.0; // unknown hc->DigMax = 255; hc->DigMin = 0; #define SENS leu16p(hdr->AS.Header+467) #define CALUV leu16p(hdr->AS.Header+469) #define CV hdr->AS.Header[425+k] #define DC hdr->AS.Header[446+k] #define gain GAIN[hdr->AS.Header[602+k]] if (VERBOSE_LEVEL>8) fprintf(stdout,"#%i sens=%i caluv=%i cv=%i dc=%i Gain=%i\n",(int)k,SENS,CALUV,CV,DC,gain); double cal, off; if (hdr->AS.Header[5]==0) { // external amplifier cal = 0.2*CALUV*SENS/CV; off = -DC*cal; } else { // internal amplifier cal = 4e6/(CV*gain); off = -(128+(DC-128)*gain/3e5)*cal; } #undef SENS #undef CALUV #undef CV #undef DC #undef gain hc->Cal = cal; hc->Off = off; hc->PhysMax = hc->DigMax * cal + off; hc->PhysMin = hc->DigMin * cal + off; hc->OnOff = 1; hc->PhysDimCode = 4275; // uV hc->LeadIdCode = 0; hc->bi = k*hc->SPR*(GDFTYP_BITS[2]>>3); } hdr->AS.bpb = hdr->NS*hdr->SPR*(GDFTYP_BITS[2]>>3); struct stat FileBuf; stat(hdr->FileName,&FileBuf); hdr->NRec = FileBuf.st_size/hdr->NS; ifseek(hdr, hdr->HeadLen, SEEK_SET); } else if (hdr->TYPE==WFT) { // WFT/Nicolet hdr->HeadLen = atol((char*)hdr->AS.Header+8); if (countHeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, hdr->HeadLen); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } uint16_t gdftyp=3; // int16_t // File_size char *next = strchr(hdr->AS.Header+8,0)+1; while (*next==32) next++; hdr->FILE.size = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // File format version next = strchr(next,0)+1; while (*next==32) next++; hdr->VERSION = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); hdr->NS = 1; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); CHANNEL_TYPE *hc = hdr->CHANNEL; hc->OnOff = 1; hc->LeadIdCode = 0; hc->Transducer[0]=0; hc->TOffset = 0.0; hc->LowPass = 0.0; hc->HighPass = 0.0; hc->Notch = 0.0; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; hc->Impedance = NAN; hc->bi = 0; hc->bi8 = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // Waveform title next = strchr(next,0)+1; while (*next==32) next++; memcpy(hc->Label, next, MAX_LENGTH_LABEL+1); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); struct tm T0; T0.tm_sec=0; T0.tm_min=0; T0.tm_hour=0; // date year next = strchr(next,0)+1; while (*next==32) next++; T0.tm_year = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // date month next = strchr(next,0)+1; while (*next==32) next++; T0.tm_mon = atol(next)-1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // date day next = strchr(next,0)+1; while (*next==32) next++; T0.tm_mday = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // milliseconds since midnight next = strchr(next,0)+1; while (*next==32) next++; long msec = atol(next); T0.tm_sec = msec / 1000; msec = msec % 1000; hdr->T0 = tm_time2gdf_time(&T0) + ldexp(msec/(3600*24*1000.0),32) ; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // date day next = strchr(next,0)+1; while (*next==32) next++; hdr->SPR = 1; hdr->NRec = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); hc->Transducer[0] = '\0'; hc->GDFTYP = 3; // int16 hc->SPR = hdr->SPR; // hc->LowPass = -1.0; hc->HighPass = -1.0; hc->Notch = -1.0; // unknown hc->DigMax = 32767; hc->DigMin = -32768; hc->OnOff = 1; hc->PhysDimCode = 4275; // uV hc->LeadIdCode = 0; // vertical zero next = strchr(next,0)+1; while (*next==32) next++; int vz = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // vertical norm next = strchr(next,0)+1; while (*next==32) next++; double vn = atof(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // user vertical zero next = strchr(next,0)+1; while (*next==32) next++; double uvz = atof(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // user vertical norm next = strchr(next,0)+1; while (*next==32) next++; double uvn = atof(next); hc->Cal = vn*uvn; hc->Off = uvz - vz*vn*uvn; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // user vertical label next = strchr(next,0)+1; while (*next==32) next++; const char *physdim = next; if (!memcmp(next,"V ",2)) hc->PhysDimCode = 4256; else hc->PhysDimCode = PhysDimCode(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // user horizontal zero next = strchr(next,0)+1; while (*next==32) next++; hdr->SampleRate = 1.0/atof(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // user horizontal norm next = strchr(next,0)+1; while (*next==32) next++; double uhn = atof(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // user horizontal label next = strchr(next,0)+1; while (*next==32) next++; const char *my_physdim = next; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // user notes next = strchr(next,0)+1; while (*next==32) next++; const char *user_notes = next; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // audit next = strchr(next,0)+1; while (*next==32) next++; const char *audit = next; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // nicolet_digitizer_type next = strchr(next,0)+1; while (*next==32) next++; const char nicolet_digitizer_type = *next; strcpy(hdr->ID.Manufacturer._field, "Nicolet"); strcpy(hdr->ID.Manufacturer._field+8, next); hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field; hdr->ID.Manufacturer.Model = hdr->ID.Manufacturer._field+8; hdr->ID.Manufacturer.Version = NULL; hdr->ID.Manufacturer.SerialNumber = NULL; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // bytes per data point next = strchr(next,0)+1; while (*next==32) next++; hdr->AS.bpb = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); // resolution next = strchr(next,0)+1; while (*next==32) next++; int resolution = atol(next); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s line %d: %s(...) <%s>:\n", __FILE__,__LINE__,__func__,next); int k=24; hdr->SampleRate = 200; // unknown while (next < (char*)(hdr->AS.Header + hdr->HeadLen)) { if (k==189) hdr->SampleRate = 1.0/atof(next); if (VERBOSE_LEVEL>8) fprintf(stdout,"%s line %d: %s(...) : %d <%s>\n", __FILE__,__LINE__,__func__, k, next); next = strchr(next,0)+1; while (*next==32) next++; k++; } } else if (hdr->TYPE==BiosigDump) { hdr->HeadLen = count; sopen_biosigdump_read(hdr); } else if (hdr->TYPE==BNI) { // BNI-1-Baltimore/Nicolet char *line = strtok((char*)hdr->AS.Header,"\x0a\x0d"); fprintf(stderr,"Warning SOPEN: BNI not implemented - experimental code!\n"); double cal=0,age; char *Label=NULL; struct tm t; while (line != NULL) { size_t c1 = strcspn(line," ="); size_t c2 = strspn(line+c1," ="); char *val = line+c1+c2; if (!strncmp(line,"PatientId",9)) strncpy(hdr->Patient.Id,val,MAX_LENGTH_PID); else if (!strncasecmp(line,"Sex",3)) hdr->Patient.Sex = 1*(toupper(val[0])=='M')+2*(toupper(val[0])=='F'); else if (!strncasecmp(line,"medication",11)) hdr->Patient.Medication = val==NULL ? 1 : 2; else if (!strncasecmp(line,"diagnosis",10)) { } else if (!strncasecmp(line,"MontageRaw",9)) Label = val; else if (!strncasecmp(line,"Age",3)) age = atol(val); else if (!strncasecmp(line,"Date",c1)) sscanf(val,"%02i/%02i/%02i",&t.tm_mon,&t.tm_mday,&t.tm_year); else if (!strncasecmp(line,"Time",c1)) sscanf(val,"%02i:%02i:%02i",&t.tm_hour,&t.tm_min,&t.tm_sec); else if (!strncasecmp(line,"Rate",c1)) hdr->SampleRate = atol(val); else if (!strncasecmp(line,"NchanFile",9)) hdr->NS = atol(val); else if (!strncasecmp(line,"UvPerBit",c1)) cal = atof(val); else if (!strncasecmp(line,"[Events]",c1)) { // not implemented yet } else fprintf(stdout,"SOPEN(BNI): unknown field %s=%s\n",line,val); line = strtok(NULL,"\x0a\x0d"); } hdr->T0 = tm_time2gdf_time(&t); hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (!k) strncpy(hc->Label, strtok(Label,","),MAX_LENGTH_LABEL); else strncpy(hc->Label, strtok(NULL,","),MAX_LENGTH_LABEL); hc->Transducer[0] = '\0'; hc->GDFTYP = 0xffff; // unknown - triggers error status hc->SPR = 1; // hc->LowPass = -1.0; hc->HighPass = -1.0; hc->Notch = -1.0; // unknown hc->DigMax = 32767; hc->DigMin = -32768; hc->Cal = cal; hc->Off = 0.0; hc->PhysMax = hc->DigMax * cal; hc->PhysMin = hc->DigMin * cal; hc->OnOff = 1; hc->PhysDimCode = 4275; // uV hc->LeadIdCode = 0; //hc->bi = k*GDFTYP_BITS[hc->GDFTYP]>>3; } } else if (hdr->TYPE==BrainVisionMarker) { while (!ifeof(hdr)) { size_t bufsiz = max(count*2, PAGESIZE); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,bufsiz+1); count += ifread(hdr->AS.Header+count,1,bufsiz-count,hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); if (VERBOSE_LEVEL>8) fprintf(stdout,"SOPEN(BV): marker file read.\n"); int seq = 0; /* decode marker file */ char *t,*t1=" "; t = Header1; t += strcspn(Header1,"\x0A\x0D"); t += strspn(t,"\x0A\x0D"); //char *t1 = strtok(Header1,"\x0A\x0D"); // skip first line size_t N_EVENT=0; hdr->EVENT.N=0; int lineNo=1; do { t1 = t; t += strcspn(t,"\x0A\x0D"); while ( (*t==0x0a) || (*t==0x0d) ) { *t=0; t++; } lineNo++; if (VERBOSE_LEVEL>8) fprintf(stdout,"%i <%s>\n",seq,t1); if (!strncmp(t1,";",1)) ; else if (!strncmp(t1,"[Common Infos]",14)) seq = 1; else if (!strncmp(t1,"[Marker Infos]",14)) seq = 2; else if (seq==1) ; else if ((seq==2) && !strncmp(t1,"Mk",2)) { int p2=0, p3=0, p4=0, p5=0, p6=0; int p1 = strcspn(t1,"="); if ( p1 && t1[p1] ) p2 = p1 + 1 + strcspn(t1+p1+1,","); if ( p2 && t1[p2] ) p3 = p2 + 1 + strcspn(t1+p2+1,","); if ( p3 && t1[p3] ) p4 = p3 + 1 + strcspn(t1+p3+1,","); if ( p4 && t1[p4] ) p5 = p4 + 1 + strcspn(t1+p4+1,","); if ( p5 && t1[p5] ) p6 = p5 + 1 + strcspn(t1+p5+1,","); if ( !p5 ) { // ignore this line when not at least 5 fields separated by 4 commas fprintf(stderr,"WARNING: syntax error in %s (line %d) '%s' - line ignored\n", hdr->FileName, lineNo, t1); continue; // next line } if (VERBOSE_LEVEL>8) fprintf(stdout," %i %i %i %i %i %i \n",p1,p2,p3,p4,p5,p6); t1[p1]=0; t1[p2]=0; t1[p3]=0; t1[p4]=0; t1[p5]=0; if (hdr->EVENT.N <= N_EVENT) { hdr->EVENT.N += 256; if (reallocEventTable(hdr, hdr->EVENT.N) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } hdr->EVENT.TYP[N_EVENT] = atol(t1+p2+2); hdr->EVENT.POS[N_EVENT] = atol(t1+p3+1)-1; // 0-based indexing hdr->EVENT.DUR[N_EVENT] = atol(t1+p4+1); hdr->EVENT.CHN[N_EVENT] = atol(t1+p5+1); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[N_EVENT] = 0; #endif if (!strncmp(t1+p1+1,"New Segment",11)) { hdr->EVENT.TYP[N_EVENT] = 0x7ffe; char* t2 = t1+p6+1; t2[14]=0; tm_time.tm_sec = atoi(t2+12); t2[12]=0; tm_time.tm_min = atoi(t2+10); t2[10]=0; tm_time.tm_hour = atoi(t2+8); t2[8] =0; tm_time.tm_mday = atoi(t2+6); t2[6] =0; tm_time.tm_mon = atoi(t2+4)-1; t2[4] =0; tm_time.tm_year = atoi(t2)-1900; hdr->T0 = tm_time2gdf_time(&tm_time); } else { if (VERBOSE_LEVEL>8) fprintf(stdout,"#%02i <%s>\n",(int)N_EVENT,t1+p2+1); FreeTextEvent(hdr,N_EVENT,t1+p2+1); } ++N_EVENT; } } while (strlen(t1)>0); // free(vmrk); hdr->AS.auxBUF = hdr->AS.Header; hdr->AS.Header = NULL; hdr->EVENT.N = N_EVENT; hdr->TYPE = EVENT; } else if ((hdr->TYPE==BrainVision) || (hdr->TYPE==BrainVisionVAmp)) { /* open and read header file */ // ifclose(hdr); while (!ifeof(hdr)) { size_t bufsiz = max(2*count, PAGESIZE); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN(BV): header file read.\n"); int seq = 0; char *datafile = NULL; int sections[6]; memset(sections,0,sizeof(sections)); /* decode header information */ hdr->FLAG.OVERFLOWDETECTION = 0; uint16_t gdftyp=3; char FLAG_ASCII = 0; hdr->FILE.LittleEndian = 1; // default little endian double physmax=1e6,physmin=-1e6,digmax=1e6,digmin=-1e6,cal=1.0,off=0.0; enum o_t{VEC,MUL} orientation = MUL; char DECIMALSYMBOL='.'; int SKIPLINES=0, SKIPCOLUMNS=0; size_t npts=0; char *t; size_t pos; // skip first line with const char EOL[] = "\r\n"; pos = strcspn(Header1,EOL); pos += strspn(Header1+pos,EOL); while (pos < hdr->HeadLen) { t = Header1+pos; // start of line pos += strcspn(t,EOL); Header1[pos] = 0; // line terminator pos += strspn(Header1+pos+1,EOL)+1; // skip if (VERBOSE_LEVEL>7) fprintf(stdout,"[212]: %i pos=%i <%s>, ERR=%i\n",seq,(int)pos,t,hdr->AS.B4C_ERRNUM); if (!strncmp(t,";",1)) // comments ; else if (!strncmp(t,"[Common Infos]",14)) { seq = 1; sections[seq]++; } else if (!strncmp(t,"[Binary Infos]",14)) { seq = 2; sections[seq]++; } else if (!strncmp(t,"[ASCII Infos]",13)) { seq = 2; sections[seq]++; FLAG_ASCII = 1; gdftyp = 17; } else if (!strncmp(t,"[Channel Infos]",14)) { seq = 3; sections[seq]++; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Label[0] = 0; hc->Transducer[0] = '\0'; hc->GDFTYP = gdftyp; hc->SPR = 1; hc->LowPass = -1.0; hc->HighPass = -1.0; hc->Notch = -1.0; // unknown hc->PhysMax = physmax; hc->DigMax = digmax; hc->PhysMin = physmin; hc->DigMin = digmin; hc->Impedance = NAN; hc->Cal = cal; hc->Off = off; hc->OnOff = 1; hc->PhysDimCode = 4275; // uV hc->LeadIdCode = 0; size_t bi8 = k*(size_t)hdr->SPR*GDFTYP_BITS[gdftyp]; hc->bi8 = bi8; hc->bi = bi8>>3; } if (VERBOSE_LEVEL>7) fprintf(stdout,"BVA210 seq=%i,pos=%i,%i <%s> bpb=%i\n",seq,(int)pos,hdr->HeadLen,t,hdr->AS.bpb); } //else if (!strncmp(t,"[Common Infos]",14)) // seq = 4; else if (!strncmp(t,"[Coordinates]",13)) seq = 5; else if (!strncmp(t,"[Comment]",9)) seq = 6; else if (!strncmp(t,"[",1)) seq = 9; else if (seq==1) { if (!strncmp(t,"DataFile=",9)) { if (datafile != NULL) fprintf(stderr,"ERROR (BrainVision): multiple DataFile entries - previous ones will be ignored\n"); char *fn = t+9; datafile = (char*)realloc(datafile, strlen(hdr->FileName)+strlen(t)); if (strrchr(hdr->FileName,FILESEP)) { strcpy(datafile, hdr->FileName); strcpy(strrchr(datafile,FILESEP)+1, fn); } else strcpy(datafile,fn); } else if (!strncmp(t,"MarkerFile=",11)) { char* mrkfile = (char*)calloc(strlen(hdr->FileName)+strlen(t),1); if (strrchr(hdr->FileName,FILESEP)) { strcpy(mrkfile, hdr->FileName); // Flawfinder: ignore strcpy(strrchr(mrkfile,FILESEP)+1, t+11); // Flawfinder: ignore } else strcpy(mrkfile,t+11); // Flawfinder: ignore if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN marker file <%s>.\n",mrkfile); HDRTYPE *hdr2 = sopen(mrkfile,"r",NULL); hdr->T0 = hdr2->T0; memcpy(&hdr->EVENT,&hdr2->EVENT,sizeof(hdr2->EVENT)); hdr->AS.auxBUF = hdr2->AS.auxBUF; // contains the free text annotation // do not de-allocate event table when hdr2 is deconstructed memset(&hdr2->EVENT,0,sizeof(hdr2->EVENT)); hdr2->AS.auxBUF = NULL; sclose(hdr2); destructHDR(hdr2); free(mrkfile); biosigERROR(hdr, B4C_NO_ERROR, NULL); // reset error status - missing or incorrect marker file is not critical } else if (!strncmp(t,"DataFormat=BINARY",11)) ; else if (!strncmp(t,"DataFormat=ASCII",16)) { FLAG_ASCII = 1; gdftyp = 17; // biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "Error SOPEN(BrainVision): ASCII-format not supported (yet)."); } else if (!strncmp(t,"DataOrientation=VECTORIZED",25)) orientation = VEC; else if (!strncmp(t,"DataOrientation=MULTIPLEXED",26)) orientation = MUL; else if (!strncmp(t,"DataType=TIMEDOMAIN",19)) ; else if (!strncmp(t,"DataType=",9)) { biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "Error SOPEN(BrainVision): DataType is not TIMEDOMAIN"); } else if (!strncmp(t,"NumberOfChannels=",17)) { hdr->NS = atoi(t+17); } else if (!strncmp(t,"DataPoints=",11)) { npts = atol(t+11); } else if (!strncmp(t,"SamplingInterval=",17)) { hdr->SampleRate = 1e6/atof(t+17); hdr->EVENT.SampleRate = hdr->SampleRate; } } else if (seq==2) { if (!strncmp(t,"BinaryFormat=IEEE_FLOAT_32",26)) { gdftyp = 16; digmax = physmax/cal; digmin = physmin/cal; } else if (!strncmp(t,"BinaryFormat=INT_16",19)) { gdftyp = 3; digmax = 32767; digmin = -32768; hdr->FLAG.OVERFLOWDETECTION = 1; } else if (!strncmp(t,"BinaryFormat=UINT_16",20)) { gdftyp = 4; digmax = 65535; digmin = 0; hdr->FLAG.OVERFLOWDETECTION = 1; } else if (!strncmp(t,"BinaryFormat",12)) { biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "Error SOPEN(BrainVision): BinaryFormat="); } else if (!strncmp(t,"UseBigEndianOrder=NO",20)) { // hdr->FLAG.SWAP = (__BYTE_ORDER == __BIG_ENDIAN); hdr->FILE.LittleEndian = 1; } else if (!strncmp(t,"UseBigEndianOrder=YES",21)) { // hdr->FLAG.SWAP = (__BYTE_ORDER == __LITTLE_ENDIAN); hdr->FILE.LittleEndian = 0; } else if (!strncmp(t,"DecimalSymbol=",14)) { DECIMALSYMBOL = t[14]; } else if (!strncmp(t,"SkipLines=",10)) { SKIPLINES = atoi(t+10); } else if (!strncmp(t,"SkipColumns=",12)) { SKIPCOLUMNS = atoi(t+12); } } else if (seq==3) { if (VERBOSE_LEVEL==9) fprintf(stdout,"BVA: seq=%i,line=<%s>,ERR=%i\n",seq,t,hdr->AS.B4C_ERRNUM ); if (!strncmp(t,"Ch",2)) { char* ptr; if (VERBOSE_LEVEL==9) fprintf(stdout,"%s\n",t); int n = strtoul(t+2, &ptr, 10)-1; if ((n < 0) || (n >= hdr->NS)) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error SOPEN(BrainVision): invalid channel number"); ifclose(hdr); return(hdr); } size_t len = min(strcspn(ptr+1,","),MAX_LENGTH_LABEL); strncpy(hdr->CHANNEL[n].Label,ptr+1,len); hdr->CHANNEL[n].Label[len]=0; ptr += len+2; ptr += strcspn(ptr,",")+1; if (strlen(ptr)>0) { double tmp = atof(ptr); if (tmp) hdr->CHANNEL[n].Cal = tmp; hdr->CHANNEL[n].PhysMax = hdr->CHANNEL[n].DigMax * hdr->CHANNEL[n].Cal ; hdr->CHANNEL[n].PhysMin = hdr->CHANNEL[n].DigMin * hdr->CHANNEL[n].Cal ; } if (VERBOSE_LEVEL==9) fprintf(stdout,"Ch%02i=%s,,%s(%f)\n",n,hdr->CHANNEL[n].Label,ptr,hdr->CHANNEL[n].Cal ); } } else if (seq==4) { } else if (seq==5) { } else if (seq==6) { } // t = strtok(NULL,"\x0a\x0d"); // extract next line } hdr->HeadLen = 0; // sanity checks if (sections[1] != 1 || sections[2] != 1 || sections[3] != 1 ) { biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "Error SOPEN(BrainVision): invalid header file"); return(hdr); } if (datafile == NULL) { hdr->NRec= 0; } else { /* open data file */ char *filename = hdr->FileName; hdr->FileName = datafile; if (FLAG_ASCII) hdr = ifopen(hdr,"rt"); else hdr = ifopen(hdr,"rb"); hdr->AS.bpb = (hdr->NS*GDFTYP_BITS[gdftyp])>>3; if (hdr->TYPE==BrainVisionVAmp) hdr->AS.bpb += 4; if (!npts) { struct stat FileBuf; stat(datafile, &FileBuf); npts = FileBuf.st_size/hdr->AS.bpb; } /* restore input file name, and free temporary file name */ hdr->FileName = filename; free(datafile); if (orientation == VEC) { hdr->SPR = npts; hdr->NRec= 1; hdr->AS.bpb *= hdr->SPR; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->SPR = hdr->SPR; } } else { hdr->SPR = 1; hdr->NRec= npts; } } if (FLAG_ASCII) { count = 0; size_t bufsiz = hdr->NS*hdr->SPR*hdr->NRec*16; while (!ifeof(hdr)) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,count+bufsiz+1); count += ifread(hdr->AS.Header+count,1,bufsiz,hdr); } ifclose(hdr); hdr->AS.Header[count]=0; // terminating null character size_t pos=0; if (DECIMALSYMBOL != '.') do { if (hdr->AS.Header[pos]==DECIMALSYMBOL) hdr->AS.Header[pos] = '.'; } while (hdr->AS.Header[++pos]); pos = 0; while (SKIPLINES>0) { while (!iscntrl(hdr->AS.Header[pos])) pos++; // skip line while ( iscntrl(hdr->AS.Header[pos])) pos++; // skip line feed and carriage return SKIPLINES--; } hdr->AS.rawdata = (uint8_t*)malloc(hdr->NS*npts*sizeof(double)); char* POS=(char*)(hdr->AS.Header+pos); for (k=0; k < hdr->NS*npts; k++) { if (((orientation==MUL) && !(k%hdr->NS)) || ((orientation==VEC) && !(k%npts))) { double d; int sc = SKIPCOLUMNS; while (sc--) d=strtod(POS,&POS); // skip value, return value is ignored } *(double*)(hdr->AS.rawdata+k*sizeof(double)) = strtod(POS,&POS); } hdr->TYPE = native; hdr->AS.length = hdr->NRec; } } else if (hdr->TYPE==CFS) { hdr->HeadLen = count; sopen_cfs_read(hdr); } else if (hdr->TYPE==SMR) { hdr->HeadLen = count; sopen_smr_read(hdr); } else if (hdr->TYPE==CFWB) { hdr->SampleRate = 1.0/lef64p(hdr->AS.Header+8); hdr->SPR = 1; tm_time.tm_year = lei32p(hdr->AS.Header+16) - 1900; tm_time.tm_mon = lei32p(hdr->AS.Header+20) - 1; tm_time.tm_mday = lei32p(hdr->AS.Header+24); tm_time.tm_hour = lei32p(hdr->AS.Header+28); tm_time.tm_min = lei32p(hdr->AS.Header+32); tm_time.tm_sec = (int)lef64p(hdr->AS.Header+36); tm_time.tm_isdst = -1; hdr->T0 = tm_time2gdf_time(&tm_time); // = *(double*)(Header1+44); // pre-trigger time hdr->NS = leu32p(hdr->AS.Header+52); hdr->NRec = leu32p(hdr->AS.Header+56); #define CFWB_FLAG_TIME_CHANNEL (*(int32_t*)(Header1+60)) // TimeChannel // = *(int32_t*)(Header1+64); // DataFormat hdr->HeadLen = 68 + hdr->NS*96; hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); if (count<=hdr->HeadLen) count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); else ifseek(hdr, hdr->HeadLen, SEEK_SET); uint16_t gdftyp = leu32p(hdr->AS.Header+64); hdr->AS.bpb = (CFWB_FLAG_TIME_CHANNEL ? GDFTYP_BITS[CFWB_GDFTYP[gdftyp-1]]>>3 : 0); hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; uint8_t* Header2 = hdr->AS.Header+68+k*96; hc->Transducer[0] = '\0'; hc->GDFTYP = CFWB_GDFTYP[gdftyp-1]; hc->SPR = 1; // *(int32_t*)(Header1+56); strncpy(hc->Label, (char*)Header2, min(32,MAX_LENGTH_LABEL)); char p[17]; memcpy(p, (char*)Header2+32, 16); p[16] = 0; hc->PhysDimCode = PhysDimCode(p); hc->LeadIdCode = 0; hc->Cal = lef64p(Header2+64); hc->Off = lef64p(Header2+72); hc->PhysMax = lef64p(Header2+80); hc->PhysMin = lef64p(Header2+88); hc->DigMax = (hc->PhysMax - hc->Off) / hc->Cal; hc->DigMin = (hc->PhysMin - hc->Off) / hc->Cal; hc->OnOff = 1; hc->bi = hdr->AS.bpb; hdr->AS.bpb += GDFTYP_BITS[hc->GDFTYP]>>3; } hdr->FLAG.OVERFLOWDETECTION = 0; // CFWB does not support automated overflow and saturation detection } else if (hdr->TYPE==CNT) { if (VERBOSE_LEVEL>7) fprintf(stdout, "%s: Neuroscan format (count=%d)\n",__func__, (int)count); // TODO: fix handling of AVG and EEG files if (count < 900) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, 900); count += ifread(hdr->AS.Header+count, 1, 900-count, hdr); } hdr->VERSION = atof((char*)hdr->AS.Header + 8); int8_t FLAG_CNT32 = 0; uint16_t gdftyp = 0; uint8_t minor_revision = hdr->AS.Header[804]; size_t eventtablepos = leu32p(hdr->AS.Header+886); uint32_t nextfilepos = leu32p(hdr->AS.Header+12); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s: Neuroscan format: minor revision %i eventtablepos: %i nextfilepos: %i\n", __func__, minor_revision, (unsigned)eventtablepos, nextfilepos); /* make base of filename */ size_t i=0, j=0; while (hdr->FileName[i] != '\0') { if ((hdr->FileName[i]=='/') || (hdr->FileName[i]=='\\')) { j=i+1; } i++; } /* skip the extension '.cnt' of filename base and copy to Patient.Id */ strncpy(hdr->Patient.Id, hdr->FileName+j, min(MAX_LENGTH_PID,strlen(hdr->FileName)-j-4)); hdr->Patient.Id[MAX_LENGTH_PID] = 0; ptr_str = (char*)hdr->AS.Header+136; hdr->Patient.Sex = (ptr_str[0]=='f')*2 + (ptr_str[0]=='F')*2 + (ptr_str[0]=='M') + (ptr_str[0]=='m'); ptr_str = (char*)hdr->AS.Header+137; hdr->Patient.Handedness = (ptr_str[0]=='r')*2 + (ptr_str[0]=='R')*2 + (ptr_str[0]=='L') + (ptr_str[0]=='l'); ptr_str = (char*)hdr->AS.Header+225; char tmp[6]; tmp[2] = '\0'; // make sure tmp is 0-terminated tm_time.tm_sec = atoi(memcpy(tmp,ptr_str+16,2)); tm_time.tm_min = atoi(memcpy(tmp,ptr_str+13,2)); tm_time.tm_hour = atoi(memcpy(tmp,ptr_str+10,2)); tm_time.tm_mday = atoi(memcpy(tmp,ptr_str,2)); tm_time.tm_mon = atoi(memcpy(tmp,ptr_str+3,2))-1; tm_time.tm_year = atoi(memcpy(tmp,ptr_str+6,2)); if (tm_time.tm_year<=80) tm_time.tm_year += 100; hdr->T0 = tm_time2gdf_time(&tm_time); hdr->NS = leu16p(hdr->AS.Header+370); hdr->HeadLen = 900+hdr->NS*75; hdr->SampleRate = leu16p(hdr->AS.Header+376); hdr->AS.bpb = hdr->NS*2; if (hdr->AS.Header[20]==1) { // Neuroscan EEG hdr->NRec = leu16p(hdr->AS.Header+362); hdr->SPR = leu16p(hdr->AS.Header+368); hdr->AS.bpb = 2*hdr->NS*hdr->SPR+1+2+2+4+2+2; size_t bpb4 = 4*hdr->NS*hdr->SPR+1+2+2+4+2+2; struct stat FileBuf; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): Neuroscan format: minor rev=%i bpb2:%i bpb4:%i\n", __func__,__LINE__, minor_revision, (unsigned)hdr->AS.bpb, (unsigned)bpb4); switch (minor_revision) { case 9: // TODO: FIXME fprintf(stderr,"Warning biosig/%s (line %d) (CNT/EEG): minor revision %i is experimental\n", __func__,__LINE__, minor_revision); gdftyp = 3; hdr->FILE.LittleEndian = 0; stat(hdr->FileName,&FileBuf); if (hdr->NRec <= 0) { hdr->NRec = (min(FileBuf.st_size, nextfilepos) - hdr->HeadLen)/hdr->AS.bpb; } break; case 12: gdftyp = 3; eventtablepos = hdr->HeadLen + hdr->NRec*hdr->AS.bpb; break; default: if (minor_revision != 16) fprintf(stderr,"Warning biosig/%s (line %d) sopen (CNT/EEG): minor revision %i not tested\n", __func__,__LINE__, minor_revision); if (VERBOSE_LEVEL>7) fprintf(stdout,"biosig/%s (line %d) (CNT/EEG): %i %i %i %i %i %i \n", __func__,__LINE__, (int)hdr->NRec, hdr->SPR, hdr->NS, (int)eventtablepos, (int)(hdr->AS.bpb * hdr->NRec + hdr->HeadLen), (int)(bpb4 * hdr->NRec + hdr->HeadLen)); if ((size_t)(hdr->AS.bpb * hdr->NRec + hdr->HeadLen) == eventtablepos) gdftyp = 3; else if ((bpb4 * hdr->NRec + hdr->HeadLen) == eventtablepos) { hdr->AS.bpb = bpb4; gdftyp = 5; } else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CNT/EEG: type of format not supported"); return(hdr); } } } else { // Neuroscan CNT hdr->SPR = 1; eventtablepos = leu32p(hdr->AS.Header+886); if (nextfilepos > 0) { ifseek (hdr,nextfilepos+52,SEEK_SET); FLAG_CNT32 = (ifgetc(hdr)==1); ifseek (hdr,count,SEEK_SET); } gdftyp = FLAG_CNT32 ? 5 : 3; hdr->AS.bpb = hdr->NS*GDFTYP_BITS[gdftyp]/8; hdr->NRec = (eventtablepos - hdr->HeadLen) / hdr->AS.bpb; if (VERBOSE_LEVEL > 7) fprintf(stdout,"biosig/%s (line %d) (CNT): %i %i %i %i %i \n", __func__,__LINE__, (int)hdr->NRec, hdr->SPR, hdr->NS, (int)eventtablepos, (int)(hdr->AS.bpb * hdr->NRec + hdr->HeadLen) ); } if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*) realloc(Header1, hdr->HeadLen); count += ifread(Header1+count, 1, hdr->HeadLen-count, hdr); } hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); size_t bi = 0; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; uint8_t* Header2 = hdr->AS.Header+900+k*75; hc->Transducer[0] = '\0'; hc->GDFTYP = gdftyp; hc->SPR = hdr->SPR; // *(int32_t*)(Header1+56); const size_t len = min(10, MAX_LENGTH_LABEL); if (VERBOSE_LEVEL > 7) fprintf(stdout,"biosig/%s (line %d): #%d label <%s>\n", __func__,__LINE__,(int)k, (char*) Header2 ); strncpy(hc->Label, (char*)Header2, len); hc->Label[len] = 0; hc->LeadIdCode = 0; hc->PhysDimCode = 4256+19; // uV hc->Cal = lef32p(Header2+59); hc->Cal *= lef32p(Header2+71)/204.8; hc->Off = lef32p(Header2+47) * hc->Cal; hc->HighPass = CNT_SETTINGS_HIGHPASS[(uint8_t)Header2[64]]; hc->LowPass = CNT_SETTINGS_LOWPASS[(uint8_t)Header2[65]]; hc->Notch = CNT_SETTINGS_NOTCH[(uint8_t)Header1[682]]; hc->OnOff = 1; if (FLAG_CNT32) { hc->DigMax = (double)(0x007fffff); hc->DigMin = -(double)(int32_t)(0xff800000); } else { hc->DigMax = (double)32767; hc->DigMin = -(double)32768; } hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->bi = bi; bi += (size_t)hdr->SPR * (GDFTYP_BITS[hc->GDFTYP]>>3); } if ((eventtablepos < nextfilepos) && !ifseek(hdr, eventtablepos, SEEK_SET)) { /* read event table */ hdr->EVENT.SampleRate = hdr->SampleRate; ifread(tmp, 9, 1, hdr); int8_t TeegType = tmp[0]; uint32_t TeegSize = leu32p(tmp+1); // uint32_t TeegOffset = leu32p(tmp+5); // not used int fieldsize; switch (TeegType) { case 2: case 3: fieldsize = 19; break; default: fieldsize = 8; } uint8_t* buf = (uint8_t*)malloc(TeegSize); count = ifread(buf, 1, TeegSize, hdr); hdr->EVENT.N = count/fieldsize; if (reallocEventTable(hdr, hdr->EVENT.N) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; hdr->EVENT.DUR=NULL; hdr->EVENT.CHN=NULL; for (k = 0; k < hdr->EVENT.N; k++) { hdr->EVENT.TYP[k] = leu16p(buf+k*fieldsize); // stimulus type uint8_t tmp8 = buf[k*fieldsize+3]; if (tmp8>0) { if (hdr->EVENT.TYP[k]>0) fprintf(stdout,"Warning %s (line %d) event %i: both, stimulus and response, codes (%i/%i) are non-zero. response code is ignored.\n",__func__,__LINE__, (int)k+1,hdr->EVENT.TYP[k],tmp8); else hdr->EVENT.TYP[k] |= tmp8 | 0x80; // response type } hdr->EVENT.POS[k] = leu32p(buf+4+k*fieldsize); // 0-based indexing if (TeegType != 3) hdr->EVENT.POS[k] = (hdr->EVENT.POS[k] - hdr->HeadLen) / hdr->AS.bpb; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[k] = 0; #endif } free(buf); } ifseek(hdr, hdr->HeadLen, SEEK_SET); hdr->FLAG.OVERFLOWDETECTION = 0; // automated overflow and saturation detection not supported } else if (hdr->TYPE==CTF) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s: CTF[101]: %s\n", __func__, hdr->FileName); char *f0 = hdr->FileName; char *f1 = (char*)malloc(strlen(f0)+6); strcpy(f1, f0); // Flawfinder: ignore strcpy(strrchr(f1,'.')+1,"res4"); // Flawfinder: ignore if (VERBOSE_LEVEL>8) fprintf(stdout,"CTF[102]: %s\n\t%s\n",f0,f1); if (strcmp(strrchr(hdr->FileName,'.'),".res4")) { if (VERBOSE_LEVEL>8) fprintf(stdout,"CTF[103]:\n"); ifclose(hdr); hdr->FileName = f1; hdr = ifopen(hdr,"rb"); count = 0; } hdr->HeadLen = 1844; if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } if (VERBOSE_LEVEL>8) fprintf(stdout,"CTF[104]: %i %s\n\t%s\n",(int)count,f0,f1); struct tm t; sscanf((char*)(hdr->AS.Header+778),"%d:%d:%d",&t.tm_hour,&t.tm_min,&t.tm_sec); sscanf((char*)(hdr->AS.Header+778+255),"%d/%d/%d",&t.tm_mday,&t.tm_mon,&t.tm_year); --t.tm_mon; hdr->T0 = tm_time2gdf_time(&t); hdr->SPR = bei32p(hdr->AS.Header+1288); hdr->NS = bei16p(hdr->AS.Header+1292); hdr->SampleRate = bef64p(hdr->AS.Header+1296); // double Dur = bef64p(hdr->AS.Header+1304); hdr->NRec = bei16p(hdr->AS.Header+1312); strncpy(hdr->Patient.Id,(char*)(hdr->AS.Header+1712),min(MAX_LENGTH_PID,32)); int32_t CTF_RunSize = bei32p(hdr->AS.Header+1836); //int32_t CTF_RunSize2 = bei32p(hdr->AS.Header+1844); hdr->HeadLen=1844+CTF_RunSize+2; if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } int16_t CTF_NumberOfFilters = bei16p(hdr->AS.Header+1844+CTF_RunSize); hdr->HeadLen = 1844+CTF_RunSize+2+CTF_NumberOfFilters*26+hdr->NS*(32+48+1280); if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } ifclose(hdr); size_t pos = 1846+CTF_RunSize+CTF_NumberOfFilters*26; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); hdr->AS.bpb = 0; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; strncpy(hc->Label,(const char*)(hdr->AS.Header+pos+k*32),min(32,MAX_LENGTH_LABEL)); hc->Label[min(MAX_LENGTH_LABEL,32)]=0; if (VERBOSE_LEVEL>8) fprintf(stdout,"CTF[107]: #%i\t%x\t%s\n",(int)k,(int)(pos+k*32),hc->Label); int16_t index = bei16p(hdr->AS.Header+pos+hdr->NS*32+k*(48+1280)); // index hc->Cal = 1.0/bef64p(hdr->AS.Header+pos+hdr->NS*32+k*(48+1280)+16); switch (index) { case 0: case 1: case 9: hc->Cal /= bef64p(hdr->AS.Header+pos+hdr->NS*32+k*(48+1280)+8); } hc->GDFTYP = 5; hc->SPR = hdr->SPR; hc->LeadIdCode = 0; hc->Off = 0.0; hc->OnOff = 1; hc->PhysDimCode = 0; hc->Transducer[0] = 0; hc->DigMax = ldexp( 1.0,31); hc->DigMin = ldexp(-1.0,31); hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->bi = hdr->AS.bpb; hdr->AS.bpb += hdr->SPR*(GDFTYP_BITS[hc->GDFTYP]>>3); } if (VERBOSE_LEVEL>8) fprintf(stdout,"CTF[109] %s: \n",hdr->FileName); /********** read marker file **********/ char *f2 = (char*)malloc(strlen(f0)+16); strcpy(f2, f0); // Flawfinder: ignore strcpy(strrchr(f2,FILESEP)+1,"MarkerFile.mrk"); // Flawfinder: ignore hdr->EVENT.SampleRate = hdr->SampleRate; hdr->EVENT.N = 0; hdr->FileName = f2; hdr = ifopen(hdr,"rb"); if (hdr->FILE.OPEN) { count = 0; char *vmrk=NULL; while (!ifeof(hdr)) { size_t bufsiz = max(2*count, PAGESIZE); vmrk = (char*)realloc(vmrk, bufsiz+1); count += ifread(vmrk+count, 1, bufsiz-count, hdr); } vmrk[count] = 0; // add terminating \0 character ifclose(hdr); char *t1, *t2; float u1,u2; t1 = strstr(vmrk,"TRIAL NUMBER"); t2 = strtok(t1,"\x0a\x0d"); size_t N = 0; t2 = strtok(NULL,"\x0a\x0d"); while (t2 != NULL) { sscanf(t2,"%f %f",&u1,&u2); if (N+1 >= hdr->EVENT.N) { hdr->EVENT.N += 256; if (reallocEventTable(hdr, hdr->EVENT.N) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } hdr->EVENT.TYP[N] = 1; hdr->EVENT.POS[N] = (uint32_t)(u1*hdr->SPR+u2*hdr->SampleRate); hdr->EVENT.DUR[N] = 0; hdr->EVENT.CHN[N] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[N] = 0; #endif N++; t2 = strtok(NULL,"\x0a\x0d"); } hdr->EVENT.N = N; free(vmrk); } free(f2); /********** end reading event/marker file **********/ strcpy(strrchr(f1,'.')+1,"meg4"); hdr->FileName = f1; hdr = ifopen(hdr,"rb"); hdr->HeadLen = 8; hdr->HeadLen = ifread(hdr->AS.Header,1,8,hdr); // hdr->FLAG.SWAP= (__BYTE_ORDER == __LITTLE_ENDIAN); hdr->FILE.LittleEndian = 0; hdr->FileName = f0; free(f1); } else if (hdr->TYPE==DEMG) { hdr->VERSION = leu16p(hdr->AS.Header+4); hdr->NS = leu16p(hdr->AS.Header+6); hdr->SPR = 1; hdr->SampleRate = leu32p(hdr->AS.Header+8); hdr->NRec = leu32p(hdr->AS.Header+12); uint16_t gdftyp = 16; uint8_t bits = hdr->AS.Header[16]; double PhysMin = (double)(int8_t)hdr->AS.Header[17]; double PhysMax = (double)(int8_t)hdr->AS.Header[18]; double Cal = 1.0; double Off = 0.0; if (hdr->VERSION==1) { gdftyp = 16; // float32 Cal = 1.0; Off = 0.0; } else if (hdr->VERSION==2) { gdftyp = 4; // uint16 Cal = (PhysMax-PhysMin)/((1<CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); hdr->AS.bpb = 0; for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE* hc = hdr->CHANNEL+k; hc->GDFTYP = gdftyp; hc->SPR = 1; hc->Cal = Cal; hc->Off = Off; hc->OnOff = 1; hc->Transducer[0] = '\0'; hc->LowPass = 450; hc->HighPass = 20; hc->PhysMax = PhysMax; hc->PhysMin = PhysMin; hc->DigMax = DigMax; hc->DigMin = DigMin; hc->LeadIdCode = 0; hc->bi = hdr->AS.bpb; hdr->AS.bpb += GDFTYP_BITS[gdftyp]>>3; } hdr->FLAG.OVERFLOWDETECTION = 0; // automated overflow and saturation detection not supported hdr->HeadLen = 19; ifseek(hdr, 19, SEEK_SET); } else if ((hdr->TYPE==EAS) || (hdr->TYPE==EZ3) || (hdr->TYPE==ARC)) { while (!ifeof(hdr)) { size_t bufsiz = max(2*count, PAGESIZE); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); sopen_cadwell_read(hdr); } else if (hdr->TYPE==EBS) { fprintf(stderr,"Warning SOPEN(EBS): support for EBS format is experimental\n"); /** Fixed Header (32 bytes) **/ uint32_t EncodingID = beu32p(hdr->AS.Header+8); hdr->NS = beu32p(hdr->AS.Header+12); hdr->SPR = beu64p(hdr->AS.Header+16); uint64_t datalen = beu64p(hdr->AS.Header+24); enum encoding { TIB_16 = 0x00000000, CIB_16 = 0x00000001, TIL_16 = 0x00000002, CIL_16 = 0x00000003, TI_16D = 0x00000010, CI_16D = 0x00000011 }; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); size_t pos = 32; uint32_t tag, len; /** Variable Header **/ tag = beu32p(hdr->AS.Header+pos); while (tag) { len = beu32p(hdr->AS.Header+pos+4)<<2; pos += 8; if (count < pos+len+8) { hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header,count*2); count += ifread(hdr->AS.Header+count, 1, count, hdr); } if (VERBOSE_LEVEL>8) fprintf(stdout,"%6i %6i tag=%08x len=%5i: |%c%c%c%c| %s\n", (int)pos, (int)count,tag, len, Header1[0x015f], Header1[0x0160], Header1[0x0161], Header1[0x0162], hdr->AS.Header+pos); /* Appendix A */ switch (tag) { case 0x00000002: break; case 0x00000004: strncpy(hdr->Patient.Name,Header1+pos,MAX_LENGTH_NAME); break; case 0x00000006: strncpy(hdr->Patient.Id,Header1+pos,MAX_LENGTH_PID); break; case 0x00000008: { struct tm t; t.tm_mday = (Header1[pos+6]-'0')*10 + (Header1[pos+7]-'0'); Header1[pos+6] = 0; t.tm_mon = atoi(Header1+pos+4) + 1; Header1[pos+4] = 0; t.tm_year = atoi(Header1+pos) - 1900; t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; hdr->Patient.Birthday = tm_time2gdf_time(&t); break; } case 0x0000000a: hdr->Patient.Sex = bei32p(hdr->AS.Header+pos); break; case 0x00000010: hdr->SampleRate = atof(Header1+pos); break; case 0x00000012: // strndup(hdr->ID.Hospital,Header1+pos,len); hdr->ID.Hospital = malloc(len+1); if (hdr->ID.Hospital) { hdr->ID.Hospital[len] = 0; strncpy(hdr->ID.Hospital,Header1+pos,len); } break; case 0x00000003: // units { int k; char* ptr = Header1+pos; for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; hc->Cal = strtod(ptr, &ptr); hc->PhysDimCode = PhysDimCode(ptr); } } break; case 0x00000005: { int k; char* ptr = Header1+pos; for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; int c = 0; while (beu32p(ptr)) { if (VERBOSE_LEVEL>8) fprintf(stdout,"0x05: [%i %i] |%c%c%c%c%c%c%c%c|\n",k,c,ptr[0],ptr[1],ptr[2],ptr[3],ptr[4],ptr[5],ptr[6],ptr[7]); if ((*ptr) && (c<=MAX_LENGTH_LABEL)) { hc->Label[c++] = *ptr; } ptr++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"0x05: %08x\n",beu32p(ptr)); hc->Label[c] = 0; ptr += 4; while (bei32p(ptr)) ptr++; ptr += 4; } } break; case 0x0000000b: // recording time if (Header1[pos+8]=='T') { struct tm t; t.tm_sec = atoi(Header1+pos+13); Header1[pos+13] = 0; t.tm_min = atoi(Header1+pos+11); Header1[pos+11] = 0; t.tm_hour = atoi(Header1+pos+9); Header1[pos+8] = 0; t.tm_mday = atoi(Header1+pos+6); Header1[pos+6] = 0; t.tm_mon = atoi(Header1+pos+4) + 1; Header1[pos+4] = 0; t.tm_year = atoi(Header1+pos) - 1900; hdr->T0 = tm_time2gdf_time(&t); if (VERBOSE_LEVEL>8) fprintf(stdout,"<%s>, T0 = %s\n",Header1+pos,asctime(&t)); } if (VERBOSE_LEVEL>8) fprintf(stdout,"<%s>\n",Header1+pos); break; case 0x0000000f: // filter { int k; char* ptr = Header1+pos; for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; switch (beu32p(ptr)) { case 1: // lowpass hc->LowPass = strtod(ptr+4, &ptr); break; case 2: // high pass hc->HighPass = strtod(ptr+4, &ptr); break; default: fprintf(stderr,"Warning SOPEN (EBS): unknown filter\n"); } while (bei32p(ptr) != -1) ptr++; ptr += 4; } } break; } pos += len; tag = beu32p(hdr->AS.Header+pos); } hdr->HeadLen = pos; ifseek(hdr,pos,SEEK_SET); hdr->AS.first = 0; hdr->AS.length = 0; if ((bei64p(hdr->AS.Header+24)==-1) && (bei64p(hdr->AS.Header+24)==-1)) { /* if data length is not present */ struct stat FileBuf; stat(hdr->FileName,&FileBuf); hdr->FILE.size = FileBuf.st_size; datalen = (hdr->FILE.size - hdr->HeadLen); } else datalen <<= 2; /** Encoded Signal Data (4*d bytes) **/ size_t spr = datalen/(2*hdr->NS); switch (EncodingID) { case TIB_16: hdr->SPR = 1; hdr->NRec = spr; hdr->FILE.LittleEndian = 0; break; case CIB_16: hdr->SPR = spr; hdr->NRec = 1; hdr->FILE.LittleEndian = 0; break; case TIL_16: hdr->SPR = 1; hdr->NRec = spr; hdr->FILE.LittleEndian = 1; break; case CIL_16: hdr->SPR = spr; hdr->NRec = 1; hdr->FILE.LittleEndian = 1; break; case TI_16D: case CI_16D: default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "EBS: unsupported Encoding"); return(hdr); } typeof(hdr->NS) k; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; hc->GDFTYP = 3; // int16 hc->SPR = hdr->SPR; // int16 hc->bi = k*2; hc->Off = 0.0; hc->OnOff = 1; hc->DigMax = (double)32767; hc->DigMin = (double)-32768; hc->PhysMax = hc->DigMax*hc->Cal; hc->PhysMin = hc->DigMin*hc->Cal; hc->Transducer[0] = 0; hc->LeadIdCode = 0; hc->Notch = NAN; hc->Impedance = INFINITY; hc->fZ = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; } hdr->AS.bpb = hdr->SPR*hdr->NS*2; /** Optional Second Variable Header **/ } else if (hdr->TYPE==EEG1100) { // the information of this format is derived from nk2edf-0.43beta-src of Teunis van Beelen if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %s(...)\n",__FILE__,__LINE__,__func__); char *fn = (char*)malloc((strlen(hdr->FileName)+5)*sizeof(char)); strcpy(fn, hdr->FileName); // Flawfinder: ignore char *LOG=NULL; /* read .pnt */ if (strrchr(fn,FILESEP)) strncpy(strrchr(fn,FILESEP)+1, (char*)(hdr->AS.Header + 32), 4); else strncpy(fn, (char*)(hdr->AS.Header + 32), 4); FILE *fid = fopen(fn,"rb"); if (fid != NULL) { count = 0; while (!feof(fid)) { size_t r = max(count*2, PAGESIZE); LOG = (char*) realloc(LOG,r+1); count += fread(LOG+count,1,r-count,fid); } fclose(fid); LOG[count] = 0; // Name: @0x062e if (!hdr->FLAG.ANONYMOUS) { strncpy(hdr->Patient.Name, LOG+0x62e, MAX_LENGTH_PID); hdr->Patient.Name[MAX_LENGTH_NAME] = 0; } // Id: @0x0604 strncpy(hdr->Patient.Id, LOG+0x604, MAX_LENGTH_PID); hdr->Patient.Id[MAX_LENGTH_PID] = 0; // Gender: @0x064a hdr->Patient.Sex = (toupper(LOG[0x064a])=='M') + 2*(toupper(LOG[0x064a])=='F') + 2*(toupper(LOG[0x064a])=='W'); // Birthday: @0x0660 sscanf((char*)(LOG+0x0660),"%04u/%02u/%02u",&tm_time.tm_year,&tm_time.tm_mon,&tm_time.tm_mday); tm_time.tm_hour = 12; tm_time.tm_min = 0; tm_time.tm_sec = 0; tm_time.tm_year -= 1900; tm_time.tm_mon--; tm_time.tm_isdst = -1; hdr->Patient.Birthday = tm_time2gdf_time(&tm_time); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %s(...)\n",__FILE__,__LINE__,__func__); size_t n1,n2,k2,pos1,pos2; n1 = hdr->AS.Header[145]; if ((n1*20+0x92) > count) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,n1*20+0x92+1); count += ifread(hdr->AS.Header+count, 1, n1*20+0x92-count,hdr); } // Start date: @0x0040 sscanf((char*)(hdr->AS.Header+0x40),"%04u%02u%02u%02u%02u%02u",&tm_time.tm_year,&tm_time.tm_mon,&tm_time.tm_mday,&tm_time.tm_hour,&tm_time.tm_min,&tm_time.tm_sec); tm_time.tm_year -= 1900; tm_time.tm_mon--; // Jan=0, Feb=1, ... tm_time.tm_isdst = -1; //hdr->T0 = tm_time2gdf_time(&tm_time); int TARGET_SEGMENT = hdr->FLAG.TARGETSEGMENT; int numSegments = 0; size_t Total_NRec = 0; uint8_t *h2 = (uint8_t*)malloc(22); uint8_t *h3 = (uint8_t*)malloc(40); for (k=0; k7) fprintf(stdout,"%s (line %d) %s(...) k=%d\n",__FILE__,__LINE__,__func__,k); pos1 = leu32p(hdr->AS.Header+146+k*20); ifseek(hdr, pos1, SEEK_SET); ifread(h2, 1, 22, hdr); n2 = h2[17]; if (n2>1) { h2 = (uint8_t*)realloc(h2,2+n2*20); ifread(h2+22, 1, 2+n2*20-22, hdr); } if (reallocEventTable(hdr, hdr->EVENT.N+n2) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; for (k2=0; k2\n",pos3,(char*)h3+1); if (!strncmp((char*)h3+1,"TIME",4)) { sscanf((char*)(h3+5),"%02u%02u%02u",&tm_time.tm_hour,&tm_time.tm_min,&tm_time.tm_sec); } typeof(hdr->NS) NS = h3[38]; typeof(hdr->SampleRate) SampleRate = leu16p(h3+26) & 0x3fff; nrec_t NRec = (nrec_t)(leu32p(h3+28) * SampleRate * 0.1); size_t HeadLen = pos2 + 39 + 10*NS; hdr->EVENT.TYP[hdr->EVENT.N] = 0x7ffe; hdr->EVENT.POS[hdr->EVENT.N] = Total_NRec; hdr->EVENT.DUR[hdr->EVENT.N] = NRec; hdr->EVENT.CHN[hdr->EVENT.N] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif Total_NRec += NRec; hdr->EVENT.N++; numSegments++; --TARGET_SEGMENT; // decrease target segment counter if (TARGET_SEGMENT != 0) { continue; } hdr->T0 = tm_time2gdf_time(&tm_time); hdr->NS = NS; hdr->SampleRate = SampleRate; hdr->EVENT.SampleRate = SampleRate; hdr->NRec = NRec; hdr->HeadLen = HeadLen; hdr->SPR = 1; int16_t gdftyp = 128; // Nihon-Kohden int16 format hdr->AS.bpb = ((hdr->NS*GDFTYP_BITS[gdftyp])>>3)+2; // fprintf(stdout,"NK k=%i <%s> k2=%i <%s>\n",k,h2+1,k2,h3+1); // fprintf(stdout,"[%i %i]:pos=%u (%x) length=%Li(%Lx).\n",k,k2,pos2,pos2,hdr->NRec*(hdr->NS+1)*2,hdr->NRec*(hdr->NS+1)*2); h3 = (uint8_t*)realloc(h3,32 + hdr->NS*10); pos3 += ifread(h3+pos3, 1, 32+hdr->NS*10 - pos3, hdr); hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); int k3; for (k3=0; k3NS; k3++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k3; uint8_t u8 = h3[39+k3*10]; switch (u8) { case 0: strcpy(hc->Label,"Fp1"); break; case 1: strcpy(hc->Label,"Fp2"); break; case 2: strcpy(hc->Label,"F3"); break; case 3: strcpy(hc->Label,"F4"); break; case 4: strcpy(hc->Label,"C3"); break; case 5: strcpy(hc->Label,"C4"); break; case 6: strcpy(hc->Label,"P3"); break; case 7: strcpy(hc->Label,"P4"); break; case 8: strcpy(hc->Label,"O1"); break; case 9: strcpy(hc->Label,"O2"); break; case 10: strcpy(hc->Label,"F7"); break; case 11: strcpy(hc->Label,"F8"); break; case 12: strcpy(hc->Label,"T3"); break; case 13: strcpy(hc->Label,"T4"); break; case 14: strcpy(hc->Label,"T5"); break; case 15: strcpy(hc->Label,"T6"); break; case 16: strcpy(hc->Label,"Fz"); break; case 17: strcpy(hc->Label,"Cz"); break; case 18: strcpy(hc->Label,"Pz"); break; case 19: strcpy(hc->Label,"E"); break; case 20: strcpy(hc->Label,"PG1"); break; case 21: strcpy(hc->Label,"PG2"); break; case 22: strcpy(hc->Label,"A1"); break; case 23: strcpy(hc->Label,"A2"); break; case 24: strcpy(hc->Label,"T1"); break; case 25: strcpy(hc->Label,"T2"); break; case 74: strcpy(hc->Label,"BN1"); break; case 75: strcpy(hc->Label,"BN2"); break; case 76: strcpy(hc->Label,"Mark1"); break; case 77: strcpy(hc->Label,"Mark2"); break; case 100: strcpy(hc->Label,"X12/BP1"); break; case 101: strcpy(hc->Label,"X13/BP2"); break; case 102: strcpy(hc->Label,"X14/BP3"); break; case 103: strcpy(hc->Label,"X15/BP4"); break; case 254: strcpy(hc->Label,"-"); break; case 255: strcpy(hc->Label,"Z"); break; default: if ((25Label,"X%u",u8-25); else if ((36Label,"-"); else if ((41Label,"DC%02u",u8-41); else if ((77Label,"-"); else if ((103Label,"X%u",u8-88); } if ((41PhysDimCode = 4274; // mV hc->PhysMin = -12002.9; hc->PhysMax = 12002.56; } else { hc->PhysDimCode = 4275; // uV hc->PhysMin = -3200.0; hc->PhysMax = 3200.0*((1<<15)-1)/(1<<15); } hc->GDFTYP = 128; // Nihon-Kohden int16 format hc->DigMax = 32767.0; hc->DigMin = -32768.0; hc->Cal = (hc->PhysMax - hc->PhysMin) / (hc->DigMax - hc->DigMin); hc->Off = hc->PhysMin - hc->Cal * hc->DigMin; hc->SPR = 1; hc->LeadIdCode = 0; hc->OnOff = 1; hc->Transducer[0] = 0; hc->bi = (k3*GDFTYP_BITS[gdftyp])>>3; // hc->LowPass = 0.1; // hc->HighPass = 100; // hdr->CHANNEL[k3].Notch = 0; } } } free(h2); free(h3); ifseek(hdr, hdr->HeadLen, SEEK_SET); if ((numSegments>1) && (hdr->FLAG.TARGETSEGMENT==1)) fprintf(stdout,"File %s has more than one (%i) segment; use TARGET_SEGMENT argument to select other segments.\n",hdr->FileName,numSegments); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %s(...) <%s>\n",__FILE__,__LINE__,__func__,fn); /* read .log */ char *c = strrchr(fn,'.'); if (c != NULL) { strcpy(c+1,"log"); FILE *fid = fopen(fn,"rb"); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %s(...) <%s>\n",__FILE__,__LINE__,__func__,fn); if (fid == NULL) { strcpy(c+1,"LOG"); fid = fopen(fn,"rb"); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %s(...) <%s>\n",__FILE__,__LINE__,__func__,fn); if (fid != NULL) { count = 0; while (!feof(fid)) { size_t c = max(2*count, 11520); LOG = (char*) realloc(LOG, c+1); count += fread(LOG+count, 1, c-count, fid); } fclose(fid); LOG[count]=0; for (k=0; k<(unsigned)LOG[145]; k++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %s(...) %i,%i<%s>\n",__FILE__,__LINE__,__func__,(int)k,(int)count,fn); //uint32_t lba = leu32p(LOG+146+k*20); uint32_t lba = atoi(LOG+146+k*20); if (VERBOSE_LEVEL>7) fprintf(stdout,"EEG1100 [253]: <%d> %d 0x%x\n",(int)k,lba,lba); //break; // FIXME: there is at least one EEG1100C file that breaks this uint32_t N = LOG[lba+18]; if (VERBOSE_LEVEL>7) fprintf(stdout,"EEG1100 [254]: <%d> %d %d\n",(int)k,(int)lba,N); if (reallocEventTable(hdr, hdr->EVENT.N+N) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; size_t k1; for (k1=0; k17) fprintf(stdout,"EEG1100 [257]: [%d,%d] N=%d,%d\n",(int)k,(int)k1,N,hdr->EVENT.N); if (VERBOSE_LEVEL>8) fprintf(stdout,"EEG1100 [258]: [%d,%d] N=%d, <%s>\n",(int)k,(int)k1,hdr->EVENT.N,(char*)(LOG+lba+20+k1*45)); // FreeTextEvent(hdr,hdr->EVENT.N,(char*)(LOG+lba+20+k1*45)); if (VERBOSE_LEVEL>7) { fprintf(stdout," <%s>\n <%s>\n",(char*)(LOG+lba+9+k1*45),(char*)(LOG+lba+29+k1*45)); int kk; for (kk=0; kk<45; kk++) putchar(LOG[lba+9+k1*45+kk]); putchar('\n'); } char *desc = (char*)(LOG+lba+9+k1*45); if (desc[0] == 0) continue; /* char secstr[7]; memcpy(secstr, LOG+lba+29+k1*45, 6); secstr[6] = 0; */ if (VERBOSE_LEVEL>7) fprintf(stdout,"EEG1100 [259]: <%s> <%s>",desc,(char*)LOG+lba+29+k1*45); /* int c = sscanf((char*)(LOG+lba+46+k1*45),"(%02u%02u%02u%02u%02u%02u)",&tm_time.tm_year,&tm_time.tm_mon,&tm_time.tm_mday,&tm_time.tm_hour,&tm_time.tm_min,&tm_time.tm_sec); if (c<6) continue; tm_time.tm_year += tm_time.tm_year<20 ? 100:0; tm_time.tm_mon--; // Jan=0, Feb=1, ... gdf_time t0 = tm_time2gdf_time(&tm_time); char tmpstr[80]; strftime(tmpstr,80,"%Y-%m-%d %H:%M:%S", &tm_time); if (VERBOSE_LEVEL>7) fprintf(stdout,"EEG1100 [261]: %s\n",tmpstr); */ if (1) //(t0 >= hdr->T0) { hdr->EVENT.TYP[hdr->EVENT.N] = 1; //hdr->EVENT.POS[hdr->EVENT.N] = (uint32_t)(ldexp(t0 - hdr->T0,-32)*86400*hdr->SampleRate); // 0-based indexing //hdr->EVENT.POS[hdr->EVENT.N] = (uint32_t)(atoi(strtok((char*)(LOG+lba+29+k1*45),"("))*hdr->SampleRate); hdr->EVENT.POS[hdr->EVENT.N] = (uint32_t)(atoi(strtok((char*)(LOG+lba+29+k1*45),"("))*hdr->SampleRate); hdr->EVENT.DUR[hdr->EVENT.N] = 0; hdr->EVENT.CHN[hdr->EVENT.N] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif FreeTextEvent(hdr,hdr->EVENT.N,desc); hdr->EVENT.N++; } } } } } hdr->AS.auxBUF = (uint8_t*)LOG; free(fn); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) %s(...)\n",__FILE__,__LINE__,__func__); } else if (hdr->TYPE==EEProbe) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "EEProbe currently not supported"); } else if (hdr->TYPE==EGI) { fprintf(stdout,"Reading EGI is under construction\n"); uint16_t NEC = 0; // specific for EGI format uint16_t gdftyp = 3; // BigEndian hdr->FILE.LittleEndian = 0; hdr->VERSION = beu32p(hdr->AS.Header); if (hdr->VERSION==2 || hdr->VERSION==3) gdftyp = 3; // int32 else if (hdr->VERSION==4 || hdr->VERSION==5) gdftyp = 16; // float else if (hdr->VERSION==6 || hdr->VERSION==7) gdftyp = 17; // double tm_time.tm_year = beu16p(hdr->AS.Header+4) - 1900; tm_time.tm_mon = beu16p(hdr->AS.Header+6) - 1; tm_time.tm_mday = beu16p(hdr->AS.Header+8); tm_time.tm_hour = beu16p(hdr->AS.Header+10); tm_time.tm_min = beu16p(hdr->AS.Header+12); tm_time.tm_sec = beu16p(hdr->AS.Header+14); // tm_time.tm_sec = beu32p(Header1+16)/1000; // not supported by tm_time hdr->T0 = tm_time2gdf_time(&tm_time); hdr->SampleRate = beu16p(hdr->AS.Header+20); hdr->NS = beu16p(hdr->AS.Header+22); // uint16_t Gain = beu16p(Header1+24); // not used uint16_t Bits = beu16p(hdr->AS.Header+26); uint16_t PhysMax= beu16p(hdr->AS.Header+28); size_t POS; if (hdr->AS.Header[3] & 0x01) { // Version 3,5,7 POS = 32; for (k=0; k < beu16p(hdr->AS.Header+30); k++) { char tmp[256]; int len = hdr->AS.Header[POS]; strncpy(tmp,Header1+POS,len); tmp[len]=0; if (VERBOSE_LEVEL>7) fprintf(stdout,"EGI categorie %i: <%s>\n",(int)k,tmp); POS += *(hdr->AS.Header+POS); // skip EGI categories if (POS > count-8) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,2*count); count += ifread(hdr->AS.Header,1,count,hdr); } } hdr->NRec= beu16p(hdr->AS.Header+POS); hdr->SPR = beu32p(hdr->AS.Header+POS+2); NEC = beu16p(hdr->AS.Header+POS+6); // EGI.N POS += 8; } else { // Version 2,4,6 hdr->NRec = beu32p(hdr->AS.Header+30); NEC = beu16p(hdr->AS.Header+34); // EGI.N hdr->SPR = 1; /* see also end-of-sopen hdr->AS.spb = hdr->SPR+NEC; hdr->AS.bpb = (hdr->NS + NEC)*GDFTYP_BITS[hdr->CHANNEL[0].GDFTYP]>>3; */ POS = 36; } if (NEC>255) { /* The GDF/Biosig header supports only 255 different types of free text events // fixes CVE-2024-21795 */ fprintf(stderr,"ERROR: %s line %d: %s(...) NEC=%d too large \n", __FILE__, __LINE__, __func__, NEC); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error EGI: number of events exceeds 255\n"); return(hdr); } /* read event code description */ hdr->AS.auxBUF = (uint8_t*) realloc(hdr->AS.auxBUF,5*NEC); hdr->EVENT.CodeDesc = (typeof(hdr->EVENT.CodeDesc)) realloc(hdr->EVENT.CodeDesc,257*sizeof(*hdr->EVENT.CodeDesc)); hdr->EVENT.CodeDesc[0] = ""; // typ==0, is always empty hdr->EVENT.LenCodeDesc = NEC+1; for (k=0; k < NEC; k++) { memcpy(hdr->AS.auxBUF+5*k,Header1+POS,4); hdr->AS.auxBUF[5*k+4]=0; hdr->EVENT.CodeDesc[k+1] = (char*)hdr->AS.auxBUF+5*k; POS += 4; } hdr->HeadLen = POS; ifseek(hdr,hdr->HeadLen,SEEK_SET); hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->GDFTYP = gdftyp; hc->PhysDimCode = 4275; // "uV" hc->LeadIdCode = 0; hc->Transducer[0] = 0; sprintf(hc->Label,"# %03i",(int)k); hc->Cal = PhysMax/ldexp(1,Bits); hc->Off = 0; hc->SPR = hdr->SPR; hc->bi = k*hdr->SPR*(GDFTYP_BITS[gdftyp]>>3); if (VERBOSE_LEVEL>8) fprintf(stdout,"SOPEN(EGI): #%i %i %i\n",(int)k,Bits, PhysMax); if (Bits && PhysMax) { hc->PhysMax = PhysMax; hc->PhysMin = -PhysMax; hc->DigMax = ldexp(1,Bits); hc->DigMin = ldexp(-1,Bits); } else { /* hc->PhysMax = PhysMax; hc->PhysMin = -PhysMax; hc->DigMax = ldexp(1,Bits); hc->DigMin = ldexp(-1,Bits); */ hc->Cal = 1.0; hc->OnOff = 1; } } hdr->AS.bpb = (hdr->NS*hdr->SPR + NEC) * (GDFTYP_BITS[gdftyp]>>3); if (hdr->AS.Header[3] & 0x01) // triggered hdr->AS.bpb += 6; size_t N = 0; if (NEC > 0) { /* read event information */ size_t sz = GDFTYP_BITS[gdftyp]>>3; uint8_t *buf = (uint8_t*)calloc(NEC, sz); uint8_t *buf8 = (uint8_t*)calloc(NEC*2, 1); size_t *ix = (size_t*)calloc(NEC, sizeof(size_t)); size_t skip = hdr->AS.bpb - NEC * sz; ifseek(hdr, hdr->HeadLen + skip, SEEK_SET); typeof(NEC) k1; nrec_t k; for (k=0; (k < hdr->NRec*hdr->SPR) && !ifeof(hdr); k++) { ifread(buf, sz, NEC, hdr); ifseek(hdr, skip, SEEK_CUR); int off0, off1; if (k & 0x01) { off0 = 0; off1=NEC; } else { off0 = NEC; off1=0; } memset(buf8+off1,0,NEC); // reset for (k1=0; k1 < NEC * sz; k1++) if (buf[k1]) buf8[ off1 + k1/sz ] = 1; for (k1=0; k1 < NEC ; k1++) { if (buf8[off1 + k1] && !buf8[off0 + k1]) { /* rising edge */ ix[k1] = k; } else if (!buf8[off1 + k1] && buf8[off0 + k1]) { /* falling edge */ if (N <= (hdr->EVENT.N + NEC*2)) { N += (hdr->EVENT.N+NEC)*2; // allocate memory for this and the terminating line. if (reallocEventTable(hdr, N) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } hdr->EVENT.TYP[hdr->EVENT.N] = k1+1; hdr->EVENT.POS[hdr->EVENT.N] = ix[k1]; // 0-based indexing hdr->EVENT.CHN[hdr->EVENT.N] = 0; hdr->EVENT.DUR[hdr->EVENT.N] = k-ix[k1]; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif hdr->EVENT.N++; ix[k1] = 0; } } } for (k1 = 0; k1 < NEC; k1++) if (ix[k1]) { /* end of data */ hdr->EVENT.TYP[hdr->EVENT.N] = k1+1; hdr->EVENT.POS[hdr->EVENT.N] = ix[k1]; // 0-based indexing hdr->EVENT.CHN[hdr->EVENT.N] = 0; hdr->EVENT.DUR[hdr->EVENT.N] = k-ix[k1]; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif hdr->EVENT.N++; ix[k1] = 0; } hdr->EVENT.SampleRate = hdr->SampleRate; free(buf); free(buf8); free(ix); } ifseek(hdr,hdr->HeadLen,SEEK_SET); /* TODO: check EGI format */ } #ifdef WITH_EGIS else if (hdr->TYPE==EGIS) { fprintf(stdout,"Reading EGIS is under construction\n"); #if __BYTE_ORDER == __BIG_ENDIAN char FLAG_SWAP = hdr->FILE.LittleEndian; #elif __BYTE_ORDER == __LITTLE_ENDIAN char FLAG_SWAP = hdr->FILE.LittleEndian; #endif hdr->VERSION = *(int16_t*) mfer_swap8b(hdr->AS.Header+4, sizeof(int16_t), char FLAG_SWAP); hdr->HeadLen = *(uint16_t*) mfer_swap8b(hdr->AS.Header+6, sizeof(uint16_t), char FLAG_SWAP); //hdr->HeadLen = *(uint32_t*) mfer_swap8b(hdr->AS.Header+8, sizeof(uint32_t), char FLAG_SWAP); /* read file */ hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen+1); if (hdr->HeadLen > count) count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); hdr->AS.Header[count]=0; } #endif #ifdef WITH_EMBLA else if (hdr->TYPE==EMBLA) { while (!ifeof(hdr)) { size_t bufsiz = max(2*count, PAGESIZE); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); count = 48; int chan; uint32_t cal; float chan32; uint16_t pdc=0; while (count+8 < hdr->HeadLen) { uint32_t tag = leu32p(hdr->AS.Header+count); uint32_t len = leu32p(hdr->AS.Header+count+4); count+=8; /* uint32_t taglen[2]; uint32_t *tag = &taglen[0]; uint32_t *len = &taglen[1]; size_t c = ifread(taglen, 4, 2, hdr); if (ifeof(hdr)) break; */ if (VERBOSE_LEVEL > 7) { int ssz = min(80,len); char S[81]; strncpy(S, hdr->AS.Header+count, ssz); S[ssz]=0; fprintf(stdout,"tag %8d [%d]: <%s>\n",tag,len, S); } switch (tag) { case 32: hdr->SPR = len/2; // hdr->AS.rawdata = realloc(hdr->AS.rawdata,len); break; case 133: chan = leu16p(hdr->AS.Header+count); fprintf(stdout,"\tchan=%d\n",chan); break; case 134: // Sampling Rate hdr->SampleRate=leu32p(hdr->AS.Header+count)/1000.0; fprintf(stdout,"\tFs=%g #134\n",hdr->SampleRate); break; case 135: // cal=leu32p(hdr->AS.Header+count)/1000.0; hc->Cal = (cal==1 ? 1.0 : cal*1e-9); break; case 136: // session count fprintf(stdout,"\t%d (session count)\n",leu32p(hdr->AS.Header+count)); break; case 137: // Sampling Rate hdr->SampleRate=lef64p(hdr->AS.Header+count); fprintf(stdout,"\tFs=%g #137\n",hdr->SampleRate); break; case 141: chan32 = lef32p(hdr->AS.Header+count); fprintf(stdout,"\tchan32=%g\n",chan32); break; case 144: // Label strncpy(hc->Label, hdr->AS.Header+count, MAX_LENGTH_LABEL); hc->Label[min(MAX_LENGTH_LABEL,len)]=0; break; case 153: // Label pdc=PhysDimCode(hdr->AS.Header+count); fprintf(stdout,"\tpdc=0x%x\t<%s>\n",pdc,PhysDim3(pdc)); break; case 208: // Patient Name if (!hdr->FLAG.ANONYMOUS) strncpy(hdr->Patient.Name, hdr->AS.Header+count, MAX_LENGTH_NAME); hdr->Patient.Name[min(MAX_LENGTH_NAME,len)]=0; break; case 209: // Patient Name strncpy(hdr->Patient.Id, hdr->AS.Header+count, MAX_LENGTH_PID); hdr->Patient.Id[min(MAX_LENGTH_PID,len)]=0; break; default: ; } count+=len; } hdr->NS = 1; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE* hc = hdr->CHANNEL+k; hc->OnOff = 1; hc->GDFTYP = 3; hc->SPR = hdr->SPR; hc->Cal = 0.1; hc->Off = 0.0; hc->Transducer[0] = '\0'; hc->LowPass = NAN; hc->HighPass = NAN; hc->PhysMax = 3276.7; hc->PhysMin = -3276.8; hc->DigMax = 32767; hc->DigMin = -32768; hc->LeadIdCode = 0; hc->PhysDimCode = 4275; //uV hc->bi = k*hdr->SPR*2; char *label = (char*)(hdr->AS.Header+1034+k*512); const size_t len = min(16,MAX_LENGTH_LABEL); if ( (hdr->AS.Header[1025+k*512]=='E') && strlen(label)<13) { strcpy(hc->Label, "EEG "); strcat(hc->Label, label); // Flawfinder: ignore } else { strncpy(hc->Label, label, len); hc->Label[len]=0; } } } #endif // EMBLA else if (hdr->TYPE==EMSA) { hdr->NS = (uint8_t)hdr->AS.Header[3]; hdr->HeadLen = 1024 + hdr->NS*512; if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, hdr->HeadLen); count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); } if (count < hdr->HeadLen) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, "EMSA file corrupted"); } hdr->HeadLen = count; sprintf(hdr->Patient.Id,"%05i",leu32p(hdr->AS.Header+4)); unsigned seq_nr = hdr->AS.Header[8]; uint16_t fs = leu16p(hdr->AS.Header+9); if (fs % 10) hdr->SPR = fs; else hdr->SPR = fs/10; hdr->AS.bpb = 2*hdr->NS*hdr->SPR; hdr->NRec = (hdr->FILE.size - hdr->HeadLen) / hdr->AS.bpb; hdr->SampleRate = fs; { struct tm t; char tmp[9]; // Birthday strncpy(tmp, (char*)(hdr->AS.Header+169), 8); for (k=0; k<8; k++) if (tmp[k]<'0' || tmp[k]>'9') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; tmp[8] = 0; t.tm_mday = atoi(tmp+6); tmp[6] = 0; t.tm_mon = atoi(tmp+4)-1; tmp[4] = 0; t.tm_year = atoi(tmp+4)-1900; t.tm_hour = 12; t.tm_min = 0; t.tm_sec = 0; hdr->Patient.Birthday = tm_time2gdf_time(&t); // startdate strncpy(tmp, (char*)hdr->AS.Header+205, 8); for (k=0; k<8; k++) if (tmp[k]<'0' || tmp[k]>'9') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; tmp[8] = 0; t.tm_mday = atoi(tmp+6); tmp[6] = 0; t.tm_mon = atoi(tmp+4)-1; tmp[4] = 0; t.tm_year = atoi(tmp+4)-1900; // starttime strncpy(tmp, (char*)hdr->AS.Header+214, 8); for (k=0; k<8; k++) { if ((k==2 || k==5) && tmp[k] != ':') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; else if (tmp[k]<'0' || tmp[k]>'9') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; } tmp[8] = 0; t.tm_sec = atoi(tmp+6); tmp[5] = 0; t.tm_min = atoi(tmp+3); tmp[2] = 0; t.tm_hour= atoi(tmp); hdr->T0 = tm_time2gdf_time(&t); if (hdr->AS.B4C_ERRNUM) biosigERROR(hdr, B4C_FORMAT_UNKNOWN, "Reading EMSA file failed - invalid data / time format"); } size_t len = min(MAX_LENGTH_NAME,30); strncpy(hdr->Patient.Name, (char*)hdr->AS.Header+11, len); hdr->Patient.Name[len]=0; // equipment len = min(MAX_LENGTH_MANUF,40); strncpy(hdr->ID.Manufacturer._field, (char*)hdr->AS.Header+309, len); hdr->ID.Manufacturer._field[len]=0; char c = toupper(hdr->AS.Header[203]); hdr->Patient.Sex = (c=='M') + (c=='F')*2; c = hdr->AS.Header[204]; hdr->Patient.Handedness = (c=='D') + (c=='E')*2; //D->1: right-handed, E->2: left-handed, 0 unknown hdr->Patient.Weight = atoi((char*)(hdr->AS.Header+351)); hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE* hc = hdr->CHANNEL+k; hc->OnOff = 1; hc->GDFTYP = 3; hc->SPR = hdr->SPR; hc->Cal = 0.1; hc->Off = 0.0; hc->Transducer[0] = '\0'; hc->LowPass = NAN; hc->HighPass = NAN; hc->PhysMax = 3276.7; hc->PhysMin = -3276.8; hc->DigMax = 32767; hc->DigMin = -32768; hc->LeadIdCode = 0; hc->PhysDimCode = 4275; //uV hc->bi = k*hdr->SPR*2; char *label = (char*)(hdr->AS.Header+1034+k*512); len = min(16,MAX_LENGTH_LABEL); if ( (hdr->AS.Header[1025+k*512]=='E') && strlen(label)<13) { strcpy(hc->Label, "EEG "); strcat(hc->Label, label); // Flawfinder: ignore } else { strncpy(hc->Label, label, len); hc->Label[len]=0; } } /* read event file */ char* tmpfile = (char*)calloc(strlen(hdr->FileName)+4, 1); strcpy(tmpfile, hdr->FileName); char* ext = strrchr(tmpfile,'.'); if (ext != NULL) strcpy(ext+1,"LBK"); // Flawfinder: ignore else strcat(tmpfile,".LBK"); // Flawfinder: ignore FILE *fid = fopen(tmpfile,"rb"); if (fid==NULL) { if (ext != NULL) strcpy(ext+1,"lbk"); else strcat(tmpfile,".lbk"); } if (fid != NULL) { size_t N_EVENTS = 0; const int sz = 69; char buf[sz+1]; hdr->EVENT.SampleRate = hdr->SampleRate; while (!feof(fid)) { if (fread(buf,sz,1,fid) <= 0) break; // starttime char *tmp = buf; for (k=0; k<8; k++) { if ((k==2 || k==5) && tmp[k] != ':') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; else if (tmp[k]<'0' || tmp[k]>'9') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; } tmp[2] = 0; tmp[5] = 0; tmp[8] = 0; size_t tstart = atoi(tmp)*3600 + atoi(tmp+3)*60 + atoi(tmp+6); fread(buf,sz,1,fid); // endtime tmp = buf+9; for (k=0; k<8; k++) { if ((k==2 || k==5) && tmp[k] != ':') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; else if (tmp[k]<'0' || tmp[k]>'9') biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); // error ; } tmp[2] = 0; tmp[5] = 0; tmp[8] = 0; size_t tend = atoi(tmp)*3600 + atoi(tmp+3)*60 + atoi(tmp+6); if (tend18 && isspace(buf[k])) k--; buf[k+1]=0; if (hdr->EVENT.N+2 >= N_EVENTS) { // memory allocation if needed N_EVENTS = max(128, N_EVENTS*2); if (reallocEventTable(hdr, N_EVENTS) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } FreeTextEvent(hdr,hdr->EVENT.N,(char*)buf); hdr->EVENT.POS[hdr->EVENT.N] = tstart*hdr->EVENT.SampleRate; hdr->EVENT.DUR[hdr->EVENT.N] = (tend-tstart)*hdr->EVENT.SampleRate; hdr->EVENT.CHN[hdr->EVENT.N] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif hdr->EVENT.N++; } } free(tmpfile); } else if (hdr->TYPE==ePrime) { /* read file */ while (!ifeof(hdr)) { size_t bufsiz = max(2*count,1<<16); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); struct Target { size_t OnsetTime; size_t RTTime; size_t RT; size_t TrigTarget; uint8_t RESP; char *Stimulus; } Target; Target.RESP = 0xff; Target.Stimulus = NULL; Target.OnsetTime = 0; Target.RTTime = 0; Target.RT = 0; Target.TrigTarget = 0; int colSubject = -1, colSampleRate = -1, colDate = -1, colTime = -1, colOnsetTime = -1; int colResponseTime = -1, colRTTime = -1, colStimulus = -1, colTrigTarget = -1, colRESP = -1; size_t N_EVENTS = 0; struct tm t; char nextRow = 0; int col=0, row=0, len; char *f = (char*)hdr->AS.Header; while (*f != 0) { len = strcspn(f,"\t\n\r"); col++; if (f[len]==9) { nextRow = 0; } else if ( f[len]==10 || f[len]==13 || f[len]==0 ) { nextRow = 1; if (row>0) { if (hdr->EVENT.N+2 >= N_EVENTS) { // memory allocation if needed N_EVENTS = max(128, N_EVENTS*2); if (reallocEventTable(hdr, N_EVENTS) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } // add trigger event if (Target.Stimulus != NULL || Target.TrigTarget > 0) { if (Target.Stimulus) FreeTextEvent(hdr, hdr->EVENT.N, Target.Stimulus); else hdr->EVENT.TYP[hdr->EVENT.N] = Target.TrigTarget; hdr->EVENT.POS[hdr->EVENT.N] = Target.OnsetTime; hdr->EVENT.DUR[hdr->EVENT.N] = Target.RT; hdr->EVENT.CHN[hdr->EVENT.N] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif hdr->EVENT.N++; } if (Target.RESP < 0x0f) { // add response event hdr->EVENT.TYP[hdr->EVENT.N] = Target.RESP + 0x0140; // eventcodes.txt: response codes are in the range between 0x0140 to 0x014f hdr->EVENT.POS[hdr->EVENT.N] = Target.OnsetTime + Target.RT; hdr->EVENT.CHN[hdr->EVENT.N] = 0; hdr->EVENT.DUR[hdr->EVENT.N] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif hdr->EVENT.N++; }; } if (VERBOSE_LEVEL>7) fprintf(stdout,"=======%i: %i\t%s\t%i\t%i\t%i\t%i\n", hdr->EVENT.N-1, (int)Target.TrigTarget, Target.Stimulus, (int)Target.OnsetTime, (int)Target.RT, (int)Target.RTTime, Target.RESP); Target.RESP = 0xff; Target.Stimulus = NULL; Target.OnsetTime = 0; Target.RTTime = 0; Target.RT = 0; Target.TrigTarget = 0; } f[len] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"r%i\tc%i\t%s\t%i\t%i\t%i\t%i\t%i\t%i\t%i\t%i\n",(int)row,(int)col,f,colSubject, colSampleRate, colDate, colTime, colOnsetTime, colResponseTime, colStimulus, colRTTime); if (row==0) { // decode header line if (!strcmp(f,"Subject")) { colSubject = col; } else if (!strcmp(f,"Display.RefreshRate")) { colSampleRate = col; } else if (!strcmp(f,"SessionDate")) { colDate = col; } else if (!strcmp(f,"SessionTime")) { colTime = col; } else if (strstr(f,"Target.OnsetTime")) { colOnsetTime = col; } else if (strstr(f,"Target.RTTime")) { colRTTime = col; } else if (strstr(f,"Target.RT")) { colResponseTime = col; } else if (!strcmp(f,"Stimulus")) { colStimulus = col; } else if (!strcmp(f,"TrigTarget")) { colTrigTarget = col; } else if (strstr(f,"Target.RESP")) { colRESP = col; } } else { // decode line of body if (row==1) { t.tm_isdst = 0; char *eptr; if (col==colTime) { t.tm_hour = strtol(f, &eptr, 10); t.tm_min = strtol(eptr+1, &eptr, 10); t.tm_sec = strtol(eptr+1, &eptr, 10); } else if (col==colDate) { t.tm_mon = strtol(f, &eptr, 10)-1; t.tm_mday = strtol(eptr+1, &eptr, 10); t.tm_year = strtol(eptr+1, &eptr, 10)-1900; } else if (col==colSubject) { strncpy(hdr->Patient.Id, f, MAX_LENGTH_PID); } else if (col==colSampleRate) { hdr->EVENT.SampleRate = atof(f); } } if (col==colOnsetTime) { Target.OnsetTime = atol(f); } else if (col==colResponseTime) { Target.RT = atoi(f); } else if (col==colRTTime) { Target.RTTime = atol(f); } else if (col==colStimulus) { Target.Stimulus = f; } else if (col==colTrigTarget) { Target.TrigTarget = atoi(f); } else if ((col==colRESP) && strlen(f)) { Target.RESP = atoi(f); } } f += len+1; if (nextRow) { f += strspn(f,"\n\r"); row += nextRow; col = 0; } }; hdr->T0 = tm_time2gdf_time(&t); } else if (hdr->TYPE==SigViewerEventsCSV) { while (!ifeof(hdr)) { size_t bufsiz = max(2*count,1<<16); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); // position,duration,channel,type,name size_t N_EVENT=0,N=0; char *nextLine=NULL; char *line = strtok_r(hdr->AS.Header, "\n\r", &nextLine); // skip first line while (line != NULL) { line = strtok_r(NULL, "\n\r" ,&nextLine); if (line==NULL) break; char *nextToken=NULL; char *tok1 = strtok_r(line, ",", &nextToken); char *tok2 = strtok_r(NULL, ",", &nextToken); char *tok3 = strtok_r(NULL, ",", &nextToken); char *tok4 = strtok_r(NULL, ",", &nextToken); char *tok5 = strtok_r(NULL, ",", &nextToken); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): <%s> <%s> <%s> <%s> <%s>\n",__FILE__,__LINE__, tok1,tok2,tok3,tok4,tok5); if (!tok1 || !tok2 || !tok3 || !tok4) continue; if (N_EVENT <= N) { N_EVENT = reallocEventTable(hdr, max(256,N_EVENT*2)); if (N_EVENT == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } hdr->EVENT.POS[N] = (uint32_t)atol(tok1); hdr->EVENT.DUR[N] = (uint32_t)atol(tok2); int CHN = atoi(tok3); hdr->EVENT.CHN[N] = (CHN < 0) ? 0 : CHN+1; if (hdr->NS < CHN) hdr->NS = CHN+1; uint16_t TYP = (uint16_t)atoi(tok4); hdr->EVENT.TYP[N] = TYP; // read free text event description if ((0 < TYP) && (TYP < 255)) { if (hdr->EVENT.LenCodeDesc==0) { // allocate memory hdr->EVENT.LenCodeDesc = 257; hdr->EVENT.CodeDesc = (typeof(hdr->EVENT.CodeDesc)) realloc(hdr->EVENT.CodeDesc,257*sizeof(*hdr->EVENT.CodeDesc)); hdr->EVENT.CodeDesc[0] = ""; // typ==0, is always empty for (k=0; k<=256; k++) hdr->EVENT.CodeDesc[k] = NULL; } if (hdr->EVENT.CodeDesc[TYP]==NULL) hdr->EVENT.CodeDesc[TYP] = tok5; } if (TYP>0) N++; // skip events with TYP==0 } hdr->AS.auxBUF=hdr->AS.Header; hdr->AS.Header=NULL; hdr->EVENT.SampleRate = NAN; hdr->EVENT.N = N; hdr->TYPE = EVENT; hdr->NS = 0; } else if (hdr->TYPE==ET_MEG) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "FLT/ET-MEG format not supported"); } else if (hdr->TYPE==ETG4000) { /* read file */ while (!ifeof(hdr)) { size_t bufsiz = max(2*count,1<<16); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz+1); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; ifclose(hdr); if (VERBOSE_LEVEL==9) fprintf(stdout,"Size of File %s is %i\n",hdr->FileName,(int)count); /* decode header section */ char dlm[2]; dlm[0] = (char)hdr->AS.Header[20]; dlm[1] = 0; hdr->VERSION = -1; char FLAG_StimType_STIM = 0; char *t = strtok((char*)hdr->AS.Header,"\xA\xD"); char *ag=NULL, *dg=NULL, *label; double lpf=-1.0,hpf=-1.0,age=0.0; while (strncmp(t,"Probe",5)) { if (VERBOSE_LEVEL==9) fprintf(stderr,"-> %s\n",t); if (!strncmp(t,"File Version",12)) hdr->VERSION = atof(strpbrk(t,dlm)+1); else if (!strncmp(t,"Name",4)) strncpy(hdr->Patient.Id,strpbrk(t,dlm)+1,MAX_LENGTH_PID); else if (!strncmp(t,"Sex",3)) hdr->Patient.Sex = ((toupper(*strpbrk(t,dlm)+1)=='F')<<1) + (toupper(*strpbrk(t,dlm)+1)=='M'); else if (!strncmp(t,"Age",3)) { char *tmp1 = strpbrk(t,dlm)+1; size_t c = strcspn(tmp1,"0123456789"); char buf[20]; age = atof(strncpy(buf,tmp1,19)); if (tmp1[c]=='y') age *= 365.25; else if (tmp1[c]=='m') age *= 30; } else if (!strncmp(t,"Date",4)) { sscanf(strpbrk(t,dlm)+1,"%d/%d/%d %d:%d",&(tm_time.tm_year),&(tm_time.tm_mon),&(tm_time.tm_mday),&(tm_time.tm_hour),&(tm_time.tm_min)); tm_time.tm_sec = 0; tm_time.tm_year -= 1900; tm_time.tm_mon -= 1; hdr->T0 = tm_time2gdf_time(&tm_time); } else if (!strncmp(t,"HPF[Hz]",7)) hpf = atof(strpbrk(t,dlm)+1); else if (!strncmp(t,"LPF[Hz]",7)) lpf = atof(strpbrk(t,dlm)+1); else if (!strncmp(t,"Analog Gain",11)) ag = strpbrk(t,dlm); else if (!strncmp(t,"Digital Gain",12)) dg = strpbrk(t,dlm)+1; else if (!strncmp(t,"Sampling Period[s]",18)) hdr->SampleRate = 1.0/atof(strpbrk(t,dlm)+1); else if (!strncmp(t,"StimType",8)) FLAG_StimType_STIM = !strncmp(t+9,"STIM",4); t = strtok(NULL,"\xA\xD"); } if (VERBOSE_LEVEL==9) fprintf(stderr,"\nNS=%i\n-> %s\n",hdr->NS,t); hdr->Patient.Birthday = hdr->T0 - (uint64_t)ldexp(age,32); hdr->NS = 0; while (ag != NULL) { ++hdr->NS; ag = strpbrk(ag+1,dlm); } hdr->NS >>= 1; if (VERBOSE_LEVEL==9) fprintf(stderr,"\n-V=%i NS=%i\n-> %s\n",VERBOSE_LEVEL,hdr->NS,t); label = strpbrk(t,dlm) + 1; //uint16_t gdftyp = 16; // use float32 as internal buffer uint16_t gdftyp = 17; // use float64 as internal buffer double DigMax = 1.0, DigMin = -1.0; hdr->FLAG.OVERFLOWDETECTION = 0; // automated overflow and saturation detection not supported hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE* hc = hdr->CHANNEL+k; hc->OnOff = 1; hc->GDFTYP = gdftyp; hc->SPR = 1; hc->Cal = 1.0; hc->Off = 0.0; hc->Transducer[0] = '\0'; hc->LowPass = lpf; hc->HighPass = hpf; hc->PhysMax = DigMax; hc->PhysMin = DigMin; hc->DigMax = DigMax; hc->DigMin = DigMin; hc->LeadIdCode = 0; hc->PhysDimCode = 65362; //mmol l-1 mm hc->bi = k*GDFTYP_BITS[gdftyp]>>3; size_t c = strcspn(label,dlm); size_t c1 = min(c,MAX_LENGTH_LABEL); strncpy(hc->Label, label, c1); hc->Label[c1]= 0; label += c+1; if (VERBOSE_LEVEL>8) fprintf(stderr,"-> Label #%02i: len(%i) %s\n",(int)k,(int)c1,hc->Label); } hdr->SPR = 1; hdr->NRec = 0; hdr->AS.bpb = hdr->NS*GDFTYP_BITS[gdftyp]>>3; /* decode data section */ // hdr->FLAG.SWAP = 0; hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); uint32_t pos; int Mark=0,hh,mm,ss,ds,BodyMovement,RemovalMark,PreScan; size_t NEV = 16; hdr->EVENT.N = 0; hdr->EVENT.SampleRate = hdr->SampleRate; hdr->EVENT.DUR = NULL; hdr->EVENT.CHN = NULL; pos = atol(strtok(NULL,dlm)); while (pos) { hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata, (((size_t)hdr->NRec+1) * hdr->NS * GDFTYP_BITS[gdftyp])>>3); for (k=0; k < hdr->NS; k++) { if (gdftyp==16) *(float*)(hdr->AS.rawdata + (((size_t)hdr->NRec*hdr->NS+k)*(GDFTYP_BITS[gdftyp]>>3))) = (float)atof(strtok(NULL,dlm)); else if (gdftyp==17) *(double*)(hdr->AS.rawdata + (((size_t)hdr->NRec*hdr->NS+k)*(GDFTYP_BITS[gdftyp]>>3))) = atof(strtok(NULL,dlm)); } ++hdr->NRec; Mark = atoi(strtok(NULL,dlm)); if (Mark) { if (hdr->EVENT.N+1 >= NEV) { NEV<<=1; // double allocated memory hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, NEV*sizeof(*hdr->EVENT.POS) ); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, NEV*sizeof(*hdr->EVENT.TYP) ); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = (gdf_time*)realloc(hdr->EVENT.TimeStamp, NEV*sizeof(gdf_time)); #endif } hdr->EVENT.POS[hdr->EVENT.N] = pos; // 0-based indexing hdr->EVENT.TYP[hdr->EVENT.N] = Mark; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = 0; #endif if (FLAG_StimType_STIM && !(hdr->EVENT.N & 0x01)) hdr->EVENT.TYP[hdr->EVENT.N] = Mark | 0x8000; ++hdr->EVENT.N; } sscanf(strtok(NULL,dlm),"%d:%d:%d.%d",&hh,&mm,&ss,&ds); BodyMovement = atoi(strtok(NULL,dlm)); RemovalMark = atoi(strtok(NULL,dlm)); PreScan = atoi(strtok(NULL,"\xA\xD")); if (VERBOSE_LEVEL>8) fprintf(stdout,"%d: %d %02d:%02d:%02d.%02d %d %d %d\n",pos,Mark,hh,mm,ss,ds,BodyMovement,RemovalMark,PreScan); pos = atol(strtok(NULL,dlm)); }; if (FLAG_StimType_STIM && (hdr->EVENT.N & 0x01)) { /* if needed, add End-Of-Event marker */ ++hdr->EVENT.N; hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, hdr->EVENT.N*sizeof(*hdr->EVENT.POS) ); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, hdr->EVENT.N*sizeof(*hdr->EVENT.TYP) ); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = (gdf_time*)realloc(hdr->EVENT.TimeStamp, hdr->EVENT.N*sizeof(gdf_time)); hdr->EVENT.TimeStamp[hdr->EVENT.N-1] = 0; #endif hdr->EVENT.POS[hdr->EVENT.N-1] = pos; // 0-based indexing hdr->EVENT.TYP[hdr->EVENT.N-1] = Mark | 0x8000; } hdr->AS.length = hdr->NRec; } #ifdef WITH_FAMOS else if (hdr->TYPE==FAMOS) { hdr->HeadLen=count; sopen_FAMOS_read(hdr); } #endif else if (hdr->TYPE==FEF) { #ifdef WITH_FEF size_t bufsiz = 1l<<24; while (!ifeof(hdr)) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,count+bufsiz+1); count += ifread(hdr->AS.Header+count,1,bufsiz,hdr); } hdr->AS.Header[count]=0; hdr->HeadLen = count; char tmp[9]; tmp[8] = 0; memcpy(tmp, hdr->AS.Header+8, 8); hdr->VERSION = atol(tmp)/100.0; memcpy(tmp, hdr->AS.Header+24, 8); hdr->FILE.LittleEndian = !atol(tmp); ifseek(hdr,32,SEEK_SET); if (VERBOSE_LEVEL>7) fprintf(stdout,"ASN1 [401] %i\n",(int)count); sopen_fef_read(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"ASN1 [491]\n"); #else biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "VITAL/FEF Format not supported"); return(hdr); #endif } else if (hdr->TYPE==FIFF) { hdr->HeadLen = count; sopen_fiff_read(hdr); } else if (hdr->TYPE==GTF) { /* read file */ while (!ifeof(hdr)) { size_t bufsiz = max(2*count,1<<16); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, bufsiz); count += ifread(hdr->AS.Header+count, 1, bufsiz-count, hdr); } ifclose(hdr); hdr->HeadLen = 512+15306+8146; count -= hdr->HeadLen; char tmp[8]; strncpy(tmp,hdr->AS.Header+34,2); tmp[2]=0; hdr->NS = atoi(tmp); strncpy(tmp,hdr->AS.Header+36,3); tmp[3]=0; hdr->SampleRate = atoi(tmp); hdr->SPR = 10 * hdr->SampleRate; if (hdr->NS <= 0 || hdr->SampleRate<=0.0) biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Invalid GTF header"); hdr->AS.bpb = hdr->SampleRate*240+2048; hdr->NRec = floor(count / hdr->AS.bpb); //hdr->AS.bpb = hdr->NS*GDFTYP_BITS[gdftyp]>>3; const float tau[] = {0.01, 0.03, 0.1, 0.3, 1}; // ignored for now const float Lowpass[] = {30, 70}; // ignored for now const float Sens[] = {.5, .7, 1, 1.4, 2, 5, 7, 10, 14, 20, 50, 70, 100, 140, 200}; // FIXME // x = reshape(s4(13:6:1932,:),32,HDR.NRec*HDR.Dur); // Cal = Sens(x(1:HDR.NS,:)+1)'/4; uint16_t gdftyp = 1; // int8 double DigMax = 127, DigMin = -127; hdr->FLAG.OVERFLOWDETECTION = 1; // automated overflow and saturation detection supported hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (int k=0; k < hdr->NS; k++) { CHANNEL_TYPE* hc = hdr->CHANNEL+k; hc->OnOff = 1; hc->GDFTYP = gdftyp; hc->SPR = hdr->SPR; hc->Cal = 1.0; hc->Off = 0.0; hc->Transducer[0] = '\0'; hc->LowPass = NAN; // TODO: get switch info about Lowpass filter hc->HighPass = NAN; // TODO: get switch info about Lowpass filter hc->PhysMax = DigMax; hc->PhysMin = DigMin; hc->DigMax = DigMax; hc->DigMin = DigMin; hc->LeadIdCode = 0; hc->PhysDimCode = 4275; // uV hc->bi = k*GDFTYP_BITS[gdftyp]>>3; assert(MAX_LENGTH_LABEL > 32); char* tmp = hdr->AS.Header+512+15306+1070+k*32; // Trim trailing space int c; for (c=31; isspace(tmp[c]) && c>0; c--); memcpy(hc->Label, tmp, c); hc->Label[c] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) : Label #%02d: len(%d) <%s>\n",__FILE__,__LINE__, k, c, hc->Label); } hdr->AS.rawdata = hdr->AS.Header+512+15306+8146; // hdr->AS.rawdata = hdr->AS.Header+count+9248; for (size_t m=0; m < hdr->NRec; m++) { size_t t2pos = 9248 + m * hdr->AS.bpb; for (size_t l=0; l < hdr->SampleRate*240; l++) { ; } } } else if (hdr->TYPE==HDF) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...)\n", __FILE__,__LINE__,__func__); if (sopen_hdf5(hdr) != 0) return(hdr); } else if (hdr->TYPE==HEKA) { // HEKA PatchMaster file format hdr->HeadLen = count; FILE *itx = fopen((char*)hdr->aECG, "w"); hdr->aECG = NULL; // reset auxillary pointer sopen_heka(hdr, itx); if (itx) fclose(itx); } else if (hdr->TYPE==IBW) { struct stat FileBuf; stat(hdr->FileName, &FileBuf); hdr->FILE.size = FileBuf.st_size; sopen_ibw_read(hdr); } else if (hdr->TYPE==ITX) { sopen_itx_read(hdr); } else if (hdr->TYPE==ISHNE) { char flagANN = !strncmp((char*)hdr->AS.Header,"ANN",3); fprintf(stderr,"Warning SOPEN(ISHNE): support for ISHNE format is experimental\n"); // unknown, generic, X,Y,Z, I-VF, V1-V6, ES, AS, AI uint16_t Table1[] = {0,0,16,17,18,1,2,87,88,89,90,3,4,5,6,7,8,131,132,133}; size_t len; struct tm t; hdr->HeadLen = lei32p(hdr->AS.Header+22); if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } hdr->HeadLen = count; if (VERBOSE_LEVEL>6) { fprintf(stdout,"SOPEN(ISNHE): @%p %i\n",hdr->AS.Header,hdr->HeadLen); fprintf(stdout,"SOPEN(ISNHE): @%p %x %x %x %x %x %x\n",hdr->AS.Header,hdr->AS.Header[132],hdr->AS.Header[133],hdr->AS.Header[134],hdr->AS.Header[135],hdr->AS.Header[136],hdr->AS.Header[137]); for (k=0;k<522;k++) { fprintf(stdout,"%02x ",hdr->AS.Header[k]); if (k%32==0) fputc('\n',stdout); } } //int offsetVarHdr = lei32p(hdr->AS.Header+18); hdr->VERSION = (float)lei16p(hdr->AS.Header+26); if (!hdr->FLAG.ANONYMOUS) { len = min(40, MAX_LENGTH_NAME); char *s; s = (char*)(hdr->AS.Header+68); // lastname size_t slen = strlen(s); int len1 = min(40, slen); memcpy(hdr->Patient.Name, s, len1); hdr->Patient.Name[len1] = 0x1f; // unit separator ascii(31) s = (char*)(hdr->AS.Header+28); // firstname int len2 = min(strlen(s), MAX_LENGTH_NAME-len-1); strncpy(hdr->Patient.Name+len1+1, s, len2); hdr->Patient.Name[len1+len2+1] = 0; } len = min(20, MAX_LENGTH_PID); strncpy(hdr->Patient.Id, (char*)(hdr->AS.Header+108), len); hdr->Patient.Id[len] = 0; hdr->Patient.Sex = lei16p(hdr->AS.Header+128); // Race = lei16p(hdr->AS.Header+128); t.tm_mday = lei16p(hdr->AS.Header + 132); t.tm_mon = lei16p(hdr->AS.Header + 134) - 1; t.tm_year = lei16p(hdr->AS.Header + 136) - 1900; t.tm_hour = 12; t.tm_min = 0; t.tm_sec = 0; t.tm_isdst = 0; if (VERBOSE_LEVEL>6) { fprintf(stdout,"SOPEN(ISNHE): Birthday: %04i-%02i-%02i %02i:%02i:%02i\n",t.tm_year,t.tm_mon,t.tm_mday,t.tm_hour,t.tm_min,t.tm_sec); fprintf(stdout,"SOPEN(ISNHE): @%p %x %x %x %x %x %x\n",hdr->AS.Header,hdr->AS.Header[132],hdr->AS.Header[133],hdr->AS.Header[134],hdr->AS.Header[135],hdr->AS.Header[136],hdr->AS.Header[137]); } if (t.tm_mday>0 && t.tm_mon>=0 && t.tm_year>=0) hdr->Patient.Birthday = tm_time2gdf_time(&t); t.tm_mday = leu16p(hdr->AS.Header + 138); t.tm_mon = leu16p(hdr->AS.Header + 140)-1; t.tm_year = leu16p(hdr->AS.Header + 142)-1900; t.tm_hour = leu16p(hdr->AS.Header + 150); t.tm_min = leu16p(hdr->AS.Header + 152); t.tm_sec = leu16p(hdr->AS.Header + 154); hdr->T0 = tm_time2gdf_time(&t); hdr->NS = lei16p(hdr->AS.Header + 156); hdr->AS.bpb= hdr->NS * 2; hdr->SPR = 1; hdr->SampleRate = lei16p(hdr->AS.Header + 272); hdr->Patient.Impairment.Heart = lei16p(hdr->AS.Header+230) ? 3 : 0; // Pacemaker { struct stat FileBuf; stat(hdr->FileName,&FileBuf); hdr->FILE.size = FileBuf.st_size; } if (flagANN) { hdr->NRec=0; hdr->EVENT.N = (hdr->FILE.size - hdr->HeadLen)/4; hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP, hdr->EVENT.N * sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS, hdr->EVENT.N * sizeof(*hdr->EVENT.POS)); /* define user specified events according to ECG Annotation format of http://thew-project.org/THEWFileFormat.htm */ hdr->EVENT.CodeDesc = (typeof(hdr->EVENT.CodeDesc)) realloc(hdr->EVENT.CodeDesc,10*sizeof(*hdr->EVENT.CodeDesc)); hdr->EVENT.CodeDesc[0]=""; hdr->EVENT.CodeDesc[1]="Normal beat"; hdr->EVENT.CodeDesc[2]="Premature ventricular contraction"; hdr->EVENT.CodeDesc[3]="Supraventricular premature or ectopic beat"; hdr->EVENT.CodeDesc[4]="Calibration Pulse"; hdr->EVENT.CodeDesc[5]="Bundle branch block beat"; hdr->EVENT.CodeDesc[6]="Pace"; hdr->EVENT.CodeDesc[7]="Artfact"; hdr->EVENT.CodeDesc[8]="Unknown"; hdr->EVENT.CodeDesc[9]="NULL"; hdr->EVENT.LenCodeDesc = 9; uint8_t evt[4]; ifseek(hdr, lei32p(hdr->AS.Header+22), SEEK_SET); size_t N = 0, pos=0; while (!ifeof(hdr)) { if (!ifread(evt, 1, 4, hdr)) break; uint16_t typ = 8; switch ((char)(evt[0])) { case 'N': typ = 1; break; case 'V': typ = 2; break; case 'S': typ = 3; break; case 'C': typ = 4; break; case 'B': typ = 5; break; case 'P': typ = 6; break; case 'X': typ = 7; break; case '!': typ = 0x7ffe; break; case 'U': typ = 8; break; default: continue; } pos += leu16p(evt+2); hdr->EVENT.POS[N] = pos; hdr->EVENT.TYP[N] = typ; N++; } hdr->EVENT.N = N; } else { hdr->EVENT.N = 0; hdr->NRec = min(leu32p(hdr->AS.Header+14), (hdr->FILE.size - hdr->HeadLen)/hdr->AS.bpb ); } hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (k=0; k < hdr->NS; k++) { CHANNEL_TYPE* hc = hdr->CHANNEL+k; hc->OnOff = 1; if (hdr->VERSION == 1) { hc->GDFTYP = 3; //int16 - 2th complement hc->DigMax = (double)(int16_t)(0x7fff); hc->DigMin = (double)(int16_t)(0x8000); } else { hc->GDFTYP = 4; //uint16 hc->DigMax = (double)(uint16_t)(0xffff); hc->DigMin = (double)(uint16_t)(0x0000); } hc->SPR = 1; hc->Cal = lei16p(hdr->AS.Header + 206 + 2*k); hc->Off = 0.0; hc->Transducer[0] = '\0'; hc->LowPass = NAN; hc->HighPass = NAN; hc->PhysMax = hc->Cal * hc->DigMax; hc->PhysMin = hc->Cal * hc->DigMin; hc->LeadIdCode = Table1[lei16p(hdr->AS.Header + 158 + 2*k)]; hc->PhysDimCode = 4276; // nV hc->bi = k*2; strcpy(hc->Label, LEAD_ID_TABLE[hc->LeadIdCode]); } ifseek(hdr, lei32p(hdr->AS.Header+22), SEEK_SET); hdr->FILE.POS = 0; } else if (hdr->TYPE==Matlab) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...)\n", __FILE__,__LINE__,__func__); if (sopen_matlab(hdr) != 0) return(hdr); } else if (hdr->TYPE==MFER) { /* // ISO/TS 11073-92001:2007(E), Table 5, p.9 physicalunits({'V','mmHg','Pa','cm H2O', 'mmHg s-1','dyn','N','%','°C','min-1','s-1','Ohm','A','rpm','W','dB','kg','J','dyne s m-2 cm-5','l','l s-1','l min-1','cd'}) */ const uint16_t MFER_PhysDimCodeTable[30] = { 4256, 3872, 3840, 3904,65330, // Volt, mmHg, Pa, mmH2O, mmHg/s 3808, 3776, 544, 6048, 2528, // dyne, N, %, °C, 1/min 4264, 4288, 4160,65376, 4032, // 1/s, Ohm, A, rpm, W 6448, 1731, 3968, 6016, 1600, // dB, kg, J, dyne s m-2 cm-5, l 3040, 3072, 4480, 0, 0, // l/s, l/min, cd 0, 0, 0, 0, 0, // }; hdr->FLAG.OVERFLOWDETECTION = 0; // MFER does not support automated overflow and saturation detection uint8_t buf[128]; void* ptrbuf = buf; uint8_t gdftyp = 3; // default: int16 uint8_t UnitCode=0; double Cal = 1.0, Off = 0.0; char SWAP = ( __BYTE_ORDER == __LITTLE_ENDIAN); // default of MFER is BigEndian hdr->FILE.LittleEndian = 0; hdr->SampleRate = 1000; // default sampling rate is 1000 Hz hdr->NS = 1; // default number of channels is 1 /* TAG */ uint8_t tag = hdr->AS.Header[0]; ifseek(hdr,1,SEEK_SET); int curPos = 1; size_t N_EVENT=0; // number of events, memory is allocated for in the event table. while (!ifeof(hdr)) { uint32_t len, val32=0; int32_t chan=-1; uint8_t tmplen; if (tag==255) break; else if (tag==63) { /* CONTEXT */ curPos += ifread(buf,1,1,hdr); chan = buf[0] & 0x7f; while (buf[0] & 0x80) { curPos += ifread(buf,1,1,hdr); chan = (chan<<7) + (buf[0] & 0x7f); } } /* LENGTH */ curPos += ifread(&tmplen,1,1,hdr); char FlagInfiniteLength = 0; if ((tag==63) && (tmplen==0x80)) { FlagInfiniteLength = -1; //Infinite Length len = 0; } else if (tmplen & 0x80) { tmplen &= 0x7f; curPos += ifread(&buf,1,tmplen,hdr); len = 0; k = 0; while (k7) fprintf(stdout,"MFER: tag=%3i chan=%2i len=%i %3i curPos=%i %li\n",tag,chan,tmplen,len,curPos,iftell(hdr)); /* VALUE */ if (tag==0) { if (len!=1) fprintf(stderr,"Warning MFER tag0 incorrect length %i!=1\n",len); curPos += ifread(buf,1,len,hdr); } else if (tag==1) { // Endianity if (len!=1) fprintf(stderr,"Warning MFER tag1 incorrect length %i!=1\n",len); ifseek(hdr,len-1,SEEK_CUR); curPos += ifread(buf,1,1,hdr); hdr->FILE.LittleEndian = buf[0]; #if (__BYTE_ORDER == __BIG_ENDIAN) SWAP = hdr->FILE.LittleEndian; #elif (__BYTE_ORDER == __LITTLE_ENDIAN) SWAP = !hdr->FILE.LittleEndian; #endif } else if (tag==2) { // Version uint8_t v[3]; if (len!=3) fprintf(stderr,"Warning MFER tag2 incorrect length %i!=3\n",len); curPos += ifread(&v,1,3,hdr); hdr->VERSION = v[0] + (v[1]<10 ? v[1]/10.0 : (v[1]<100 ? v[1]/100.0 : v[1]/1000.0)); } else if (tag==3) { // character code char v[17]; if (len>16) fprintf(stderr,"Warning MFER tag2 incorrect length %i>16\n",len); curPos += ifread(&v,1,len,hdr); v[len] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: character code <%s>\n",v); } else if (tag==4) { // SPR if (len>4) fprintf(stderr,"Warning MFER tag4 incorrect length %i>4\n",len); curPos += ifread(buf,1,len,hdr); hdr->SPR = *(int64_t*) mfer_swap8b(buf, len, SWAP); if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: TLV %i %i %i \n",tag,len,(int)hdr->SPR); } else if (tag==5) //0x05: number of channels { uint16_t oldNS=hdr->NS; if (len>4) fprintf(stderr,"Warning MFER tag5 incorrect length %i>4\n",len); curPos += ifread(buf,1,len,hdr); hdr->NS = *(int64_t*) mfer_swap8b(buf, len, SWAP); if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: TLV %i %i %i \n",tag,len,(int)hdr->NS); hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); for (k=oldNS; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->SPR = 0; hc->PhysDimCode = 4275; // uV : default value in Table 5, ISO/FDIS 22077-1(E)ISO/WD 22077-1 hc->Cal = 1.0; hc->Off = 0.0; hc->OnOff = 1; hc->LeadIdCode = 0; hc->GDFTYP = 3; hc->Transducer[0] = 0; } } else if (tag==6) // 0x06 "number of sequences" { // NRec if (len>4) fprintf(stderr,"Warning MFER tag6 incorrect length %i>4\n",len); curPos += ifread(buf,1,len,hdr); hdr->NRec = *(int64_t*) mfer_swap8b(buf, len, SWAP); if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: TLV %i %i %i \n",tag,len,(int)hdr->NRec); } else if (tag==8) { if (len>2) fprintf(stderr,"Warning MFER tag8 incorrect length %i>2\n",len); curPos += ifread(buf,1,len,hdr); /* // NOT USED // Type of Waveform union { uint8_t TypeOfWaveForm8[2]; uint16_t TypeOfWaveForm; } t; if (len==1) t.TypeOfWaveForm = buf[0]; else { t.TypeOfWaveForm8[0] = buf[0]; t.TypeOfWaveForm8[1] = buf[1]; if (SWAP) t.TypeOfWaveForm = bswap_16(t.TypeOfWaveForm); } */ } else if (tag==10) { // GDFTYP if (len!=1) fprintf(stderr,"warning MFER tag10 incorrect length %i!=1\n",len); curPos += ifread(&gdftyp,1,1,hdr); if (gdftyp==0) gdftyp=3; // int16 else if (gdftyp==1) gdftyp=4; // uint16 else if (gdftyp==2) gdftyp=5; // int32 else if (gdftyp==3) gdftyp=2; // uint8 else if (gdftyp==4) gdftyp=4; // bit16 else if (gdftyp==5) gdftyp=1; // int8 else if (gdftyp==6) gdftyp=6; // uint32 else if (gdftyp==7) gdftyp=16; // float32 else if (gdftyp==8) gdftyp=17; // float64 else if (gdftyp==9) //gdftyp=2; // 8 bit AHA compression fprintf(stdout,"Warning: MFER compressed format not supported\n"); else gdftyp=3; } else if (tag==11) //0x0B { // Fs if (len>6) fprintf(stderr,"Warning MFER tag11 incorrect length %i>6\n",len); double fval; curPos += ifread(buf,1,len,hdr); fval = *(int64_t*) mfer_swap8b(buf+2, len-2, SWAP); hdr->SampleRate = fval*pow(10.0, (int8_t)buf[1]); if (buf[0]==1) // s hdr->SampleRate = 1.0/hdr->SampleRate; if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: TLV %i %i %i %i %g \n",tag,len,buf[0], buf[1], hdr->SampleRate); } else if (tag==12) //0x0C { // sampling resolution if (len>6) fprintf(stderr,"Warning MFER tag12 incorrect length %i>6\n",len); val32 = 0; int8_t v8; curPos += ifread(&UnitCode,1,1,hdr); curPos += ifread(&v8,1,1,hdr); curPos += ifread(buf,1,len-2,hdr); Cal = *(int64_t*) mfer_swap8b(buf, len-2, SWAP); Cal *= pow(10.0,v8); if (!MFER_PhysDimCodeTable[UnitCode]) fprintf(stderr,"Warning MFER: unsupported physical unit (code=%i)\n", UnitCode); } else if (tag==13) { if (len>8) fprintf(stderr,"Warning MFER tag13 incorrect length %i>8\n",len); curPos += ifread(&buf,1,len,hdr); if (gdftyp == 1) Off = ( int8_t)buf[0]; else if (gdftyp == 2) Off = (uint8_t)buf[0]; else if (SWAP) { if (gdftyp == 3) Off = ( int16_t)bswap_16(*( int16_t*)ptrbuf); else if (gdftyp == 4) Off = (uint16_t)bswap_16(*(uint16_t*)ptrbuf); else if (gdftyp == 5) Off = ( int32_t)bswap_32(*( int32_t*)ptrbuf); else if (gdftyp == 6) Off = (uint32_t)bswap_32(*(uint32_t*)ptrbuf); else if (gdftyp == 7) Off = ( int64_t)bswap_64(*( int64_t*)ptrbuf); else if (gdftyp == 8) Off = (uint64_t)bswap_64(*(uint64_t*)ptrbuf); else if (gdftyp ==16) { *(uint32_t*)ptrbuf = bswap_32(*(uint32_t*)ptrbuf); Off = *(float*)ptrbuf; } else if (gdftyp ==17) { *(uint64_t*)ptrbuf = bswap_64(*(uint64_t*)ptrbuf); Off = *(double*)ptrbuf; } } else { if (gdftyp == 3) Off = *( int16_t*)ptrbuf; else if (gdftyp == 4) Off = *(uint16_t*)ptrbuf; else if (gdftyp == 5) Off = *( int32_t*)ptrbuf; else if (gdftyp == 6) Off = *(uint32_t*)ptrbuf; else if (gdftyp == 7) Off = *( int64_t*)ptrbuf; else if (gdftyp == 8) Off = *(uint64_t*)ptrbuf; else if (gdftyp ==16) Off = *(float*)ptrbuf; else if (gdftyp ==17) Off = *(double*)ptrbuf; } } else if (tag==22) { // MWF_NTE (16h): Comment char buf[257]; ifread(buf,1,min(256,len),hdr); buf[min(256,len)]=0; if (VERBOSE_LEVEL > 7) fprintf(stdout,"MFER comment (tag=22): %s\n",buf); size_t POS=0, CHN=0; const char *Desc = NULL; char *ptrP1 = strstr(buf,""); if (ptrP2) { *ptrP2=0; ptrP2++; POS = atol(ptrP1); Desc = ptrP2; } } char *ptrP3 = strstr(buf,""); if (ptrP2) { *ptrP2=0; ptrP2++; CHN = strtol(ptrP3, &ptrP3, 10); } } if (POS>0 && Desc) { size_t N = hdr->EVENT.N; if (N_EVENT <= N) { N_EVENT = reallocEventTable(hdr, N_EVENT); if (N_EVENT == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } hdr->EVENT.POS[N] = POS; hdr->EVENT.CHN[N] = CHN; FreeTextEvent(hdr, N, Desc); // sets hdr->EVENT.TYP[n] hdr->EVENT.N = N+1; } curPos += len; } else if (tag==23) { // manufacturer information: "Manufacturer^model^version number^serial number" ifread(hdr->ID.Manufacturer._field,1,min(MAX_LENGTH_MANUF,len),hdr); if (len>MAX_LENGTH_MANUF) { fprintf(stderr,"Warning MFER tag23 incorrect length %i>128\n",len); ifseek(hdr,len-MAX_LENGTH_MANUF,SEEK_CUR); } curPos += len; for (k=0; isprint(hdr->ID.Manufacturer._field[k]) && (kID.Manufacturer._field[k] = 0; hdr->ID.Manufacturer.Name = strtok(hdr->ID.Manufacturer._field,"^"); hdr->ID.Manufacturer.Model = strtok(NULL,"^"); hdr->ID.Manufacturer.Version = strtok(NULL,"^"); hdr->ID.Manufacturer.SerialNumber = strtok(NULL,"^"); if (hdr->ID.Manufacturer.Name == NULL) hdr->ID.Manufacturer.Name="\0"; if (hdr->ID.Manufacturer.Model == NULL) hdr->ID.Manufacturer.Model="\0"; if (hdr->ID.Manufacturer.Version == NULL) hdr->ID.Manufacturer.Version="\0"; if (hdr->ID.Manufacturer.SerialNumber == NULL) hdr->ID.Manufacturer.SerialNumber="\0"; } else if (tag==30) //0x1e: waveform data { // data block hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata,len); hdr->HeadLen = curPos; curPos += ifread(hdr->AS.rawdata,1,len,hdr); hdr->AS.first = 0; hdr->AS.length= hdr->NRec; } else if (tag==63) { uint8_t tag2=255, len2=255; count = 0; while ((count4) fprintf(stderr,"Warning MFER tag63-4 incorrect length %i>4\n",len2); int64_t SPR = *(int64_t*) mfer_swap8b(buf, len2, SWAP); hdr->SPR = (chan==0) ? SPR : lcm(SPR, hdr->SPR); hdr->CHANNEL[chan].SPR = SPR; if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: TLV %i %i %i %i %i %i %i %i %i\n",tag,len, chan, tag2,len2, buf[0], buf[1], (int)hdr->SPR, (int)hdr->CHANNEL[chan].SPR); } else if (tag2==9) { //leadname if (len2==2) hdr->CHANNEL[chan].LeadIdCode = 0; else if (len2==1) hdr->CHANNEL[chan].LeadIdCode = buf[0]; else if (len2<=32) strncpy(hdr->CHANNEL[chan].Label,(char*)buf,len2); else fprintf(stderr,"Warning MFER tag63-9 incorrect length %i>32\n",len2); } else if (tag2==10) { // GDFTYP if (len2!=1) fprintf(stderr,"warning MFER tag63-10 incorrect length %i!=1\n",len2); if (buf[0]==0) gdftyp=3; // int16 else if (buf[0]==1) gdftyp=4; // uint16 else if (buf[0]==2) gdftyp=5; // int32 else if (buf[0]==3) gdftyp=2; // uint8 else if (buf[0]==4) gdftyp=4; // bit16 else if (buf[0]==5) gdftyp=1; // int8 else if (buf[0]==6) gdftyp=6; // uint32 else if (buf[0]==7) gdftyp=16; // float32 else if (buf[0]==8) gdftyp=17; // float64 else if (buf[0]==9) //gdftyp=2; // 8 bit AHA compression fprintf(stdout,"Warning: MFER compressed format not supported\n"); else gdftyp=3; hdr->CHANNEL[chan].GDFTYP = gdftyp; if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: TLV %i %i %i %i %i %i %i\n",tag, len, chan, tag2, len2, buf[0], gdftyp); } else if (tag2==11) { // sampling rate if (len2>6) fprintf(stderr,"Warning MFER tag63-11 incorrect length %i>6\n",len2); double fval; fval = *(int64_t*) mfer_swap8b(buf+2, len2-2, SWAP); fval *= pow(10.0, (int8_t)(buf[1])); if (buf[0]==1) // s fval = 1.0/fval; hdr->CHANNEL[chan].SPR = lround(hdr->SPR * fval / hdr->SampleRate); if (VERBOSE_LEVEL>7) fprintf(stdout,"MFER: TLV %i %i %i %i %i %i %i %g %i %g\n",tag,len, chan, tag2,len2, buf[0], buf[1], fval, (int)hdr->SPR, hdr->SampleRate); } else if (tag2==12) { // MWF_SEN (0Ch): Sampling resolution CHANNEL_TYPE *hc = hdr->CHANNEL+chan; hc->PhysDimCode = 4275; // uV : default value in Table 5, ISO/FDIS 22077-1(E)ISO/WD 22077-1 hc->Cal = *(int64_t*) mfer_swap8b(buf+2, len2-2, SWAP); hc->Cal *= pow(10.0, (int8_t)(buf[1])); hc->PhysDimCode = MFER_PhysDimCodeTable[buf[0]]; } else if (tag2==13) { // Offset gdftyp = hdr->CHANNEL[chan].GDFTYP; if (gdftyp == 1) Off = ( int8_t)buf[0]; else if (gdftyp == 2) Off = (uint8_t)buf[0]; else if (SWAP) { if (gdftyp == 3) Off = ( int16_t)bswap_16(*( int16_t*)buf); else if (gdftyp == 4) Off = (uint16_t)bswap_16(*(uint16_t*)buf); else if (gdftyp == 5) Off = ( int32_t)bswap_32(*( int32_t*)buf); else if (gdftyp == 6) Off = (uint32_t)bswap_32(*(uint32_t*)buf); else if (gdftyp == 7) Off = ( int64_t)bswap_64(*( int64_t*)buf); else if (gdftyp == 8) Off = (uint64_t)bswap_64(*(uint64_t*)buf); else if (gdftyp ==16) { *(uint32_t*)ptrbuf = bswap_32(*(uint32_t*)buf); Off = *(float*)ptrbuf; } else if (gdftyp ==17) { uint64_t u64 = bswap_64(*(uint64_t*)ptrbuf); Off = *(double*)&u64; } } else { if (gdftyp == 3) Off = *( int16_t*)buf; else if (gdftyp == 4) Off = *(uint16_t*)buf; else if (gdftyp == 5) Off = *( int32_t*)buf; else if (gdftyp == 6) Off = *(uint32_t*)buf; else if (gdftyp == 7) Off = *( int64_t*)buf; else if (gdftyp == 8) Off = *(uint64_t*)buf; else if (gdftyp ==16) Off = *(float*)buf; else if (gdftyp ==17) Off = *(double*)buf; } hdr->CHANNEL[chan].Off = Off; /* TODO convert to Phys/Dig/Min/Max */ } else if (tag2==18) { // null value // FIXME: needed for overflow detection if (len2>6) fprintf(stderr,"Warning MFER tag63-12 incorrect length %i>6\n", len2); if (!MFER_PhysDimCodeTable[UnitCode]) fprintf(stderr,"Warning MFER: unsupported physical unit (code=%i)\n", UnitCode); hdr->CHANNEL[chan].PhysDimCode = MFER_PhysDimCodeTable[UnitCode]; double cal = *(int64_t*) mfer_swap8b(buf+2, len2-2, SWAP); hdr->CHANNEL[chan].Cal = cal * pow(10.0,(int8_t)buf[1]); } else { if (VERBOSE_LEVEL==9) fprintf(stdout,"tag=63-%i (len=%i) not supported\n",tag2,len2); } } } else if (tag==64) //0x40 { // preamble char tmp[256]; curPos += ifread(tmp,1,len,hdr); if (VERBOSE_LEVEL>7) { fprintf(stdout,"Preamble: pos=%i|",curPos); for (k=0; k2) { size_t N = hdr->EVENT.N; #ifdef CURRENTLY_NOT_AVAILABLE // FIXME: biosig_set_number_of_events is currently part of biosig2 interface if (N_EVENT <= N) { N_EVENT = biosig_set_number_of_events(hdr, max(16, N*2)); } if (VERBOSE_LEVEL > 7) fprintf(stdout,"MFER-event: N=%i\n",hdr->EVENT.N); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[N] = 0; #endif hdr->EVENT.CHN[N] = 0; hdr->EVENT.DUR[N] = 0; if (SWAP) { hdr->EVENT.TYP[N] = bswap_16(*(uint16_t*)ptrbuf); hdr->EVENT.POS[N] = bswap_32(*(uint32_t*)(buf+2)); // 0-based indexing if (len>6) hdr->EVENT.DUR[N] = bswap_32(*(uint32_t*)(buf+6)); } else { hdr->EVENT.TYP[N] = *(uint16_t*)ptrbuf; hdr->EVENT.POS[N] = *(uint32_t*)(buf+2); // 0-based indexing if (len>6) hdr->EVENT.DUR[N] = *(uint32_t*)(buf+6); } hdr->EVENT.N = N+1; #endif //CURRENTLY_NOT_AVAILABLE } } else if (tag==66) //0x42: NIPB, SpO2(value) { } else if (tag==67) //0x43: Sample skew { int skew=0; curPos += ifread(&skew, 1, len,hdr); if (VERBOSE_LEVEL>2) fprintf(stdout,"MFER: sample skew %i ns\n",skew); } else if (tag==70) //0x46: digital signature { if (VERBOSE_LEVEL>2) fprintf(stdout,"MFER: digital signature \n"); } else if (tag==103) //0x67 Group definition { if (VERBOSE_LEVEL>2) fprintf(stdout,"MFER: Group definition\n"); } else if (tag==129) //0x81 { if (!hdr->FLAG.ANONYMOUS) curPos += ifread(hdr->Patient.Name,1,len,hdr); else { ifseek(hdr,len,SEEK_CUR); curPos += len; } } else if (tag==130) //0x82 { // Patient Id if (len>64) fprintf(stderr,"Warning MFER tag131 incorrect length %i>64\n",len); if (len>MAX_LENGTH_PID) { ifread(hdr->Patient.Id,1,MAX_LENGTH_PID,hdr); ifseek(hdr,MAX_LENGTH_PID-len,SEEK_CUR); curPos += len; } else curPos += ifread(hdr->Patient.Id,1,len,hdr); } else if (tag==131) //0x83 { // Patient Age if (len!=7) fprintf(stderr,"Warning MFER tag131 incorrect length %i!=7\n",len); curPos += ifread(buf,1,len,hdr); uint16_t t16; memcpy(&t16, buf+3, 2); if (SWAP) t16 = bswap_16(t16); tm_time.tm_year = t16 - 1900; tm_time.tm_mon = buf[5]-1; tm_time.tm_mday = buf[6]; tm_time.tm_hour = 12; tm_time.tm_min = 0; tm_time.tm_sec = 0; hdr->Patient.Birthday = tm_time2gdf_time(&tm_time); //hdr->Patient.Age = buf[0] + cswap_u16(*(uint16_t*)(buf+1))/365.25; } else if (tag==132) //0x84 { // Patient Sex if (len!=1) fprintf(stderr,"Warning MFER tag132 incorrect length %i!=1\n",len); curPos += ifread(&hdr->Patient.Sex,1,len,hdr); } else if (tag==133) //0x85 { curPos += ifread(buf,1,len,hdr); uint16_t t16, u16; memcpy(&t16, buf+3, 2); if (SWAP) t16 = bswap_16(t16); tm_time.tm_year = t16 - 1900; tm_time.tm_mon = buf[2] - 1; tm_time.tm_mday = buf[3]; tm_time.tm_hour = buf[4]; tm_time.tm_min = buf[5]; tm_time.tm_sec = buf[6]; hdr->T0 = tm_time2gdf_time(&tm_time); // add milli- and micro-seconds memcpy(&t16, buf+7, 2); memcpy(&u16, buf+9, 2); if (SWAP) hdr->T0 += (uint64_t) ( bswap_16(t16) * 1e+3 + bswap_16(u16) * ldexp(1.0,32) / (24*3600e6) ); else hdr->T0 += (uint64_t) ( t16 * 1e+3 + u16 * ldexp(1.0,32) / (24*3600e6) ); } else if (tag==135) //0x67 Object identifier { if (VERBOSE_LEVEL>2) fprintf(stdout,"MFER: object identifier\n"); } else { curPos += len; ifseek(hdr,len,SEEK_CUR); if (VERBOSE_LEVEL>7) fprintf(stdout,"tag=%i (len=%i) not supported\n",tag,len); } if (curPos != iftell(hdr)) fprintf(stdout,"positions differ %i %li \n",curPos,iftell(hdr)); /* TAG */ int sz=ifread(&tag,1,1,hdr); curPos += sz; } hdr->FLAG.OVERFLOWDETECTION = 0; // overflow detection OFF - not supported hdr->AS.bpb = 0; for (k=0; kNS; k++) { if (VERBOSE_LEVEL>8) fprintf(stdout,"sopen(MFER): #%i\n",(int)k); CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Transducer[0] = 0; if (!hc->PhysDimCode) hc->PhysDimCode = MFER_PhysDimCodeTable[UnitCode]; if (hc->Cal==1.0) hc->Cal = Cal; hc->Off = Off * hc->Cal; if (!hc->SPR) hc->SPR = hdr->SPR; if (hc->GDFTYP<16) if (hc->GDFTYP & 0x01) { hc->DigMax = ldexp( 1.0,GDFTYP_BITS[gdftyp]-1) - 1.0; hc->DigMin = ldexp(-1.0,GDFTYP_BITS[gdftyp]-1); } else { hc->DigMax = ldexp( 1.0,GDFTYP_BITS[gdftyp]); hc->DigMin = 0.0; } else { hc->DigMax = INFINITY; hc->DigMin = -INFINITY; } hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->OnOff = 1; hc->bi = hdr->AS.bpb; hdr->AS.bpb += hdr->SPR*(GDFTYP_BITS[gdftyp]>>3); } if (VERBOSE_LEVEL>7) fprintf(stdout,"[MFER] -V=%i NE=%i\n",VERBOSE_LEVEL,hdr->EVENT.N); } else if (hdr->TYPE==MIT) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %i \n",__FILE__,__LINE__,__func__,VERBOSE_LEVEL); size_t bufsiz = 1024; while (!ifeof(hdr)) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,count+bufsiz); count += ifread(hdr->AS.Header+count, 1, bufsiz, hdr); } ifclose(hdr); /* MIT: decode header information */ if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %s \n",__FILE__,__LINE__,__func__, (char*)hdr->AS.Header); hdr->SampleRate = 250.0; hdr->NRec = 0; hdr->SPR = 1; size_t NumberOfSegments = 1; char *ptr = (char*)hdr->AS.Header; char *line; do line = strtok((char*)hdr->AS.Header,"\x0d\x0a"); while ((line != NULL) && (line[0]=='#')); ptr = strpbrk(line,"\x09\x0a\x0d\x20"); // skip 1st field ptr[0] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %s \n",__FILE__,__LINE__,__func__, ptr); if (strchr(line,'/') != NULL) { NumberOfSegments = atol(strchr(line,'/')+1); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT/HEA/PhysioBank: multi-segment records are not supported"); } hdr->NS = (typeof(hdr->NS))strtod(ptr+1,&ptr); // number of channels if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): NS=%i %p\n",__FILE__,__LINE__,__func__, hdr->NS, ptr); if ((ptr != NULL) && strlen(ptr)) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...) MIT : 123: <%s>\n",__FILE__,__LINE__,__func__, ptr); hdr->SampleRate = strtod(ptr,&ptr); if (ptr[0]=='/') { double CounterFrequency = strtod(ptr+1,&ptr); if (fabs(CounterFrequency-hdr->SampleRate) > 1e-5) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT format: Sampling rate and counter frequency differ - this is currently not supported!"); } } if (ptr[0]=='(') { double BaseCounterValue = strtod(ptr+1,&ptr); if (BaseCounterValue) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT format: BaseCounterValue is not zero - this is currently not supported !"); } ptr++; // skip ")" } } if ((ptr != NULL) && strlen(ptr)) { hdr->NRec = (nrec_t)strtod(ptr,&ptr); } if ((ptr != NULL) && strlen(ptr)) { struct tm t; sscanf(ptr," %u:%u:%u %u/%u/%u",&t.tm_hour,&t.tm_min,&t.tm_sec,&t.tm_mday,&t.tm_mon,&t.tm_year); t.tm_mon--; t.tm_year -= 1900; t.tm_isdst = -1; hdr->T0 = tm_time2gdf_time(&t); } if (VERBOSE_LEVEL>8) hdr2ascii(hdr,stdout,2); // channel header not parsed yet int fmt=0,FMT=0; size_t MUL=1; char **DatFiles = (char**)calloc(hdr->NS, sizeof(char*)); size_t *ByteOffset = (size_t*)calloc(hdr->NS, sizeof(size_t)); size_t nDatFiles = 0; uint16_t gdftyp,NUM=1,DEN=1; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); hdr->AS.bpb8 = 0; hdr->AS.bpb = 0; for (k=0; k < hdr->NS; k++) { double skew=0; //double byteoffset=0; double ADCgain=200; double baseline=0; double ADCresolution=12; double ADCzero=0; double InitialValue=0; double BlockSize=0; CHANNEL_TYPE* hc = hdr->CHANNEL+k; if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); do line = strtok(NULL,"\x0d\x0a"); while (line[0]=='#'); // read next line if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %i/%i <%s>\n",__FILE__,__LINE__,__func__, (int)k, hdr->NS, line); for (ptr=line; !isspace(ptr[0]); ptr++) {}; // skip 1st field ptr[0]=0; if (k==0) DatFiles[nDatFiles++]=line; else if (strcmp(DatFiles[nDatFiles-1],line)) DatFiles[nDatFiles++]=line; fmt = (typeof(fmt))strtod(ptr+1,&ptr); if (k==0) FMT = fmt; else if (FMT != fmt) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT/HEA/PhysioBank: different formats within a single data set is not supported"); } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); size_t DIV=1; if (ptr[0]=='x') { DIV = (size_t)strtod(ptr+1, &ptr); hdr->CHANNEL[k].SPR *= DIV; MUL = lcm(MUL, DIV); } hdr->CHANNEL[k].SPR = DIV; if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); if (ptr[0]==':') skew = strtod(ptr+1,&ptr); if (ptr[0]=='+') ByteOffset[k] = (size_t)strtod(ptr+1,&ptr); if (ptr != NULL) ADCgain = strtod(ptr+1,&ptr); if (ADCgain==0) ADCgain=200; // DEFGAIN: https://www.physionet.org/physiotools/wag/header-5.htm if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); if (ptr[0] == '(') { baseline = strtod(ptr+1,&ptr); ptr++; } hc->PhysDimCode = 4274; // mV if (ptr[0] == '/') { char *PhysUnits = ++ptr; while (!isspace(ptr[0])) ++ptr; ptr[0] = 0; hc->PhysDimCode = PhysDimCode(PhysUnits); } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); if (ptr != NULL) ADCresolution = strtod(ptr+1,&ptr); if (ptr != NULL) ADCzero = strtod(ptr+1,&ptr); if (ptr != NULL) InitialValue = strtod(ptr+1,&ptr); else InitialValue = ADCzero; double checksum; if (ptr != NULL) checksum = strtod(ptr+1,&ptr); if (ptr != NULL) BlockSize = strtod(ptr+1,&ptr); while (isspace(ptr[0])) ++ptr; strncpy(hdr->CHANNEL[k].Label,ptr,MAX_LENGTH_LABEL); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); hc->Cal = 1/ADCgain; hc->Off = -ADCzero*hc->Cal; hc->OnOff = 1; hc->Transducer[0] = '\0'; hc->LowPass = -1; hc->HighPass = -1; if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); // hdr->FLAG.SWAP = (__BYTE_ORDER == __BIG_ENDIAN); hdr->FILE.LittleEndian = 1; switch (fmt) { case 8: gdftyp = 1; hc->DigMax = 127.0; hc->DigMin = -128.0; biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT/HEA/PhysioBank format 8(diff) not supported"); break; case 80: gdftyp = 2; // uint8; hc->Off= -128*hc->Cal; hc->DigMax = 255.0; hc->DigMin = 0.0; break; case 16: if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); gdftyp = 3; NUM = 2; DEN = 1; hc->DigMax = ldexp( 1.0,15)-1.0; hc->DigMin = ldexp(-1.0,15); break; case 24: gdftyp = 255+24; NUM = 3; DEN = 1; hc->DigMax = ldexp( 1.0,23)-1.0; hc->DigMin = ldexp(-1.0,23); break; case 32: gdftyp = 5; NUM = 4; DEN = 1; hc->DigMax = ldexp( 1.0,31)-1.0; hc->DigMin = ldexp(-1.0,31); break; case 61: gdftyp = 3; // hdr->FLAG.SWAP = !(__BYTE_ORDER == __BIG_ENDIAN); hdr->FILE.LittleEndian = 0; NUM = 2; DEN = 1; hc->DigMax = ldexp( 1.0,15)-1.0; hc->DigMin = ldexp(-1.0,15); break; case 160: gdftyp = 4; // uint16; hc->Off= ldexp(-1.0,15)*hc->Cal; NUM = 2; DEN = 1; hc->DigMax = ldexp(1.0,16)-1.0; hc->DigMin = 0.0; break; case 212: gdftyp = 255+12; NUM = 3; DEN = 2; hc->DigMax = ldexp( 1.0,11)-1.0; hc->DigMin = ldexp(-1.0,11); break; case 310: case 311: gdftyp = 255+10; NUM = 4; DEN = 3; hc->DigMax = ldexp( 1.0,9)-1.0; hc->DigMin = ldexp(-1.0,9); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT/HEA/PhysioBank format 310/311 not supported"); break; default: gdftyp = 0xffff; biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT/HEA/PhysioBank: unknown format"); } hc->GDFTYP = gdftyp; hc->LeadIdCode = 0; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->bi8 = hdr->AS.bpb8; hdr->AS.bpb8 += (hdr->SPR*NUM<<3)/DEN; hc->bi = hdr->AS.bpb; hdr->AS.bpb += hdr->AS.bpb8>>3; if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); } hdr->SampleRate *= MUL; hdr->SPR *= MUL; if (VERBOSE_LEVEL > 7) hdr2ascii(hdr,stdout,4); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): %s(...)\n",__FILE__,__LINE__,__func__); /* read age, sex etc. */ line = strtok(NULL,"\x0d\x0a"); if (line != NULL) { char *t1; double age=0.0; for (k=0; k:"); if (t1 != NULL) age = strtod(t1+5,&ptr); if (age>0.0) hdr->Patient.Birthday = hdr->T0 - (uint64_t)ldexp(age*365.25,32); t1 = strstr(line,"SEX:"); if (t1 != NULL) t1 += 4; else { t1 = strstr(line,"SEX>:"); if (t1 != NULL) t1 += 5; } if (t1 != NULL) { while (isspace(t1[0])) t1++; hdr->Patient.Sex = (t1[0]=='M') + 2* (t1[0]=='F'); } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %i (%i) %s FMT=%i + %i\n",__FILE__,__LINE__,__func__, (int)k+1,(int)nDatFiles,DatFiles[0],fmt,(int)ByteOffset[0]); /* MIT: read ATR annotation file */ char *f0 = hdr->FileName; char *f1 = (char*) malloc(strlen(hdr->FileName)+5); strcpy(f1,hdr->FileName); // Flawfinder: ignore strcpy(strrchr(f1,'.')+1,"atr"); // Flawfinder: ignore hdr->FileName = f1; hdr = ifopen(hdr,"r"); if (!hdr->FILE.OPEN) { // if no *.atr file, try *.qrs strcpy(strrchr(f1,'.')+1,"qrs"); // Flawfinder: ignore hdr = ifopen(hdr,"r"); } if (!hdr->FILE.OPEN) { // *.ecg strcpy(strrchr(f1,'.')+1,"ecg"); // Flawfinder: ignore hdr = ifopen(hdr,"r"); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): <%s> %i %i\n",__FILE__,__LINE__,__func__, hdr->FileName,hdr->FILE.OPEN,(int)bufsiz); if (hdr->FILE.OPEN) { uint16_t *Marker=NULL; count = 0; while (!ifeof(hdr)) { if (bufsiz<1024) bufsiz = 1024; bufsiz *= 2; void *tmp = realloc(Marker, 2 * bufsiz ); Marker = (uint16_t*) tmp; count += ifread (Marker+count, 2, bufsiz-count, hdr); } ifclose(hdr); Marker[count]=0; /* define user specified events according to http://www.physionet.org/physiotools/wfdb/lib/ecgcodes.h */ hdr->EVENT.CodeDesc = (typeof(hdr->EVENT.CodeDesc)) realloc(hdr->EVENT.CodeDesc,257*sizeof(*hdr->EVENT.CodeDesc)); hdr->EVENT.CodeDesc[0] = ""; for (k=0; strlen(MIT_EVENT_DESC[k])>0; k++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...) [MIT 182]: %i\n",__FILE__,__LINE__,__func__, (int)k); hdr->EVENT.CodeDesc[k+1] = (char*)MIT_EVENT_DESC[k]; // hack to satisfy MinGW (gcc version 4.2.1-sjlj) if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...) [MIT 182]: %i %s %s\n",__FILE__,__LINE__,__func__, (int)k,MIT_EVENT_DESC[k],hdr->EVENT.CodeDesc[k]); } hdr->EVENT.LenCodeDesc = k+1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...)[MIT 183] %s %i\n",__FILE__,__LINE__,__func__, f1,(int)count); /* decode ATR annotation information */ size_t N = count; hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP,N*sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS,N*sizeof(*hdr->EVENT.POS)); hdr->EVENT.CHN = (typeof(hdr->EVENT.CHN)) realloc(hdr->EVENT.CHN,N*sizeof(*hdr->EVENT.CHN)); hdr->EVENT.N = 0; hdr->EVENT.SampleRate = hdr->SampleRate; uint16_t chn = 0; size_t pos = 0; char flag_chn = 0; for (k=0; (k> 10; uint16_t len = a16 & 0x03ff; if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i) %s(...)[MIT 183] k=%i/%i N=%i A=%i l=%i\n", __FILE__,__LINE__,__func__, (int)k, (int)N, (int)hdr->EVENT.N, a16>>10, len); switch (A) { case 59: // SKIP pos += (((uint32_t)leu16p(Marker+k+1))<<16) + leu16p(Marker+k+2); k += 2; break; case 60: // NUM case 61: // SUB break; case 62: // CHN chn = len; flag_chn = flag_chn || chn; break; case 63: // AUX k += (len+1)/2; break; default: pos += len; // code = 0 is mapped to 49(ACMAX), see MIT_EVENT_DESC and http://www.physionet.org/physiotools/wfdb/lib/ecgcodes.h hdr->EVENT.TYP[hdr->EVENT.N] = (A==0 ? 49 : A); hdr->EVENT.POS[hdr->EVENT.N] = pos-1; // convert to 0-based indexing hdr->EVENT.CHN[hdr->EVENT.N] = chn; ++hdr->EVENT.N; } } if (flag_chn) hdr->EVENT.DUR = (typeof(hdr->EVENT.DUR)) realloc(hdr->EVENT.DUR,N*sizeof(*hdr->EVENT.DUR)); else { free(hdr->EVENT.CHN); hdr->EVENT.CHN = NULL; } free(Marker); } free(f1); hdr->FileName = f0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...)[MIT 185] \n",__FILE__,__LINE__,__func__); /* MIT: open data file */ if (nDatFiles == 1) { //uint8_t *Marker=NULL; count = 0; char *f0 = hdr->FileName; char *f1 = (char*) malloc(strlen(hdr->FileName)+strlen(DatFiles[0])+2); strcpy(f1,hdr->FileName); hdr->FileName = f1; char *ptr = strrchr(f1,FILESEP); if (ptr != NULL) strcpy(ptr+1,DatFiles[0]); else strcpy(f1,DatFiles[0]); hdr->HeadLen = ByteOffset[0]; hdr = ifopen(hdr,"rb"); ifseek(hdr, hdr->HeadLen, SEEK_SET); count = 0; bufsiz = 1024; while (!ifeof(hdr)) { bufsiz *= 2; void *tmpptr = realloc(hdr->AS.rawdata, bufsiz + 1 ); hdr->AS.rawdata = (uint8_t*) tmpptr; count += ifread (hdr->AS.rawdata+count, 1, bufsiz-count, hdr); } ifclose(hdr); free(f1); hdr->FileName = f0; if (!hdr->NRec) { hdr->NRec = count/(hdr->AS.bpb); } } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %s(...)[MIT 198] #%i: (%i) %s FMT=%i\n",__FILE__,__LINE__,__func__,(int)k+1,(int)nDatFiles,DatFiles[0],fmt); free(DatFiles); free(ByteOffset); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %s(...)[MIT 199] #%i: (%i) %s FMT=%i\n",__FILE__,__LINE__,__func__,(int)k+1,(int)nDatFiles,DatFiles[0],fmt); if (nDatFiles != 1) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "MIT/HEA/PhysioBank: multiply data files within a single data set is not supported"); return(hdr); } hdr->AS.length = hdr->NRec; } /* END OF MIT FORMAT */ #ifdef CHOLMOD_H else if ((hdr->TYPE==MM) && (!hdr->FILE.COMPRESSION)) { if (VERBOSE_LEVEL>7) fprintf(stdout,"[MM 001] %i,%i\n",hdr->HeadLen,hdr->FILE.COMPRESSION); while (!ifeof(hdr)) { count = max(5000, hdr->HeadLen*2); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, count); hdr->HeadLen += ifread(hdr->AS.Header + hdr->HeadLen, 1, count - hdr->HeadLen - 1, hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"[MM 003] %i,%i\n",hdr->HeadLen,hdr->FILE.COMPRESSION); char *line = strtok((char*)hdr->AS.Header, "\x0a\x0d"); char status = 0; unsigned long ns = 0; while (line != NULL) { if (VERBOSE_LEVEL>7) fprintf(stdout,"[MM 013] <%s>\n",line); if ((line[0]=='%') && (line[1]=='%') && isspace(line[2])) { if (!strncmp(line+3,"LABELS",6)) status = 1; else if (!strncmp(line+3,"ENDLABEL",8)) { status = 0; break; } if (status) { int k = 3; while (isspace(line[k])) k++; unsigned long ch = strtoul(line+k, &line, 10); while (isspace(line[0])) line++; if (ch >= ns) { hdr->rerefCHANNEL = (CHANNEL_TYPE*)realloc(hdr->rerefCHANNEL, ch*sizeof(CHANNEL_TYPE)); while (ns < ch) { hdr->rerefCHANNEL[ns].Label[0] = 0; hdr->rerefCHANNEL[ns].Transducer[0] = 0; ns++; } } strncpy(hdr->rerefCHANNEL[ch-1].Label, line, MAX_LENGTH_LABEL); hdr->rerefCHANNEL[ch-1].OnOff = 1; hdr->rerefCHANNEL[ch-1].Label[MAX_LENGTH_LABEL] = 0; hdr->rerefCHANNEL[ch-1].LeadIdCode = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"[MM 027] %i <%s>\n",(int)ch,line); } } line = strtok(NULL,"\x0a\x0d"); } if (VERBOSE_LEVEL>7) fprintf(stdout,"[MM 033]\n"); ifseek(hdr,0,SEEK_SET); CSstart(); // init cholmod library CHOLMOD_COMMON_VAR.print = 5; hdr->Calib = cholmod_read_sparse (hdr->FILE.FID, &CHOLMOD_COMMON_VAR); /* read in a matrix */ if (VERBOSE_LEVEL>7) cholmod_print_sparse (hdr->Calib, "Calib", &CHOLMOD_COMMON_VAR); /* print the matrix */ ifclose(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"[MM 999]\n"); return(hdr); } /* END OF MatrixMarket */ #endif else if (hdr->TYPE==NEURON) { hdr->HeadLen = count; if (VERBOSE_LEVEL>7) fprintf(stdout,"NEURON: start\n"); size_t count; while (!ifeof(hdr)) { count = max(1<<20, hdr->HeadLen*2); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, count); hdr->HeadLen += ifread(hdr->AS.Header + hdr->HeadLen, 1, count - hdr->HeadLen - 1, hdr); } hdr->AS.Header[hdr->HeadLen] = 0; hdr->NS = 1; hdr->SPR = 1; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); hdr->CHANNEL[0].GDFTYP = 17; hdr->CHANNEL[0].Cal = 1.0; hdr->CHANNEL[0].Off = 0.0; hdr->CHANNEL[0].PhysMin = -1e9; hdr->CHANNEL[0].PhysMax = +1e9; hdr->CHANNEL[0].DigMin = -1e9; hdr->CHANNEL[0].DigMax = +1e9; hdr->AS.bpb = sizeof(double); hdr->CHANNEL[0].bi = 0; hdr->CHANNEL[0].bi8 = 0; hdr->CHANNEL[0].LeadIdCode = 0; hdr->CHANNEL[0].SPR = hdr->SPR; hdr->CHANNEL[0].LowPass = NAN; hdr->CHANNEL[0].HighPass = NAN; hdr->CHANNEL[0].Notch = NAN; hdr->CHANNEL[0].Transducer[0] = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"NEURON 202: \n"); char *t = strtok( (char*)hdr->AS.Header, "\x0A\x0D"); char status = 0; size_t spr = 0; while (t != NULL) { if (VERBOSE_LEVEL>8) fprintf(stdout,"NEURON 301: <%s>\n", t); if (status==0) { if (!strncmp(t,"Header:", 7)) status = 1; } else if (status==1) { if (VERBOSE_LEVEL>7) fprintf(stdout,"NEURON 311: <%s>\n",t); char *val = t+strlen(t); while (isspace(*(--val))) {}; val[1]=0; // remove trailing blanks val = strchr(t,':'); // find right value val[0] = 0; while (isspace(*(++val))) {}; if (!strncmp(t,"Data", 7)) { status=2; spr = 0; } else if (!strcmp(t,"SampleInt")) hdr->SampleRate = 1.0 / atof(val); else if (!strcmp(t,"Points")) { hdr->NRec = atoi(val); hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata, sizeof(double) * hdr->NRec); } else if (!strcmp(t,"XUnit")) { uint16_t xunits = PhysDimCode(val); double scale = PhysDimScale(xunits); if ((xunits & 0xffe0)==2176) hdr->SampleRate /= scale; else fprintf(stdout, "Error NEURON: invalid XUnits <%s>\n", val); } else if (!strcmp(t,"YUnit")) { if (VERBOSE_LEVEL>7) fprintf(stdout,"NEURON 321: Yunits:<%s>\n",val); hdr->CHANNEL[0].PhysDimCode = PhysDimCode(val); } else if (!strcmp(t,"Method")) { strncpy(hdr->CHANNEL[0].Label, val, MAX_LENGTH_LABEL); } } else if (status==2) { if (strpbrk(t,"0123456789")) { // ignore non-numeric (e.g. emtpy) lines *(double*)(hdr->AS.rawdata + spr*sizeof(double)) = atof(t); spr++; } if (hdr->NRec >= 0) if (spr >= (size_t)hdr->NRec) { void *ptr = realloc(hdr->AS.rawdata, 2 * min(spr, (size_t)hdr->NRec) * sizeof(double)); if (ptr==NULL) break; hdr->AS.rawdata = (uint8_t*)ptr; } } t = strtok(NULL, "\x0A\x0D"); } free(hdr->AS.Header); hdr->AS.Header = NULL; hdr->AS.first = 0; hdr->AS.length = spr; } else if (hdr->TYPE == NeuroLoggerHEX) { hdr->NS = 8; // uint16_t gdftyp = 2; biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "NeuroLogger HEX format not supported, yet"); return(hdr); } #if defined(WITH_NEV) else if (hdr->TYPE==NEV) { fprintf(stdout,"Support for NEV format is under construction - most likely its not useful yet.\n"); if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (NEV)\n"); hdr->VERSION = beu16p(hdr->AS.Header+8)>>8; switch (beu16p(hdr->AS.Header+8)) { case 0x0100: // readnev1 case 0x0101: // readnev1_1 case 0x0200: // readnev2 //biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, NULL); break; default: biosigERROR(hdr, B4C_FORMAT_UNKNOWN, NULL); } const int H1Len = 28+16+32+256+4; /* read Basic Header */ // uint16_t fileFormat = beu16p(hdr->AS.Header+10); uint32_t HeadLen = leu32p(hdr->AS.Header+12); if (HeadLen < H1Len) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, NULL); return(hdr); } hdr->AS.bpb = leu32p(hdr->AS.Header+16); uint32_t TimeStepFrequency = leu32p(hdr->AS.Header+20); // samples = TimeStepFrequency / 10; // Freq in 0.1 seconds hdr->SampleRate = leu32p(hdr->AS.Header+24); if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (NEV) [210] %d %d \n", (int)count, (int)HeadLen); if (countAS.Header = (uint8_t*)realloc(hdr->AS.Header,HeadLen); count += ifread(hdr->AS.Header+count, 1, HeadLen-count, hdr); } uint32_t extHdrN = leu32p(hdr->AS.Header+H1Len-4); if (count < H1Len + 32*extHdrN) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,HeadLen); count += ifread(hdr->AS.Header+count, 1, HeadLen-count, hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (NEV) [220] %d %d %d \n", extHdrN, (int)count, (int)HeadLen); struct tm t; t.tm_year = leu32p(hdr->AS.Header+28); t.tm_mon = leu32p(hdr->AS.Header+30); //t.tm_wday = beu32p(hdr->AS.Header+32); t.tm_mday = leu32p(hdr->AS.Header+34); t.tm_hour = leu32p(hdr->AS.Header+36); t.tm_min = leu32p(hdr->AS.Header+38); t.tm_sec = leu32p(hdr->AS.Header+40); //milliseconds = beu32p(hdr->AS.Header+42); hdr->T0 = tm_time2gdf_time(&t); double time_interval = 1e3 * (hdr->AS.bpb-8) / TimeStepFrequency; if (VERBOSE_LEVEL>7) hdr2ascii(hdr,stdout,2); //******** read Extended Header ********* const char *nameOfElectrode, *extraComment, *continuedComment, *mapfile; const char *H2 = (char*)hdr->AS.Header + H1Len; hdr->NS = 0; for (k = 0; k < extHdrN; k++) { const char *identifier = H2 + k*32; if (VERBOSE_LEVEL>8) { char tmp[9];tmp[8]=0; char tmp24[25]; tmp24[24]=0; memcpy(tmp,identifier,8); memcpy(tmp24,identifier+8,24); fprintf(stdout,"SOPEN (NEV) [225] %d %d <%s> <%s>\n",(int)k,hdr->NS,tmp,tmp24); } if (!memcmp (identifier, "NEUEVWAV",8)) hdr->NS++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (NEV) [230]\n"); hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); uint16_t NS = 0; for (k = 0; k < extHdrN; k++) { const char *identifier = H2 + k*32; if (!memcmp (identifier, "ARRAYNME",8)) { nameOfElectrode = identifier + 8; } else if (!memcmp (identifier, "ECOMMENT",8)) { extraComment = identifier + 8; } else if (!memcmp (identifier, "CCOMMENT",8)) { continuedComment = identifier + 8; } else if (!memcmp (identifier, "MAPFILE",8)) { mapfile = identifier + 8; } else if (!memcmp (identifier, "NEUEVWAV",8)) { //neuralEventWaveform = identifier + 8; CHANNEL_TYPE *hc = hdr->CHANNEL+(NS++); sprintf(hc->Label,"#%d",leu16p(identifier + 8)); // electrodeId hc->Transducer[0] = 0; // (uint8_t)(identifier + 8 + 2); // module // (uint8_t)(identifier + 8 + 3); // channel hc->OnOff = 1; hc->Cal = leu16p(identifier+ 8 + 4); // scaling factor // beu16p(identifier + 8 + 6); // energyTreshold hc->Off = 0; hc->DigMax = lei16p(identifier + 8 + 8); // high threshold hc->DigMin = lei16p(identifier + 8 + 10); // low threshold // (uint8_t)(identifier + 8 + 11); // sortedUnitsInChannel hc->GDFTYP = 2 * identifier[8 + 12]; // bytesPerWaveformSample hc->PhysMax = hc->DigMax*hc->Cal; hc->PhysMin = hc->DigMin*hc->Cal; hc->LeadIdCode = 0; hc->Transducer[0] = 0; hc->PhysDimCode = 0; hc->TOffset = 0; hc->LowPass = NAN; hc->HighPass = NAN; hc->Notch = NAN; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; hc->Impedance = NAN; hc->SPR = 0; hc->bi = hdr->AS.bpb; hc->bi8 = hdr->AS.bpb*8; hc->bufptr = NULL; } else if (!memcmp (identifier, "NSASEXEV",8)) { char *nsas = identifier + 8; } else { /* // IGNORE biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "NEV: unknown extended header"); */ } } return(hdr); } #endif else if (hdr->TYPE==NEX1) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__func__,__LINE__); if (count < 284) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,284); count += ifread(hdr->AS.Header + count, 1, 284 - count, hdr); } uint8_t v = hdr->AS.Header[3]-'0'; const int H1LEN = (v==1) ? (4 + 4 + 256 + 8 + 4*4 + 256) : (4 + 4 + 256 + 8 + 8 + 4 + 8 + 64); const int H2LEN = (v==1) ? (4 + 4 + 64 + 6*4 + 4*8 + 12 + 16 + 52) : (4 + 4 + 64 + 2*8 + 2*4 + 8 + 32 + 4*8 + 4*4 + 60); uint32_t k = leu32p(hdr->AS.Header + 280); if (count < H1LEN + k * H2LEN) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, H1LEN + k * H2LEN); count += ifread(hdr->AS.Header + count, 1, H1LEN + k * H2LEN - count, hdr); } hdr->HeadLen = count; hdr->VERSION = leu32p(hdr->AS.Header + 4) / 100.0; hdr->SampleRate = lef64p(hdr->AS.Header + 264); hdr->SPR = 1; hdr->EVENT.SampleRate = lef64p(hdr->AS.Header + 264); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__func__,__LINE__); if (k > 0xffff) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "NEX format has more than 65535 channels"); return (hdr); } while (!ifeof(hdr)) { void *tmpptr = realloc(hdr->AS.Header, count*2); if (tmpptr) hdr->AS.Header = (uint8_t*)tmpptr; else { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Not enough memory to read NEX file"); return(hdr); } count += ifread(hdr->AS.Header + count, 1, count, hdr); } hdr->NS = k; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__func__,__LINE__); for (k=0; k < hdr->NS; k++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): VarHdr # %i\n",__func__,__LINE__, k); CHANNEL_TYPE *hc = hdr->CHANNEL+k; uint32_t type = leu32p(hdr->AS.Header + H1LEN + k*H2LEN); hc->OnOff = (type==5); strncpy(hc->Label, hdr->AS.Header + H1LEN + k*H2LEN + 8, min(64,MAX_LENGTH_LABEL)); hc->Label[min(64, MAX_LENGTH_LABEL)] = 0; hc->Transducer[0] = 0; size_t n; if (v==5) { hc->GDFTYP = (leu32p(hdr->AS.Header + H1LEN + k*H2LEN + 92)==1) ? 16 : 3; hc->PhysDimCode = PhysDimCode(hdr->AS.Header + H1LEN + k*H2LEN + 5*8 + 64); n = leu64p(hdr->AS.Header + 80 + H1LEN + k*H2LEN); hc->Cal = lef64p(hdr->AS.Header + 64+8*5+32 + H1LEN + k*H2LEN); hc->Off = lef64p(hdr->AS.Header + 64+8*5+40 + H1LEN + k*H2LEN); hc->SPR = leu64p(hdr->AS.Header + 64+8*5+48 + H1LEN + k*H2LEN); hc->bufptr = hdr->AS.Header + leu64p(hdr->AS.Header + 64+8 + H1LEN + k*H2LEN); } else { hc->GDFTYP = 3; hc->PhysDimCode = PhysDimCode("mV"); n = leu32p(hdr->AS.Header + 76 + H1LEN + k*H2LEN); hc->Cal = lef64p(hdr->AS.Header + 64+8*4+3*8 + H1LEN + k*H2LEN); hc->Off = lef64p(hdr->AS.Header + 64+8*4+3*8+20 + H1LEN + k*H2LEN); hc->SPR = leu32p(hdr->AS.Header + 64+8*4+4*8 + H1LEN + k*H2LEN); hc->bufptr = hdr->AS.Header+leu32p(hdr->AS.Header + 64+8 + H1LEN + k*H2LEN); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): VarHdr # %i %i %i %i \n",__func__,__LINE__, k,v,type,(int)n); switch (type) { case 2: //case 6: case 0: case 1: hdr->EVENT.N += n; } //if (hc->OnOff) hdr->SPR = lcm(hdr->SPR, hc->SPR); } if (hdr->EVENT.N > 0) { size_t N=hdr->EVENT.N; hdr->EVENT.N=0; reallocEventTable(hdr,N); N = 0; for (k=0; k < hdr->NS; k++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): VarHdr # %i\n",__func__,__LINE__, k); CHANNEL_TYPE *hc = hdr->CHANNEL+k; uint32_t type = leu32p(hdr->AS.Header + H1LEN + k*H2LEN); size_t n,l; uint16_t gdftyp = 5; if (v==5) { n = leu64p(hdr->AS.Header + 80 + H1LEN + k*H2LEN); if (leu32p(hdr->AS.Header + 88 + H1LEN + k*H2LEN)) gdftyp=7; } else n = leu32p(hdr->AS.Header + 76 + H1LEN + k*H2LEN); switch (type) { case 2: if (gdftyp==5) { for (l=0; lEVENT.DUR[N+l] = leu32p(hc->bufptr+4*(l+n)); } else { for (l=0; lEVENT.DUR[N+l] = leu64p(hc->bufptr+8*(l+n)); } case 0: case 1: //case 6: if (gdftyp==5) { for (l=0; lEVENT.POS[N+l] = leu32p(hc->bufptr+4*l); } else { for (l=0; lEVENT.POS[N+l] = leu64p(hc->bufptr+8*l); } for (l=0; lEVENT.TYP[N+l] = type; hdr->EVENT.CHN[N+l] = k; //hdr->EVENT.TimeStamp[N+l] = 0; } } N+=n; } hdr->EVENT.N=N; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i)\n",__func__,__LINE__); hdr2ascii(hdr,stdout,4); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Support for NEX format is not ready yet"); return(hdr); } else if (hdr->TYPE==NIFTI) { if (count<352) count += ifread(hdr->AS.Header+count, 1, 352-count, hdr); // nifti_1_header *NIFTI_HDR = (nifti_1_header*)hdr-AS.Header; char SWAP = *(int16_t*)(Header1+40) > 7; #if (__BYTE_ORDER == __BIG_ENDIAN) hdr->FILE.LittleEndian = SWAP; #elif (__BYTE_ORDER == __LITTLE_ENDIAN) hdr->FILE.LittleEndian = !SWAP; #endif if (!SWAP) { hdr->HeadLen = (size_t)*(float*)(Header1+80); } else { union {uint32_t u32; float f32;} u; u.u32 = bswap_32(*(uint32_t*)(Header1+108)); hdr->HeadLen = (size_t)u.f32; } if (Header1[345]=='i') { ifclose(hdr); char *f0 = hdr->FileName; char *f1 = (char*)malloc(strlen(hdr->FileName)+4); strcpy(f1,hdr->FileName); strcpy(strrchr(f1,'.') + 1, "img"); // Flawfinder: ignore hdr->FileName = f1; hdr = ifopen(hdr,"r"); hdr->FileName = f0; } else ifseek(hdr,hdr->HeadLen,SEEK_SET); #ifdef _NIFTI_HEADER_ nifti_1_header *NIFTI_HDR = (nifti_1_header*)hdr->AS.Header; #endif ifclose(hdr); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format NIFTI not supported"); return(hdr); } else if (hdr->TYPE==NUMPY) { /* There is no way to extract sampling rate and scaling factors from numpy files. For this reason, numpy is not going to be a supported data format. */ fprintf(stderr,"Warning SOPEN (NUMPY): sampling rate, scaling, physical units etc. are not supported, and are most likely incorrect."); hdr->VERSION = hdr->AS.Header[6]+hdr->AS.Header[7]/100; hdr->HeadLen = leu16p(hdr->AS.Header+8); if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, hdr->HeadLen+1); count += ifread(hdr->AS.Header + count, 1, hdr->HeadLen - count, hdr); } hdr->AS.Header[count]=0; hdr->NS=1; hdr->SPR=0; hdr->NRec=1; uint16_t gdftyp = 0; const char *h=(char*)hdr->AS.Header+10; int flag_order = (strstr(h,"'fortran_order': False")==NULL) + (strstr(h,"'fortran_order': True")==NULL)*2; switch (flag_order) { case 1: break; case 2: break; default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "format NUMPY: fortran_order not specified or invalid"); } char *descr = strstr(h,"'descr':"); if (descr==NULL) biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format NUMPY: descr not defined"); else { descr += 8; descr += strspn(descr," \t'"); descr[strcspn(descr," \t'")]=0; if (descr[0]=='<') hdr->FILE.LittleEndian = 1; else if (descr[0]=='>') hdr->FILE.LittleEndian = 0; else biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format NUMPY: field 'descr': endianity undefined"); if (!strcmp(descr+1,"f8")) gdftyp = 17; else if (!strcmp(descr+1,"f4")) gdftyp = 16; else if (!strcmp(descr+1,"u8")) gdftyp = 8; else if (!strcmp(descr+1,"i8")) gdftyp = 7; else if (!strcmp(descr+1,"u4")) gdftyp = 6; else if (!strcmp(descr+1,"i4")) gdftyp = 5; else if (!strcmp(descr+1,"u2")) gdftyp = 4; else if (!strcmp(descr+1,"i2")) gdftyp = 3; else if (!strcmp(descr+1,"u1")) gdftyp = 2; else if (!strcmp(descr+1,"i1")) gdftyp = 1; else biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format NUMPY: field 'descr': not supported"); } char *shapestr = strstr(h,"'shape':"); if (shapestr==NULL) biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format NUMPY: shape not defined"); else { int n = 0; char *tmpstr = strchr(shapestr,'(') + 1; while (tmpstr && *tmpstr) { *strchr(tmpstr,')') = 0; // terminating \0 char *next = strchr(tmpstr,','); if (next) { *next=0; long dim = atol(tmpstr); switch (n) { case 0: hdr->SPR =dim; break; case 1: hdr->NS =dim; break; //case 2: hdr->NRec=dim; break; default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "format NUMPY: shape not supported"); } n++; tmpstr = next+1; } } } hdr->AS.bpb = hdr->NS*GDFTYP_BITS[gdftyp]>>3; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); typeof (hdr->NS) k; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Transducer[0] = 0; hc->Label[0] = 0; hc->GDFTYP = gdftyp; hc->SPR = hdr->SPR; hc->Cal = 1.0; hc->Off = 0.0; } if (VERBOSE_LEVEL > 6) fprintf(stdout,"NUMPY:\n%s",(char*)hdr->AS.Header+10); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format NUMPY not supported"); return(hdr); } else if (hdr->TYPE==Persyst) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) (Persyst) [225]\n", __func__,__LINE__); size_t c=1; while (~ifeof(hdr) && c) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d) (Persyst) [25] %d\n",__func__,__LINE__,(int)count); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,count*2+1); c = ifread(hdr->AS.Header + count, 1, count, hdr); count += c; } hdr->AS.Header[count] = 0; ifclose(hdr); hdr->SPR = 1; int32_t gdftyp = 3; double Cal = 1.0; int status = 0; char *remHDR=(char*)hdr->AS.Header; const char *FirstName=NULL, *MiddleName=NULL, *SurName=NULL; char *datfile = NULL; struct tm RecTime; size_t NEvent = 0; hdr->FLAG.OVERFLOWDETECTION = 0; // overflow detection is not supported for this format double DigMax = ldexp(1,-15); double DigMin = -ldexp(1,-15)-1; char *line; char flag_interleaved = 1; while (1) { if (*remHDR == '\0') break; // line = strsep(&remHDR,"\n\r"); line = remHDR; remHDR = strpbrk(remHDR,"\n\r\0"); *remHDR++ = 0; remHDR += strspn(remHDR,"\n\r"); if (!strncmp(line,"[FileInfo]",10)) status = 1; else if (!strncmp(line,"[ChannelMap]",12)) { status = 2; hdr->AS.bpb = hdr->NS*GDFTYP_BITS[gdftyp]>>3; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); uint16_t ch; for (ch=0; ch < hdr->NS; ch++) { CHANNEL_TYPE *hc = hdr->CHANNEL+ch; hc->PhysMax = DigMax*Cal; hc->PhysMin = DigMin*Cal; hc->DigMax = DigMax; hc->DigMin = DigMin; hc->Cal = Cal; hc->Off = 0.0; hc->OnOff = 1; hc->Label[0] = 0; hc->LeadIdCode = 0; hc->Transducer[0] = 0; hc->PhysDimCode = 0; //TODO hc->GDFTYP = gdftyp; hc->TOffset = NAN; hc->LowPass = NAN; hc->HighPass = NAN; hc->Notch = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; hc->Impedance = NAN; hc->SPR = hdr->SPR; hc->bi8 = ch*GDFTYP_BITS[gdftyp]; hc->bi = hc->bi8>>3; hc->bufptr = NULL; } } else if (!strncmp(line,"[Sheets]",8)) status = 3; else if (!strncmp(line,"[Comments]",10)) status = 4; else if (!strncmp(line,"[Patient]",9)) status = 5; else if (!strncmp(line,"[SampleTimes]",13)) status = 6; else { switch (status) { case 1: { char *tag = line; char *val = strchr(line,'='); *val= 0; // replace "=" with terminating \0 val++; // next character is the start of the value parameters if (!strcmp(tag,"File")) { datfile = strrchr(val,'/'); if (!datfile) datfile = strrchr(val,'\\')+1; if (!datfile) datfile = val; } else if (!strcmp(line,"FileType")) flag_interleaved = !strcmp(val,"Interleaved"); else if (!strcmp(line,"SamplingRate")) hdr->SampleRate = atof(val); else if (!strcmp(line,"Calibration")) Cal = atof(val); else if (!strcmp(line,"WaveformCount")) hdr->NS = atol(val); else if (!strcmp(line,"DataType")) { switch (atol(val)) { case 0: gdftyp = 3; // int 16 hdr->FILE.LittleEndian = 1; hdr->AS.bpb *= 2; DigMin = -ldexp(1.0,-15)-1; DigMax = ldexp(1.0,-15); break; case 4: gdftyp = 3; // int16 hdr->FILE.LittleEndian = 0; hdr->AS.bpb *= 2; DigMin = -ldexp(1.0,-15)-1; DigMax = ldexp(1.0,-15); break; case 6: gdftyp = 1; // int8 DigMin = -ldexp(1.0,-7)-1; DigMax = ldexp(1.0,-7); break; default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format Persyst: unsupported data type"); } } break; } case 2: { char *tag = line; char *val = strchr(line,'='); *val = 0; // replace "=" with terminating \0 val++; // next character is the start of the value parameters int channo = atol(val)-1; if (0 <= channo && channo < hdr->NS) { strncpy(hdr->CHANNEL[channo].Label, tag, MAX_LENGTH_LABEL); } break; } case 3: { break; } case 4: { if (NEvent < hdr->EVENT.N+2) { NEvent += max(128,NEvent); if (reallocEventTable(hdr, NEvent) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return (hdr); }; } char *tmp2,*tmp1 = line; tmp2 = strchr(tmp1,','); *tmp2 = 0; hdr->EVENT.POS[hdr->EVENT.N] = atof(tmp1)*hdr->SampleRate; tmp1 = strchr(tmp2+1,','); *tmp1 = 0; hdr->EVENT.DUR[hdr->EVENT.N] = atof(tmp1)*hdr->SampleRate; tmp2 = strchr(tmp1+1,','); *tmp2 = 0; // ignore next field tmp1 = strchr(tmp2+1,','); *tmp1 = 0; // ignore next field char *Desc = tmp1+1; FreeTextEvent(hdr,hdr->EVENT.N,Desc); hdr->EVENT.N++; break; } case 5: { char *val = strchr(line,'='); *val= 0; // replace "=" with terminating \0 val++; // next character is the start of the value parameters if (!strcmp(line,"First")) FirstName=val; else if (!strcmp(line,"MI")) MiddleName=val; else if (!strcmp(line,"Last")) SurName=val; else if (!strcmp(line,"Hand")) hdr->Patient.Handedness = (toupper(val[0])=='R') + 2*(toupper(val[0])=='L') ; else if (!strcmp(line,"Sex")) hdr->Patient.Sex = (toupper(val[0])=='M') + 2*(toupper(val[0])=='F') ; else if (!strcmp(line,"BirthDate")) { struct tm t; t.tm_year = atol(val+6); if (t.tm_year < 80) t.tm_year+=100; val[5]=0; t.tm_mday = atol(val+3); val[2]=0; t.tm_mon = atol(val); t.tm_hour = 12; t.tm_min = 0; t.tm_sec = 0; hdr->Patient.Birthday = tm_time2gdf_time(&t); } else if (!strcmp(line,"TestDate")) { RecTime.tm_year = atol(val+6); if (RecTime.tm_year < 80) RecTime.tm_year+=100; val[5]=0; RecTime.tm_mday = atol(val+3); val[2]=0; RecTime.tm_mon = atol(val); } else if (!strcmp(line,"TestTime")) { RecTime.tm_sec = atol(val+6); val[5]=0; RecTime.tm_min = atol(val+3); val[2]=0; RecTime.tm_hour = atol(val); } else if (!strcmp(line,"ID")) { strncpy(hdr->Patient.Id,val,MAX_LENGTH_PID); hdr->Patient.Id[MAX_LENGTH_PID] = 0; } /* Omitted, because it is not important, identification through ID, and T0; quality is determined by Technician else if (!strcmp(line,"Physician")) Physician=val; */ else if (!strcmp(line,"Technician")) hdr->ID.Technician = strdup(val); else if (!strcmp(line,"Medications")) hdr->Patient.Medication = (val!=NULL) && strlen(val)>0; break; } case 6: { break; } case 7: { break; } } } } if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (Persyst) [260] %d<%s>\n",status,line); hdr->T0 = tm_time2gdf_time(&RecTime); if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (Persyst) [270] %d<%s>\n",status,line); if (!hdr->FLAG.ANONYMOUS) { size_t len = 0, len0=0; if (SurName!=NULL) len += strlen(SurName); if (len < MAX_LENGTH_NAME) { strcpy(hdr->Patient.Name, SurName); hdr->Patient.Name[len]=0x1f; len0 = ++len; } if (FirstName!=NULL) len += strlen(FirstName); if (len < MAX_LENGTH_NAME) { strcpy(hdr->Patient.Name+len0, FirstName); hdr->Patient.Name[len]=' '; len0 = ++len; } if (MiddleName!=NULL) len += strlen(MiddleName); if (len < MAX_LENGTH_NAME) { strcpy(hdr->Patient.Name+len0, MiddleName); hdr->Patient.Name[len0]=' '; } hdr->Patient.Name[len]=0; } if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (Persyst) [280] %d<%s>\n",status,datfile); size_t len = strlen(hdr->FileName); char *FileName = hdr->FileName; hdr->FileName = (char*) malloc(len+strlen(datfile)+2); if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (Persyst) [283] %d<%s> %d/%d\n",(int)len,datfile,(int)hdr->SPR,(int)hdr->NRec); if (strspn(FileName,"/\\")) { strcpy(hdr->FileName, FileName); char *tmpstr = strrchr(hdr->FileName,'/')+1; if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (Persyst) [285] %d<%s>\n",(int)len,tmpstr); if (tmpstr==NULL) tmpstr = strrchr(hdr->FileName,'\\')+1; if (tmpstr!=NULL) strcpy(tmpstr,datfile); else { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "Format Persyst: cannot open dat file."); } } else { strcpy(hdr->FileName, datfile); } if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (Persyst) [290] %d<%s>\n",status, hdr->FileName); struct stat FileBuf; if (stat(hdr->FileName, &FileBuf)==0) { hdr->FILE.size = FileBuf.st_size; hdr->NRec = FileBuf.st_size*8/(hdr->NS*GDFTYP_BITS[gdftyp]); if (!flag_interleaved) { hdr->SPR = hdr->NRec; hdr->NRec = 1; uint16_t ch; for (ch=0; ch < hdr->NS; ch++) { CHANNEL_TYPE *hc = hdr->CHANNEL+ch; hc->SPR = hdr->SPR; size_t bi8 = ch * (size_t)hdr->SPR * GDFTYP_BITS[gdftyp]; hc->bi8 = bi8; hc->bi = bi8>>3; } hdr->AS.bpb = FileBuf.st_size; } } else { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "Format Persyst: cannot open dat file."); } ifopen(hdr,"r"); hdr->HeadLen = 0; // datfile has no header free(hdr->FileName); hdr->FileName = FileName; if (VERBOSE_LEVEL>7) fprintf(stdout,"SOPEN (Persyst) [298] %d %d %d\n",(int)FileBuf.st_size,(int)hdr->AS.bpb,(int)(FileBuf.st_size/hdr->AS.bpb)); } else if (hdr->TYPE==PLEXON) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format PLEXON not supported"); return(hdr); } else if (hdr->TYPE==RDF) { // UCSD ERPSS aquisition system #define RH_F_CONV 0x0001 /* converted from other format */ #define RH_F_RCOMP 0x0002 /* raw file is compressed */ #define RH_F_DCMAP 0x4000 /* channel mapping used during dig. */ #define RH_CHANS 256 /* maximum # channels */ #define RH_DESC 64 /* max # chars in description */ #define RH_CHDESC 8 /* max # chars in channel descriptor */ #define RH_SFILL 4 /* short filler */ #define RH_LFILL 6 /* long filler */ #define RH_ALOG 828 /* max # chars in ASCII log */ struct rawhdr { uint16_t rh_byteswab; /* ERPSS byte swab indicator */ uint16_t rh_magic; /* file magic number */ uint16_t rh_flags; /* flags */ uint16_t rh_nchans; /* # channels */ uint16_t rh_calsize; /* (if norm, |cal|) */ uint16_t rh_res; /* (if norm, in pts/unit) */ uint16_t rh_pmod; /* # times processed */ uint16_t rh_dvers; /* dig. program version */ uint16_t rh_l2recsize; /* log 2 record size */ uint16_t rh_recsize; /* record size in pts */ uint16_t rh_errdetect; /* error detection in effect */ uint16_t rh_chksum; /* error detection chksum */ uint16_t rh_tcomp; /* log 2 time comp/exp */ uint16_t rh_narbins; /* (# art. rej. count slots) */ uint16_t rh_sfill[RH_SFILL]; /* short filler (to 16 slots) */ uint16_t rh_nrmcs[RH_CHANS]; /* (cal sizes used for norm.) */ uint32_t rh_time; /* creation time, secs since 1970 */ uint32_t rh_speriod; /* digitization sampling period */ uint32_t rh_lfill[RH_LFILL]; /* long filler (to 8 slots) */ char rh_chdesc[RH_CHANS][RH_CHDESC]; /* chan descriptions */ char rh_chmap[RH_CHANS]; /* input chan mapping array */ char rh_subdesc[RH_DESC]; /* subject description */ char rh_expdesc[RH_DESC]; /* experimenter description */ char rh_ename[RH_DESC]; /* experiment name */ char rh_hname[RH_DESC]; /* host machine name */ char rh_filedesc[RH_DESC]; /* file description */ char rh_arbdescs[RH_DESC]; /* (art. rej. descriptions) */ char rh_alog[RH_ALOG]; /* ASCII log */ }; if (count < sizeof(struct rawhdr)) { hdr->HeadLen = sizeof(struct rawhdr); hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header,hdr->HeadLen+1); count += ifread(Header1+count, 1, hdr->HeadLen-count, hdr); hdr->AS.Header[hdr->HeadLen]=0; } hdr->NS = *(uint16_t*)(hdr->AS.Header+2); time_t T0 = (time_t)*(uint32_t*)(hdr->AS.Header+32); // seconds since 1970 hdr->T0 = t_time2gdf_time(T0); hdr->SampleRate = 1e6 / (*(uint32_t*)(hdr->AS.Header+36)); strncpy(hdr->Patient.Id, (const char*)hdr->AS.Header+32+24+256*9, min(64,MAX_LENGTH_PID)); hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; hc->OnOff = 1; strncpy(hc->Label,(char*)(hdr->AS.Header+32+24+8*k),8); hc->Transducer[0] = 0; hc->LeadIdCode = 0; } biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format RDF (UCSD ERPSS) not supported"); } else if (hdr->TYPE==IntanCLP) { sopen_intan_clp_read(hdr); } else if (hdr->TYPE==RHD2000) { sopen_rhd2000_read(hdr); } else if (hdr->TYPE==RHS2000) { sopen_rhs2000_read(hdr); } else if (hdr->TYPE==SCP_ECG) { hdr->HeadLen = leu32p(hdr->AS.Header+2); if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); } uint16_t crc = CRCEvaluate(hdr->AS.Header+2,hdr->HeadLen-2); if ( leu16p(hdr->AS.Header) != crc) { biosigERROR(hdr, B4C_CRC_ERROR, "Warning SOPEN(SCP-READ): Bad CRC!"); } hdr->Version = hdr->AS.Header[14]/10.0; sopen_SCP_read(hdr); serror2(hdr); // report and reset error, but continue // hdr->FLAG.SWAP = 0; // no swapping hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); // no swapping hdr->AS.length = hdr->NRec; } else if (hdr->TYPE==Sigma) { /********* Sigma PLpro ************/ hdr->HeadLen = leu32p(hdr->AS.Header+16); if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header,hdr->HeadLen+1); count += ifread(Header1+count, 1, hdr->HeadLen-count, hdr); } hdr->AS.Header[count]=0; struct tm t; char *tag, *val; size_t pos = leu32p(hdr->AS.Header+28); uint8_t len; typeof(hdr->NS) k; for (k=0; k<5; k++) { #define line ((char*)(hdr->AS.Header+pos)) len = strcspn(line,"\x0a\x0d"); line[len] = 0; tag = line; val = strchr(line,'='); if (val!=NULL) { val[0] = 0; val++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%i: %s=%s\n",k,tag,val); if (0) {} //else if (!strcmp(tag,"Name")) {} //else if (!strcmp(tag,"Vorname")) {} else if (!strcmp(tag,"GebDat")) { sscanf(val,"%02u.%02u.%04u",&t.tm_mday,&t.tm_mon,&t.tm_year); t.tm_year -=1900; t.tm_mon--; t.tm_hour = 12; t.tm_min = 0; t.tm_sec = 0; t.tm_isdst = -1; hdr->T0 = tm_time2gdf_time(&t); } else if (!strcmp(tag,"ID")) strncpy(hdr->Patient.Id,val,MAX_LENGTH_PID); pos += len+1; while ((line[0]==10) || (line[0]==13)) pos++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"333 SIGMA pos=%i, 0x%x\n", (int)pos, (int)pos); hdr->NS = leu16p(hdr->AS.Header+pos); hdr->SampleRate = 128; hdr->SPR = 1; hdr->NRec = -1; // unknown struct stat stbuf; if(!stat(hdr->FileName, &stbuf)) { if (!hdr->FILE.COMPRESSION) hdr->NRec = (stbuf.st_size-hdr->HeadLen)/(2*hdr->NS); else fprintf(stdout,"Compressed Sigma file (%s) is currently not supported. Uncompress file and try again.", hdr->FileName); } if (VERBOSE_LEVEL>7) fprintf(stdout,"333 SIGMA NS=%i/0x%x, Fs=%f, SPR=%i, NRec=%i\n",hdr->NS,hdr->NS, hdr->SampleRate,hdr->SPR,(int)hdr->NRec); // define variable header pos = 148; hdr->FLAG.UCAL = 1; hdr->FLAG.OVERFLOWDETECTION = 0; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); uint16_t p[] = {4,19,19,19,19+2,19,19,19,19+8,9,11}; // difference of positions of string elements within variable header for (k=1; k < sizeof(p)/sizeof(p[0]); k++) p[k] += p[k-1]; // relative position double *fs = (double*) malloc(hdr->NS * sizeof(double)); double minFs = INFINITY; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; pos = 148 + k*203; // ch = lei16p(hdr->AS.Header+pos); double val; hc->GDFTYP = 3; hc->OnOff = 1; hc->SPR = 1; hc->DigMax = (int16_t)0x7fff; hc->DigMin = (int16_t)0x8000; hc->PhysMax = hc->DigMax; hc->PhysMin = hc->DigMin; // hc->Cal = 1.0; hc->Off = 0.0; hc->HighPass = NAN; hc->LowPass = NAN; hc->Notch = *(int16_t*)(hdr->AS.Header+pos+2) ? 1.0 : 0.0; hc->Impedance = INFINITY; hc->fZ = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; hc->LeadIdCode = 0; hc->Transducer[0] = 0; hc->Label[0] = 0; unsigned k1; for (k1 = sizeof(p)/sizeof(p[0]); k1>0; ) { k1--; len = hdr->AS.Header[pos+p[k1]]; hdr->AS.Header[pos+p[k1]+len+1] = 0; val = atof((char*)(hdr->AS.Header+pos+p[k1]+1)); switch (k1) { case 0: // Abtastrate fs[k] = val; if (hdr->SampleRate < fs[k]) hdr->SampleRate=fs[k]; if (minFs > fs[k]) minFs=fs[k]; break; case 1: // obere Grenzfrequenz hc->LowPass = val; break; case 2: // untere Grenzfrequenz hc->HighPass = val; break; case 6: // Electrodenimpedanz hc->Impedance = val; break; case 7: // Sensitivitaet Verstaerker hc->Cal = val; break; case 8: // Elektrodenbezeichnung strcpy(hc->Label, (char*)(hdr->AS.Header+pos+p[k1]+1)); break; case 10: // Masseinheit hc->PhysDimCode = PhysDimCode((char*)(hdr->AS.Header+pos+p[k1]+1)); break; case 11: // strcpy(hc->Transducer, (char*)(hdr->AS.Header+pos+p[k1]+1)); break; case 3: // gerfac ? case 4: // Kalibriergroesse case 5: // Kanaldimension case 9: // Bezeichnung der Referenzelektrode {}; } } hc->Off = lei16p(hdr->AS.Header+pos+ 80) * hc->Cal; hc->XYZ[0] = lei32p(hdr->AS.Header+pos+158); hc->XYZ[1] = lei32p(hdr->AS.Header+pos+162); hc->XYZ[2] = lei32p(hdr->AS.Header+pos+166); } #undef line hdr->SPR = (typeof(hdr->SPR))round(hdr->SampleRate/minFs); for (k=0,hdr->AS.bpb=0; kNS; k++) { hdr->CHANNEL[k].SPR = (typeof(hdr->SPR))round(fs[k]/minFs); hdr->CHANNEL[k].bi = hdr->AS.bpb; hdr->AS.bpb += hdr->CHANNEL[k].SPR*2; } free(fs); } /******* end of Sigma PLpro ********/ else if (hdr->TYPE==SQLite) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...)\n", __FILE__,__LINE__,__func__); if (sopen_sqlite(hdr)) return(hdr); } /* else if (hdr->TYPE==SMA) { char *delim = "=\x0a\x0d\x22"; } */ else if (hdr->TYPE==SND) { /* read file */ // hdr->FLAG.SWAP = (__BYTE_ORDER == __LITTLE_ENDIAN); hdr->FILE.LittleEndian = 0; hdr->HeadLen = beu32p(hdr->AS.Header+4); size_t datlen = beu32p(hdr->AS.Header+8); uint32_t filetype = beu32p(hdr->AS.Header+12); hdr->SampleRate = (double)beu32p(hdr->AS.Header+16); hdr->NS = beu32p(hdr->AS.Header+20); if (countHeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); count += ifread(hdr->AS.Header+count,1,hdr->HeadLen-count,hdr); } else { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); ifseek(hdr,hdr->HeadLen,SEEK_SET); } const uint16_t SND_GDFTYP[] = {0,2,1,3,255+24,5,16,17,0,0,0,2,4,511+25,6}; uint16_t gdftyp = SND_GDFTYP[filetype]; hdr->AS.bpb = hdr->NS * GDFTYP_BITS[gdftyp]>>3; double Cal = 1; if ((filetype>1) && (filetype<6)) Cal = ldexp(1,-GDFTYP_BITS[gdftyp]); hdr->NRec = datlen/hdr->AS.bpb; hdr->SPR = 1; hdr->FLAG.OVERFLOWDETECTION = 0; // automated overflow and saturation detection not supported hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); double digmax = ldexp(1,GDFTYP_BITS[gdftyp]); for (k=0,hdr->AS.bpb=0; k < hdr->NS; k++) { CHANNEL_TYPE* hc = hdr->CHANNEL+k; hc->OnOff = 1; hc->GDFTYP = gdftyp; hc->SPR = 1; hc->Cal = Cal; hc->Off = 0.0; hc->Transducer[0] = '\0'; hc->LowPass = -1; hc->HighPass = -1; hc->PhysMax = 1.0; hc->PhysMin = -1.0; hc->DigMax = digmax; hc->DigMin = -digmax; hc->LeadIdCode = 0; hc->PhysDimCode = 0; hc->Label[0] = 0; hc->bi = hdr->AS.bpb; hdr->AS.bpb += GDFTYP_BITS[gdftyp]>>3; } } #if defined(WITH_TDMS) else if (hdr->TYPE==TDMS) { sopen_tdms_read(hdr); } #endif else if (hdr->TYPE==TMS32) { hdr->VERSION = leu16p(hdr->AS.Header+31); hdr->SampleRate = leu16p(hdr->AS.Header+114); size_t NS = leu16p(hdr->AS.Header+119); hdr->HeadLen = 217 + NS*136; if (hdr->HeadLen > count) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen); count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); } else ifseek(hdr,hdr->HeadLen,SEEK_SET); // size_t filesize = lei32p(hdr->AS.Header+121); tm_time.tm_year = lei16p(hdr->AS.Header+129)-1900; tm_time.tm_mon = lei16p(hdr->AS.Header+131)-1; tm_time.tm_mday = lei16p(hdr->AS.Header+133); tm_time.tm_hour = lei16p(hdr->AS.Header+137); tm_time.tm_min = lei16p(hdr->AS.Header+139); tm_time.tm_sec = lei16p(hdr->AS.Header+141); tm_time.tm_isdst= -1; hdr->T0 = tm_time2gdf_time(&tm_time); hdr->NRec = lei32p(hdr->AS.Header+143); hdr->SPR = leu16p(hdr->AS.Header+147); //hdr->AS.bpb = leu16p(hdr->AS.Header+149)+86; hdr->AS.bpb = 86; hdr->FLAG.OVERFLOWDETECTION = 0; hdr->CHANNEL = (CHANNEL_TYPE*)calloc(NS, sizeof(CHANNEL_TYPE)); size_t aux = 0; for (k=0; k < NS; k += 1) { CHANNEL_TYPE* hc = hdr->CHANNEL+aux; uint8_t StringLength = hdr->AS.Header[217+k*136]; char *SignalName = (char*)(hdr->AS.Header+218+k*136); if (!strncmp(SignalName, "(Lo) ", 5)) { strncpy(hc->Label,SignalName+5,StringLength-5); hc->GDFTYP = 16; aux += 1; hc->Label[StringLength-5] = 0; hc->bi = hdr->AS.bpb; } else if (!strncmp(SignalName, "(Hi) ", 5)) { } else { strncpy(hc->Label, SignalName, StringLength); hc->GDFTYP = 3; aux += 1; hc->Label[StringLength] = 0; hc->bi = hdr->AS.bpb; } StringLength = hdr->AS.Header[45+217+k*136]; char tmp[256]; strncpy(tmp, (char*)(hdr->AS.Header+46+217+k*136), StringLength); tmp[StringLength] = 0; hc->PhysDimCode = PhysDimCode(tmp); hc->PhysMin = lef32p(hdr->AS.Header+56+217+k*136); hc->PhysMax = lef32p(hdr->AS.Header+60+217+k*136); hc->DigMin = lef32p(hdr->AS.Header+64+217+k*136); hc->DigMax = lef32p(hdr->AS.Header+68+217+k*136); hc->Cal = (hc->PhysMax-hc->PhysMin)/(hc->DigMax-hc->DigMin); hc->Off = hc->PhysMin - hc->Cal * hc->DigMin; hc->OnOff = 1; hc->SPR = hdr->SPR; hc->Transducer[0] = '\0'; hc->LowPass = -1; hc->HighPass = -1; hc->LeadIdCode = 0; //hdr->AS.bpb += 2 * hc->SPR; hdr->AS.bpb += hc->SPR * (GDFTYP_BITS[hc->GDFTYP]>>3); if (VERBOSE_LEVEL>7) fprintf(stdout,"k=%i\tLabel=%s [%s]\tNS=%i\tpos=%i\n",(int)k,SignalName,tmp,(int)NS,(int)iftell(hdr)); } hdr->NS = aux; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL,hdr->NS*sizeof(CHANNEL_TYPE)); } else if (hdr->TYPE==TMSiLOG) { /* read header docu says HeadLen = 141+275*NS, but our example has 135+277*NS; */ while (!ifeof(hdr)) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,count*2+1); count += ifread(hdr->AS.Header + count, 1, count, hdr); } ifclose(hdr); hdr->AS.Header[count] = 0; hdr->NS = 0; hdr->SPR = 1; hdr->NRec = 1; double duration = 0.0; uint16_t gdftyp = 0; char *line = strstr(Header1,"Signals="); if (line) { char tmp[5]; strncpy(tmp,line+8,5); hdr->NS = atoi(tmp); } if (!hdr->NS) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "TMSiLOG: multiple data files not supported"); } hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); char *filename = NULL; line = strtok(Header1,"\x0d\x0a"); while (line) { char *val = strchr(line,'='); val[0] = 0; val++; if (!strcmp(line,"FileId")) {} else if (!strcmp(line,"Version")) hdr->VERSION = atoi(val); else if (!strcmp(line,"DateTime")) { struct tm t; sscanf(val,"%04d/%02d/%02d-%02d:%02d:%02d",&t.tm_year,&t.tm_mon,&t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); t.tm_year -= 1900; t.tm_mon--; t.tm_isdst =-1; } else if (!strcmp(line,"Format")) { if (!strcmp(val,"Float32")) gdftyp = 16; else if (!strcmp(val,"Int32 ")) gdftyp = 5; else if (!strcmp(val,"Int16 ")) gdftyp = 3; else if (!strcmp(val,"Ascii ")) gdftyp = 0xfffe; else gdftyp = 0xffff; } else if (!strcmp(line,"Length")) { duration = atof(val); } else if (!strcmp(line,"Signals")) { hdr->NS = atoi(val); } else if (!strncmp(line,"Signal",6)) { char tmp[5]; strncpy(tmp,line+6,4); size_t ch = atoi(tmp)-1; char *field = line+11; if (!strcmp(field,"Name")) strncpy(hdr->CHANNEL[ch].Label,val,MAX_LENGTH_LABEL); else if (!strcmp(field,"UnitName")) hdr->CHANNEL[ch].PhysDimCode=PhysDimCode(val); else if (!strcmp(field,"Resolution")) hdr->CHANNEL[ch].Cal=atof(val); else if (!strcmp(field,"StoreRate")) { hdr->NRec = (nrec_t)atof(val)*duration; hdr->CHANNEL[ch].SPR = 1; // hdr->CHANNEL[ch].SPR=atof(val)*duration; //hdr->SPR = lcm(hdr->SPR,hdr->CHANNEL[ch].SPR); } else if (!strcmp(field,"File")) { if (!filename) filename = val; else if (strcmp(val, filename)) { fprintf(stdout,"<%s><%s>",val,filename); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "TMSiLOG: multiple data files not supported"); } } else if (!strcmp(field,"Index")) {} else fprintf(stdout,"TMSi Signal%04i.%s = <%s>\n",(int)ch,field,val); } else fprintf(stdout,"TMSi %s = <%s>\n",line,val); line = strtok(NULL,"\x0d\x0a"); } hdr->SampleRate = hdr->SPR*hdr->NRec/duration; hdr->NRec *= hdr->SPR; hdr->SPR = 1; char *fullfilename = (char*)malloc(strlen(hdr->FileName)+strlen(filename)+1); if (!filename) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "TMSiLOG: data file not specified"); } else if (strrchr(hdr->FileName,FILESEP)) { strcpy(fullfilename,hdr->FileName); strcpy(strrchr(fullfilename,FILESEP)+1,filename); } else { strcpy(fullfilename,filename); } filename = NULL; // filename had a pointer to hdr->AS.Header; could be released here if (gdftyp < 1000) { FILE *fid = fopen(fullfilename,"rb"); if (!fid) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "TMSiLOG: data file not found"); } else { int16_t h[3]; size_t c = fread(h, 2, 3, fid); if (h[2]==16) h[2] = 3; else if (h[2]==32) h[2] = 5; else if (h[2]==288) h[2] = 16; else h[2] = 0xffff; // this triggers the error trap if ( (c<2) || (h[0] != hdr->NS) || (((double)h[1]) != hdr->SampleRate) || (h[2] != gdftyp) ) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "TMSiLOG: Binary file corrupted"); } else { size_t sz = (size_t)hdr->NS*hdr->SPR*hdr->NRec*(GDFTYP_BITS[gdftyp]>>3); hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata,sz); c = fread(hdr->AS.rawdata, hdr->NRec, hdr->SPR*hdr->NS*GDFTYP_BITS[gdftyp]>>3, fid); if (c < sz) hdr->NRec = c; } fclose(fid); } } else if (gdftyp==0xfffe) { // double Fs; gdftyp = 17; // ascii is converted to double FILE *fid = fopen(fullfilename,"rt"); if (!fid) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "TMSiLOG: data file not found"); } else { size_t sz = (hdr->NS+1)*24; char *line = (char*) malloc(sz); // read and ignore (i.e. skip) 3 lines int c = 3; while (c>0) { if (fgetc(fid)=='\n') { c--; int ch = fgetc(fid); // skip '\r' if (ch=='\r') ungetc(ch,fid); } } // TODO: sanity checks if (0) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "TMSiLOG: Binary file corrupted"); } else { // hdr->FLAG.SWAP = 0; // no swaping required typeof(hdr->NS) k2; size_t k; hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); size_t sz = (size_t)hdr->NS * hdr->SPR * hdr->NRec * GDFTYP_BITS[gdftyp]>>3; hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata,sz); for (k=0; k < (size_t)hdr->SPR*hdr->NRec; k++) if (fgets(line,sz,fid)) { char *next; strtoul(line, &next, 10); // skip index entry for (k2=0;k2NS;k2++) *(double*)(hdr->AS.rawdata+(k*hdr->NS+k2)*sizeof(double)) = strtod(next,&next); } else { for (k2=0;k2NS;k2++) *(double*)(hdr->AS.rawdata+(k*hdr->NS+k2)*sizeof(double)) = NAN; } } free(line); fclose(fid); } } free(fullfilename); hdr->AS.length = hdr->NRec; if (VERBOSE_LEVEL>8) fprintf(stdout,"TMSi [149] \n"); hdr->AS.bpb = 0; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (VERBOSE_LEVEL>8) fprintf(stdout,"TMSi [151] %i\n",(int)k); hc->GDFTYP = gdftyp; if (gdftyp==3) { hc->DigMax = (double)(int16_t)0x7fff; hc->DigMin = (double)(int16_t)0x8000; } else if (gdftyp==5) { hc->DigMax = (double)(int32_t)0x7fffffff; hc->DigMin = (double)(int32_t)0x80000000; } else { hc->DigMax = 1.0; hc->DigMin = 0.0; hdr->FLAG.OVERFLOWDETECTION = 0; // no overflow detection } hc->PhysMax = hc->DigMax * hc->Cal; hc->PhysMin = hc->DigMin * hc->Cal; hc->LeadIdCode = 0; hc->Transducer[0] = 0; hc->SPR = 1; // one sample per block hc->OnOff = 1; hc->HighPass = NAN; hc->LowPass = NAN; hc->Notch = NAN; hc->Impedance = INFINITY; hc->fZ = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; hc->bi = hdr->AS.bpb; hdr->AS.bpb += GDFTYP_BITS[gdftyp]>>3; } } else if (hdr->TYPE==AIFF) { // hdr->FLAG.SWAP = (__BYTE_ORDER == __LITTLE_ENDIAN); hdr->FILE.LittleEndian = 0; uint8_t *tag; uint32_t tagsize; //uint16_t gdftyp; size_t pos; tagsize = beu32p(hdr->AS.Header+4); tagsize += tagsize & 0x0001; pos = 12; tag = hdr->AS.Header+pos; while (1) { tagsize = beu32p(hdr->AS.Header+pos+4); tagsize += tagsize & 0x0001; if (!strncmp((char*)tag,"COMM",4)) { } else if (!strncmp((char*)tag,"DATA",4)) { } pos += tagsize; tag = hdr->AS.Header+pos; } /// TODO, FIXME } #if defined(WITH_WAV) || defined(WITH_AVI) || defined(WITH_RIFF) else if ((hdr->TYPE==WAV)||(hdr->TYPE==AVI)||(hdr->TYPE==RIFF)) { // hdr->FLAG.SWAP = (__BYTE_ORDER == __BIG_ENDIAN); hdr->FILE.LittleEndian = 1; uint8_t *tag; uint32_t tagsize; uint16_t gdftyp; uint16_t format=0, bits = 0; double Cal=1.0, Off=0.0; size_t pos; tagsize = leu32p(hdr->AS.Header+4); tagsize += tagsize & 0x0001; pos = 12; tag = hdr->AS.Header+pos; while (1) { tagsize = leu32p(hdr->AS.Header+pos+4); tagsize += tagsize & 0x0001; if (!strncmp((char*)tag,"fmt ",4)) { format = leu16p(hdr->AS.Header+pos+4); hdr->NS = leu16p(hdr->AS.Header+pos+4+2); hdr->SampleRate = (double)leu32p(hdr->AS.Header+pos+4+4); if (format==1) { bits = leu16p(hdr->AS.Header+pos+4+14); Cal = ldexp(1,-8*(bits/8 + ((bits%8) > 0))); if (bits <= 8) { gdftyp = 2; Off = 0.5; } else if (bits <= 16) gdftyp = 3; else if (bits <= 24) gdftyp = 255+24; else if (bits <= 32) gdftyp = 5; } else fprintf(stdout,"Warning (WAV): format not supported.\n"); } else if (!strncmp((char*)tag,"data",4)) { if (format==1) { hdr->AS.bpb = hdr->NS * ((bits/8) + ((bits%8)>0)); hdr->SPR = tagsize/hdr->AS.bpb; } } pos += tagsize; tag = hdr->AS.Header+pos; /// TODO, FIXME } } #endif else if (hdr->TYPE==ASCII_IBI) { hdr->NS = 0; hdr->NRec = 0; hdr->SPR = 1; hdr->AS.bpb = 0; ifseek(hdr,0,SEEK_SET); char line[81]; ifgets(line,80,hdr); size_t N = 0; hdr->EVENT.N = 0; while (!ifeof(hdr) && strlen(line)) { if (isdigit(line[0])) { struct tm t; int ms,rri; char *desc = NULL; #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L sscanf(line,"%02u-%02u-%02u %02u:%02u:%02u %03u %as %u", &t.tm_mday, &t.tm_mon, &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec, &ms, &desc, &rri); #else sscanf(line,"%02u-%02u-%02u %02u:%02u:%02u %03u %ms %u", &t.tm_mday, &t.tm_mon, &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec, &ms, &desc, &rri); #endif if (t.tm_year < 1970) t.tm_year += 100; t.tm_mon--; t.tm_isdst = -1; if (N+1 >= hdr->EVENT.N) { hdr->EVENT.N += max(4096,hdr->EVENT.N); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS, hdr->EVENT.N*sizeof(*hdr->EVENT.POS) ); hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP, hdr->EVENT.N*sizeof(*hdr->EVENT.TYP) ); } if (N==0) { hdr->T0 = (gdf_time)(tm_time2gdf_time(&t) + ldexp((ms-rri)/(24*3600*1e3),32)); hdr->EVENT.POS[0] = 0; hdr->EVENT.TYP[0] = 0x0501; hdr->EVENT.POS[1] = rri; hdr->EVENT.TYP[1] = 0x0501; N = 1; } else { hdr->EVENT.POS[N] = hdr->EVENT.POS[N-1] + rri; } if (!strcmp(desc,"IBI")) hdr->EVENT.TYP[N] = 0x0501; else FreeTextEvent(hdr,N,desc); ++N; if (desc) free(desc); } else { strtok(line,":"); char *v = strtok(NULL,":"); if (!strncmp(line,"File version",12)) hdr->VERSION = atof(v); else if (!hdr->FLAG.ANONYMOUS && !strncmp(line,"File version",12)) strncpy(hdr->Patient.Id,v,MAX_LENGTH_PID); } ifgets(line,80,hdr); } ifclose(hdr); hdr->EVENT.N = N; hdr->SampleRate = 1000.0; hdr->EVENT.SampleRate = 1000.0; hdr->TYPE = EVENT; hdr->data.block = NULL; hdr->data.size[0] = 0; hdr->data.size[1] = 0; } #if defined(WITH_DICOM) || defined(WITH_GDCM) || defined(WITH_DCMTK) else if (hdr->TYPE==DICOM) { fprintf(stderr,"DICOM support is very (!!!) experimental!\n"); hdr->HeadLen = count; sopen_dicom_read(hdr); return(hdr); } #endif else if (hdr->TYPE==HL7aECG || hdr->TYPE==XML) { sopen_HL7aECG_read(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"[181] #%i\n",hdr->NS); if (hdr->AS.B4C_ERRNUM) return(hdr); // hdr->FLAG.SWAP = 0; hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); // no swapping hdr->AS.length = hdr->NRec; } #ifdef WITH_MICROMED else if (hdr->TYPE==TRC) { sopen_TRC_read(hdr); } #endif else if (hdr->TYPE==UNIPRO) { sopen_unipro_read(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"[181] #%i\n",hdr->NS); if (hdr->AS.B4C_ERRNUM) return(hdr); // hdr->FLAG.SWAP = 0; } else if (hdr->TYPE==WCP) { fprintf(stderr,"%s (line %i) %s: WARNING WCP support is experimental!\n", __FILE__,__LINE__,__func__); const int WCP_HEADER_LENGTH=2048; if (hdr->HeadLen < WCP_HEADER_LENGTH) { hdr->AS.Header = realloc(hdr->AS.Header, WCP_HEADER_LENGTH); hdr->HeadLen += ifread(hdr->AS.Header+hdr->HeadLen, 1, WCP_HEADER_LENGTH - hdr->HeadLen, hdr); } int ADCMAX=0; char *tok = strtok(hdr->AS.Header,"\r\n"); while (tok != NULL) { char *sep = strchr(tok,'='); *sep = 0; char *val = sep+1; char *key = tok; if (!strcmp(key,"VER")) hdr->VERSION=atof(val); else if (!strcmp(key,"RTIME")) { struct tm T; #if !defined(_WIN32) strptime(val,"%d/%m/%Y %T",&T); #else char *p=val+strlen(val); do p--; while (isdigit(*p) && (p>val)); T.tm_sec = atoi(p+1); *p=0; do p--; while (isdigit(*p) && (p>val)); T.tm_min = atoi(p+1); *p=0; do p--; while (isdigit(*p) && (p>val)); T.tm_hour = atoi(p+1); *p=0; do p--; while (isdigit(*p) && (p>val)); T.tm_year = atoi(p+1); *p=0; do p--; while (isdigit(*p) && (p>val)); T.tm_mon = atoi(p+1); *p=0; do p--; while (isdigit(*p) && (p>val)); T.tm_mday = atoi(p+1); #endif hdr->T0 = tm_time2gdf_time(&T); } else if (!strcmp(key,"NC")) { hdr->NS=atoi(val); hdr->CHANNEL = realloc(hdr->CHANNEL, sizeof(CHANNEL_TYPE)*hdr->NS); } else if (!strcmp(key,"DT")) hdr->SampleRate=1.0/atof(val); else if (!strcmp(key,"ADCMAX")) ADCMAX=atoi(val); else if (!strcmp(key,"NR")) hdr->NRec=atoi(val); else if (key[0]=='Y') { int chan = atoi(key+2); CHANNEL_TYPE *hc = hdr->CHANNEL+chan; switch (key[1]) { case 'U': // YU hc->PhysDimCode = PhysDimCode(val); break; case 'N': // YN strncpy(hc->Label, val, MAX_LENGTH_LABEL+1); break; case 'G': // YG hc->Cal = atof(val); break; } } else { fprintf(stdout,"%s-WCP: %s=%s ignored\n",__func__,key,val); } tok = strtok(NULL,"\r\n"); } uint16_t gdftyp=3; if (ADCMAX==32767) gdftyp = 3; struct stat FileBuf; stat(hdr->FileName,&FileBuf); hdr->SPR = 1; typeof (hdr->NS) k; size_t bpb8=0; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Transducer[0] = 0; hc->GDFTYP = gdftyp; hc->OnOff = 1; hc->bi = bpb8>>3; hc->Off = 0.0; hc->DigMax = ADCMAX; hc->DigMin = -ADCMAX; hc->PhysMax = ADCMAX*hc->Cal; hc->PhysMin = -ADCMAX*hc->Cal; hc->SPR = 1; hc->TOffset = 0.0; hc->LowPass = 0.0; hc->HighPass= 0.0; hc->Notch = 0.0; hc->Impedance = NAN; hc->LeadIdCode = 0; hc->Transducer[0] = 0; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; hc->bufptr = NULL; bpb8 += GDFTYP_BITS[gdftyp]; } hdr->AS.bpb = bpb8>>3; hdr->NRec = (FileBuf.st_size - WCP_HEADER_LENGTH)/hdr->AS.bpb; } else if (hdr->TYPE==WG1) { uint32_t VER = leu32p(hdr->AS.Header); if (VER==0xAFFE5555) { // FIXME: this version is currently not implemented if (count < 5120) { hdr->AS.Header = realloc(hdr->AS.Header, 5120); count += ifread(hdr->AS.Header,5120-count,1,hdr); } hdr->HeadLen = count; hdr->NS = leu16p(hdr->AS.Header+0x40); hdr->NRec = leu16p(hdr->AS.Header+0x110); // total number of blocks /* uint16_t gdftyp = 1; uint16_t startblock = leu16p(hdr->AS.Header+0x112); // FIXME: */ biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "ERROR BIOSIG SOPEN(READ): WG1 0x5555FEAF format is not supported yet"); } else { hdr->SampleRate = 1e6 / leu32p(Header1+16); hdr->NS = leu16p(Header1+22); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "ERROR BIOSIG SOPEN(READ): WG1 data format is not supported yet"); } return(hdr); } #endif //ONLYGDF else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "ERROR BIOSIG SOPEN(READ): data format is not supported"); ifclose(hdr); return(hdr); } hdr->FILE.POS = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"[189] #%i\n",hdr->NS); for (k=0; kNS; k++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"[190] #%i: LeadIdCode=%i\n",(int)k,hdr->CHANNEL[k].LeadIdCode); // set HDR.PhysDim - this part will become obsolete /* k1 = hdr->CHANNEL[k].PhysDimCode; if (k1>0) hdr->CHANNEL[k].PhysDim = PhysDim3(k1); */ // set HDR.PhysDimCode if (hdr->CHANNEL[k].LeadIdCode == 0) { int k1; if (!strncmp(hdr->CHANNEL[k].Label, "MDC_ECG_LEAD_", 13)) { // MDC_ECG_LEAD_* - ignore case // for (k1=0; strcasecmp(hdr->CHANNEL[k].Label+13,LEAD_ID_TABLE[k1]) && LEAD_ID_TABLE[k1][0]; k1++) {}; if (LEAD_ID_TABLE[k1][0]) hdr->CHANNEL[k].LeadIdCode = k1; } else { for (k1=0; strcmp(hdr->CHANNEL[k].Label, LEAD_ID_TABLE[k1]) && LEAD_ID_TABLE[k1][0]; k1++) {}; if (LEAD_ID_TABLE[k1][0]) hdr->CHANNEL[k].LeadIdCode = k1; } } // based on ISO/DIS 11073-91064, EN 1064:2005+A1:2007 (E) if (200 <= hdr->CHANNEL[k].LeadIdCode) strcpy(hdr->CHANNEL[k].Label,"(Manufacturere specific)"); else if (185 <= hdr->CHANNEL[k].LeadIdCode) strcpy(hdr->CHANNEL[k].Label,"(reserved for future expansion)"); else if (hdr->CHANNEL[k].LeadIdCode) strcpy(hdr->CHANNEL[k].Label,LEAD_ID_TABLE[hdr->CHANNEL[k].LeadIdCode]); // Flawfinder: ignore } if (!hdr->EVENT.SampleRate) hdr->EVENT.SampleRate = hdr->SampleRate; /* convert2to4_eventtable(hdr); convert into canonical form if needed */ } else if (!strncmp(MODE,"w",1)) /* --- WRITE --- */ { hdr->FILE.COMPRESSION = hdr->FILE.COMPRESSION || strchr(MODE,'z'); if ( (hdr->Patient.Id==NULL) || !strlen(hdr->Patient.Id)) strcpy(hdr->Patient.Id,"00000000"); #ifndef WITHOUT_NETWORK if (!memcmp(hdr->FileName,"bscs://",7)) { // network: write to server const char *hostname = hdr->FileName+7; char *tmp= (char*)strchr(hostname,'/'); if (tmp != NULL) tmp[0]=0; // ignore terminating slash uint64_t ID=0; int sd, s; sd = bscs_connect(hostname); if (sd<0) { fprintf(stdout,"could not connect to <%s> (err %i)\n",hostname, sd); biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "could not connect to server"); return(hdr); } hdr->FILE.Des = sd; s = bscs_open(sd, &ID); s = bscs_send_hdr(sd,hdr); hdr->FILE.OPEN = 2; fprintf(stdout,"write file to bscs://%s/%016"PRIx64"\n",hostname,ID); return(hdr); } #endif // NS number of channels selected for writing typeof(hdr->NS) NS = 0; { typeof(hdr->NS) k; for (k=0; kNS; k++) if (hdr->CHANNEL[k].OnOff) NS++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"sopen-W ns=%i (%s)\n",NS,GetFileTypeString(hdr->TYPE)); #ifndef ONLYGDF if ((hdr->TYPE==ASCII) || (hdr->TYPE==BIN)) { size_t k; FILE *fid = fopen(hdr->FileName,"w"); hdr->FILE.LittleEndian = 1; fprintf(fid,"#BIOSIG %s\n", (hdr->TYPE==ASCII ? "ASCII" : "BINARY")); fprintf(fid,"# comments start with #\n\n"); fprintf(fid,"Filename\t= %s\t # (this file)\n",hdr->FileName); fprintf(fid,"\n[Header 1]\n"); // fprintf(fid,"\n[Header 1]\nNumberOfChannels\t= %i\n",hdr->NS); //fprintf(fid,"NRec\t= %i\n",hdr->NRec); fprintf(fid,"Duration \t= %f\t# in seconds\n",hdr->SPR*hdr->NRec/hdr->SampleRate); char tmp[40]; snprintf_gdfdatetime(tmp, sizeof(tmp), hdr->T0); fprintf(fid,"Recording.Time \t= %s\t# YYYY-MM-DD hh:mm:ss.uuuuuu\n",tmp); fprintf(fid,"Timezone \t= +%i min\n",hdr->tzmin); fprintf(fid,"Patient.Id \t= %s\n",hdr->Patient.Id); snprintf_gdfdate(tmp, sizeof(tmp), hdr->Patient.Birthday); fprintf(fid,"Patient.Birthday \t= %s\t# YYYY-MM-DD\n",tmp); fprintf(fid,"Patient.Weight \t= %i\t# in [kg]\n",hdr->Patient.Weight); fprintf(fid,"Patient.Height \t= %i\t# in [cm]\n",hdr->Patient.Height); fprintf(fid,"Patient.Gender \t= %i\t# 0:Unknown, 1: Male, 2: Female, 9: Unspecified\n",hdr->Patient.Sex); fprintf(fid,"Patient.Handedness\t= %i\t# 0:Unknown, 1: Right, 2: Left, 3: Equal\n",hdr->Patient.Handedness); fprintf(fid,"Patient.Smoking \t= %i\t# 0:Unknown, 1: NO, 2: YES\n",hdr->Patient.Sex); fprintf(fid,"Patient.AlcoholAbuse\t= %i\t# 0:Unknown, 1: NO, 2: YES\n",hdr->Patient.AlcoholAbuse); fprintf(fid,"Patient.DrugAbuse \t= %i\t# 0:Unknown, 1: NO, 2: YES \n",hdr->Patient.DrugAbuse); fprintf(fid,"Patient.Medication\t= %i\t# 0:Unknown, 1: NO, 2: YES \n",hdr->Patient.Medication); fprintf(fid,"Recording.ID \t= %s\n",hdr->ID.Recording); uint8_t IPv6=0; for (k=4; k<16; k++) IPv6 |= hdr->IPaddr[k]; if (IPv6) fprintf(fid,"Recording.IPaddress \t= %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",hdr->IPaddr[0],hdr->IPaddr[1],hdr->IPaddr[2],hdr->IPaddr[3],hdr->IPaddr[4],hdr->IPaddr[5],hdr->IPaddr[6],hdr->IPaddr[7],hdr->IPaddr[8],hdr->IPaddr[9],hdr->IPaddr[10],hdr->IPaddr[11],hdr->IPaddr[12],hdr->IPaddr[13],hdr->IPaddr[14],hdr->IPaddr[15]); else fprintf(fid,"Recording.IPaddress \t= %u.%u.%u.%u\n",hdr->IPaddr[0],hdr->IPaddr[1],hdr->IPaddr[2],hdr->IPaddr[3]); fprintf(fid,"Recording.Technician\t= %s\n",hdr->ID.Technician); fprintf(fid,"Manufacturer.Name \t= %s\n",hdr->ID.Manufacturer.Name); fprintf(fid,"Manufacturer.Model\t= %s\n",hdr->ID.Manufacturer.Model); fprintf(fid,"Manufacturer.Version\t= %s\n",hdr->ID.Manufacturer.Version); fprintf(fid,"Manufacturer.SerialNumber\t= %s\n",hdr->ID.Manufacturer.SerialNumber); fprintf(fid,"\n[Header 2]\n"); k = strlen(hdr->FileName); char* fn = (char*)calloc(k + 10,1); strcpy(fn, hdr->FileName); char *e = strrchr(fn,'.'); if (e==NULL) { fn[k] = '.'; e = fn+k; } e[1] = (hdr->TYPE == ASCII ? 'a' : 's'); e+=2; for (k=0; kNS; k++) if (hdr->CHANNEL[k].OnOff) { if (hdr->FILE.COMPRESSION) sprintf(e,"%02i_gz",(int)k+1); else sprintf(e,"%02i",(int)k+1); fprintf(fid,"Filename \t= %s\n",fn); fprintf(fid,"Label \t= %s\n",hdr->CHANNEL[k].Label); if (hdr->TYPE==ASCII) fprintf(fid,"GDFTYP \t= ascii\n"); else if (hdr->TYPE==BIN) { const char *gdftyp; switch (hdr->CHANNEL[k].GDFTYP) { case 1: gdftyp="int8"; break; case 2: gdftyp="uint8"; break; case 3: gdftyp="int16"; break; case 4: gdftyp="uint16"; break; case 5: gdftyp="int32"; break; case 6: gdftyp="uint32"; break; case 7: gdftyp="int64"; break; case 8: gdftyp="uint64"; break; case 16: gdftyp="float32"; break; case 17: gdftyp="float64"; break; case 18: gdftyp="float128"; break; case 255+24: gdftyp="bit24"; break; case 511+24: gdftyp="ubit24"; break; case 255+12: gdftyp="bit12"; break; case 511+12: gdftyp="ubit12"; break; default: gdftyp = "unknown"; } fprintf(fid,"GDFTYP \t= %s\n",gdftyp); } fprintf(fid,"Transducer\t= %s\n",hdr->CHANNEL[k].Transducer); fprintf(fid,"PhysicalUnits\t= %s\n",PhysDim3(hdr->CHANNEL[k].PhysDimCode)); fprintf(fid,"PhysDimCode\t= %i\n",hdr->CHANNEL[k].PhysDimCode); fprintf(fid,"DigMax \t= %f\n",hdr->CHANNEL[k].DigMax); fprintf(fid,"DigMin \t= %f\n",hdr->CHANNEL[k].DigMin); fprintf(fid,"PhysMax \t= %g\n",hdr->CHANNEL[k].PhysMax); fprintf(fid,"PhysMin \t= %g\n",hdr->CHANNEL[k].PhysMin); fprintf(fid,"SamplingRate\t= %f\n",hdr->CHANNEL[k].SPR*hdr->SampleRate/hdr->SPR); fprintf(fid,"NumberOfSamples\t= %i\t# 0 indicates a channel with sparse samples\n",(int)(hdr->CHANNEL[k].SPR*hdr->NRec)); fprintf(fid,"HighPassFilter\t= %f\n",hdr->CHANNEL[k].HighPass); fprintf(fid,"LowPassFilter\t= %f\n",hdr->CHANNEL[k].LowPass); fprintf(fid,"NotchFilter\t= %f\n",hdr->CHANNEL[k].Notch); switch (hdr->CHANNEL[k].PhysDimCode & 0xffe0) { case 4256: // Voltage data fprintf(fid,"Impedance\t= %f\n",hdr->CHANNEL[k].Impedance); break; case 4288: // Impedance data fprintf(fid,"freqZ\t= %f\n",hdr->CHANNEL[k].fZ); break; } fprintf(fid,"PositionXYZ\t= %f\t%f\t%f\n",hdr->CHANNEL[k].XYZ[0],hdr->CHANNEL[k].XYZ[1],hdr->CHANNEL[k].XYZ[2]); // fprintf(fid,"OrientationXYZ\t= %f\t%f\t%f\n",hdr->CHANNEL[k].Orientation[0],hdr->CHANNEL[k].Orientation[1],hdr->CHANNEL[k].Orientation[2]); // fprintf(fid,"Area \t= %f\n",hdr->CHANNEL[k].Area); fprintf(fid,"\n"); hdr->CHANNEL[k].SPR *= hdr->NRec; } hdr->SPR *= hdr->NRec; hdr->NRec = 1; fprintf(fid,"[EVENT TABLE]\n"); fprintf(fid,"TYP\tPOS [s]\tDUR [s]\tCHN\tVAL/Desc"); for (k=0; kEVENT.N; k++) { fprintf(fid,"\n0x%04x\t%f\t",hdr->EVENT.TYP[k],hdr->EVENT.POS[k]/hdr->EVENT.SampleRate); // EVENT.POS uses 0-based indexing if (hdr->EVENT.DUR != NULL) { typeof(*hdr->EVENT.DUR) DUR; DUR = (hdr->EVENT.TYP[k]==0x7fff) ? 0 : hdr->EVENT.DUR[k]; fprintf(fid,"%f\t%d\t", DUR/hdr->EVENT.SampleRate, hdr->EVENT.CHN[k]); } else fprintf(fid,"\t\t"); if (hdr->EVENT.TYP[k] == 0x7fff) { typeof(hdr->NS) chan = hdr->EVENT.CHN[k] - 1; double val = dur2val(hdr->EVENT.DUR[k], hdr->CHANNEL[chan].GDFTYP); val *= hdr->CHANNEL[chan].Cal; val += hdr->CHANNEL[chan].Off; fprintf(fid,"%g\t# sparse sample ", val); // value of sparse samples } else { const char *str = GetEventDescription(hdr,k); if (str) fprintf(fid,"%s",str); } } fclose(fid); free(fn); hdr->FILE.POS = 0; } else if (hdr->TYPE==ATF) { // Write ATF hdr->HeadLen = 0; hdr->FILE.POS = 0; hdr->FILE.FID = fopen(hdr->FileName, "w"); typeof(hdr->NS) k, NS = 1; for (k = 0; k < hdr->NS; k++) { NS += (hdr->CHANNEL[k].OnOff > 0); } hdr->HeadLen += fprintf(hdr->FILE.FID, "ATF\t1.0\n0\t%d", NS); char sep = '\n'; if (getTimeChannelNumber(hdr) == 0) { hdr->HeadLen += fprintf(hdr->FILE.FID, "%c\"Time (ms)\"", sep); sep = '\t'; } for (k = 0; k < hdr->NS; k++) { if (hdr->CHANNEL[k].OnOff) { hdr->HeadLen += fprintf(hdr->FILE.FID, "%c\"%s (%s)\"", sep, hdr->CHANNEL[k].Label, PhysDim3(hdr->CHANNEL[k].PhysDimCode)); sep = '\t'; } } } else if (hdr->TYPE==BrainVision) { if (VERBOSE_LEVEL>8) fprintf(stdout,"BVA-write: [210]\n"); char* tmpfile = (char*)calloc(strlen(hdr->FileName)+6,1); strcpy(tmpfile,hdr->FileName); // Flawfinder: ignore char* ext = strrchr(tmpfile,'.'); if (ext != NULL) strcpy(ext+1,"vhdr"); // Flawfinder: ignore else strcat(tmpfile,".vhdr"); // Flawfinder: ignore if (VERBOSE_LEVEL>8) fprintf(stdout,"BVA-write: [211]\n"); hdr->HeadLen = 0; FILE *fid = fopen(tmpfile,"wb"); fprintf(fid,"Brain Vision Data Exchange Header File Version 1.0\r\n"); fprintf(fid,"; Data created by BioSig4C++\r\n\r\n"); fprintf(fid,"[Common Infos]\r\n"); fprintf(fid,"DataFile=%s\r\n",hdr->FileName); fprintf(fid,"MarkerFile=%s\r\n",strcpy(strrchr(tmpfile,'.')+1,"vhdr")); fprintf(fid,"DataFormat=BINARY\r\n"); fprintf(fid,"; Data orientation: MULTIPLEXED=ch1,pt1, ch2,pt1 ...\r\n"); fprintf(fid,"DataOrientation=MULTIPLEXED\r\n"); hdr->NRec *= hdr->SPR; hdr->SPR = 1; fprintf(fid,"NumberOfChannels=%i\r\n",hdr->NS); fprintf(fid,"; Sampling interval in microseconds\r\n"); fprintf(fid,"SamplingInterval=%f\r\n\r\n",1e6/hdr->SampleRate); if (VERBOSE_LEVEL>8) fprintf(stdout,"BVA-write: [212]\n"); fprintf(fid,"[Binary Infos]\r\nBinaryFormat="); uint16_t gdftyp = 0; typeof(hdr->NS) k; for (k=0; kNS; k++) if (gdftyp < hdr->CHANNEL[k].GDFTYP) gdftyp = hdr->CHANNEL[k].GDFTYP; if (gdftyp<4) { gdftyp = 3; fprintf(fid,"INT_16"); } else { gdftyp = 16; fprintf(fid,"IEEE_FLOAT_32"); } if (VERBOSE_LEVEL>8) fprintf(stdout,"BVA-write: [214] gdftyp=%i NS=%i\n",gdftyp,hdr->NS); hdr->AS.bpb = (size_t)hdr->NS * hdr->SPR * GDFTYP_BITS[gdftyp] >> 3; fprintf(fid,"\r\n\r\n[Channel Infos]\r\n"); fprintf(fid,"; Each entry: Ch=,,\r\n"); fprintf(fid,"; ,,,NS; k++) { if (VERBOSE_LEVEL>8) fprintf(stdout,"BVA-write: [220] %i\n",k); hdr->CHANNEL[k].SPR = hdr->SPR; hdr->CHANNEL[k].GDFTYP = gdftyp; char Label[MAX_LENGTH_LABEL+1]; strcpy(Label,hdr->CHANNEL[k].Label); // Flawfinder: ignore size_t k1; for (k1=0; Label[k1]; k1++) if (Label[k1]==',') Label[k1]=1; fprintf(fid,"Ch%d=%s,,1,%s\r\n",k+1,Label,PhysDim3(hdr->CHANNEL[k].PhysDimCode)); } fprintf(fid,"\r\n\r\n[Coordinates]\r\n"); // fprintf(fid,"; Each entry: Ch=,,\n\r"); fprintf(fid,"; Each entry: Ch=,,\r\n"); for (k=0; kNS; k++) fprintf(fid,"Ch%i=%f,%f,%f\r\n",k+1,hdr->CHANNEL[k].XYZ[0],hdr->CHANNEL[k].XYZ[1],hdr->CHANNEL[k].XYZ[2]); if (VERBOSE_LEVEL>8) fprintf(stdout,"BVA-write: [222]\n"); fprintf(fid,"\r\n\r\n[Comment]\r\n\r\n"); fprintf(fid,"A m p l i f i e r S e t u p\r\n"); fprintf(fid,"============================\r\n"); fprintf(fid,"Number of channels: %i\r\n",hdr->NS); fprintf(fid,"Sampling Rate [Hz]: %f\r\n",hdr->SampleRate); fprintf(fid,"Sampling Interval [µS]: %f\r\n",1e6/hdr->SampleRate); fprintf(fid,"Channels\r\n--------\r\n"); fprintf(fid,"# Name Phys. Chn. Resolution [µV] Low Cutoff [s] High Cutoff [Hz] Notch [Hz]\n\r"); for (k=0; kNS; k++) { fprintf(fid,"\r\n%6i %13s %17i %18f",k+1,hdr->CHANNEL[k].Label,k+1,hdr->CHANNEL[k].Cal); if (hdr->CHANNEL[k].HighPass>0) fprintf(fid," %15f",1/(2*3.141592653589793238462643383279502884197169399375*hdr->CHANNEL[k].HighPass)); else fprintf(fid,"\t-"); if (hdr->CHANNEL[k].LowPass>0) fprintf(fid," %15f",hdr->CHANNEL[k].LowPass); else fprintf(fid,"\t-"); if (hdr->CHANNEL[k].Notch>0) fprintf(fid," %f",hdr->CHANNEL[k].Notch); else fprintf(fid,"\t-"); } fprintf(fid,"\r\n\r\nImpedance [kOhm] :\r\n\r\n"); for (k=0; kNS; k++) if (isnan(hdr->CHANNEL[k].Impedance)) fprintf(fid,"%s:\t\t-\r\n",hdr->CHANNEL[k].Label); else fprintf(fid,"%s:\t\t%f\r\n",hdr->CHANNEL[k].Label,hdr->CHANNEL[k].Impedance); fclose(fid); strcpy(strrchr(tmpfile,'.')+1,"vmrk"); fid = fopen(tmpfile,"wb"); fprintf(fid,"Brain Vision Data Exchange Marker File, Version 1.0\r\n"); fprintf(fid,"; Data created by BioSig4C++\r\n\r\n"); fprintf(fid,"[Common Infos]\r\n"); fprintf(fid,"DataFile=%s\r\n\r\n",hdr->FileName); fprintf(fid,"[Marker Infos]\r\n\r\n"); fprintf(fid,"; Each entry: Mk=,,,\r\n"); fprintf(fid,"; , \r\n"); fprintf(fid,"; Fields are delimited by commas, some fields might be omitted (empty).\r\n"); fprintf(fid,"; Commas in type or description text are coded as \"\\1\".\r\n"); struct tm *T0 = gdf_time2tm_time(hdr->T0); uint32_t us = (hdr->T0*24*3600 - floor(hdr->T0*24*3600))*1e6; fprintf(fid,"Mk1=New Segment,,1,1,0,%04u%02u%02u%02u%02u%02u%06u",T0->tm_year+1900,T0->tm_mon+1,T0->tm_mday,T0->tm_hour,T0->tm_min,T0->tm_sec,us); // 20081002150147124211 if ((hdr->EVENT.DUR==NULL) && (hdr->EVENT.CHN==NULL)) for (k=0; kEVENT.N; k++) { fprintf(fid,"\r\nMk%i=,0x%04x,%u,1,0",k+2,hdr->EVENT.TYP[k],hdr->EVENT.POS[k]+1); // convert to 1-based indexing } else for (k=0; kEVENT.N; k++) { fprintf(fid,"\r\nMk%i=,0x%04x,%u,%u,%u",k+2,hdr->EVENT.TYP[k],hdr->EVENT.POS[k]+1,hdr->EVENT.DUR[k],hdr->EVENT.CHN[k]); // convert EVENT.POS to 1-based indexing } fclose(fid); free(tmpfile); if (VERBOSE_LEVEL>8) fprintf(stdout,"BVA-write: [290] %s %s\n",tmpfile,hdr->FileName); } else if (hdr->TYPE==CFWB) { hdr->HeadLen = 68 + NS*96; hdr->AS.Header = (uint8_t*)malloc(hdr->HeadLen); uint8_t* Header2 = hdr->AS.Header+68; memset(hdr->AS.Header,0,hdr->HeadLen); memcpy(hdr->AS.Header,"CFWB\1\0\0\0",8); lef64a(1/hdr->SampleRate, hdr->AS.Header+8); lef64a(0.0, hdr->AS.Header+44); // pretrigger time leu32a(NS, hdr->AS.Header+52); hdr->NRec *= hdr->SPR; hdr->SPR = 1; leu32a(hdr->NRec, hdr->AS.Header+56); // number of samples lei32a(0, hdr->AS.Header+60); // 1: time channel int32_t gdftyp = 3; // 1:double, 2:float, 3: int16; see CFWB_GDFTYP too. typeof(hdr->NS) k,k2; for (k=0; kNS; k++) if (hdr->CHANNEL[k].OnOff) { /* if int16 is not sufficient, use float or double */ if (hdr->CHANNEL[k].GDFTYP>16) gdftyp = min(gdftyp,1); // double else if (hdr->CHANNEL[k].GDFTYP>3) gdftyp = min(gdftyp,2); // float } lei32a(gdftyp, hdr->AS.Header+64); // 1: double, 2: float, 3:short for (k=0,k2=0; kNS; k++) if (hdr->CHANNEL[k].OnOff) { hdr->CHANNEL[k].SPR = 1; hdr->CHANNEL[k].GDFTYP = CFWB_GDFTYP[gdftyp-1]; const char *tmpstr; if (hdr->CHANNEL[k].LeadIdCode) tmpstr = LEAD_ID_TABLE[hdr->CHANNEL[k].LeadIdCode]; else tmpstr = hdr->CHANNEL[k].Label; size_t len = strlen(tmpstr); memcpy(Header2+96*k2, tmpstr, min(len,32)); tmpstr = PhysDim3(hdr->CHANNEL[k].PhysDimCode); if (tmpstr != NULL) { len = strlen(tmpstr)+1; memcpy(Header2+96*k2+32, tmpstr, min(len,32)); } lef64a(hdr->CHANNEL[k].Cal, Header2+96*k2+64); lef64a(hdr->CHANNEL[k].Off, Header2+96*k2+72); lef64a(hdr->CHANNEL[k].PhysMax, Header2+96*k2+80); lef64a(hdr->CHANNEL[k].PhysMin, Header2+96*k2+88); k2++; } } else #endif //ONLYGDF if ((hdr->TYPE==GDF) || (hdr->TYPE==GDF1)) { /* use of GDF1 is deprecated, instead hdr->TYPE=GDF and hdr->VERSION=1.25 should be used. a test and a warning is about this is implemented within struct2gdfbin */ struct2gdfbin(hdr); size_t bpb8 = 0; typeof(hdr->NS) k; for (k=0, hdr->AS.bpb=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->bi8 = bpb8; hc->bi = bpb8>>3; if (hc->OnOff) bpb8 += (GDFTYP_BITS[hc->GDFTYP] * hc->SPR); } hdr->AS.bpb8 = bpb8; hdr->AS.bpb = bpb8>>3; if (bpb8 & 0x07) { // each block must use whole number of bytes hdr->AS.bpb++; hdr->AS.bpb8 = hdr->AS.bpb<<3; } if (VERBOSE_LEVEL>7) fprintf(stdout,"GDFw h3\n"); } #ifndef ONLYGDF else if ((hdr->TYPE==EDF) || (hdr->TYPE==BDF)) { hdr->HeadLen = (NS+1)*256; hdr->AS.Header = (uint8_t*)malloc(hdr->HeadLen); char* Header2 = (char*)hdr->AS.Header+256; memset(Header1,' ',hdr->HeadLen); if (hdr->TYPE==BDF) { Header1[0] = 255; memcpy(Header1+1,"BIOSEMI",7); } else { Header1[0] = '0'; } char tmp[81]; if (hdr->Patient.Birthday>1) strfgdftime(tmp,81,"%02d-%b-%04Y",hdr->Patient.Birthday); else strcpy(tmp,"X"); if (strlen(hdr->Patient.Id) > 0) { size_t k; for (k=0; hdr->Patient.Id[k]; k++) if (isspace(hdr->Patient.Id[k])) hdr->Patient.Id[k] = '_'; } char cmd[256]; if (!hdr->FLAG.ANONYMOUS) snprintf(cmd,MAX_LENGTH_PID+1,"%s %c %s %s",hdr->Patient.Id,GENDER[hdr->Patient.Sex],tmp,hdr->Patient.Name); else snprintf(cmd,MAX_LENGTH_PID+1,"%s %c %s X",hdr->Patient.Id,GENDER[hdr->Patient.Sex],tmp); memcpy(Header1+8, cmd, strlen(cmd)); if (hdr->T0 > 1) strfgdftime(tmp,81,"%d-%b-%Y", hdr->T0); else strcpy(tmp,"X"); char *tmpstr = hdr->ID.Technician; if (!tmpstr || !strlen(tmp)) tmpstr = "X"; size_t len = snprintf(cmd,sizeof(cmd),"Startdate %s X %s ", tmp, tmpstr); memcpy(Header1+88, cmd, len); memcpy(Header1+88+len, &hdr->ID.Equipment, 8); strfgdftime(tmp,81,"%d.%m.%y%H.%M.%S",hdr->T0); memcpy(Header1+168, tmp, 16); len = sprintf(tmp,"%i",hdr->HeadLen); if (len>8) fprintf(stderr,"Warning: HeaderLength is (%s) too long (%i>8).\n",tmp,(int)len); memcpy(Header1+184, tmp, len); memcpy(Header1+192, "EDF+C ", 5); len = sprintf(tmp,"%u",(int)hdr->NRec); if (len>8) fprintf(stderr,"Warning: NRec is (%s) too long (%i>8).\n",tmp,(int)len); memcpy(Header1+236, tmp, len); len = sprintf(tmp,"%f",hdr->SPR/hdr->SampleRate); if (len>8) fprintf(stderr,"Warning: Duration is (%s) too long (%i>8).\n",tmp,(int)len); memcpy(Header1+244, tmp, len); len = sprintf(tmp,"%i",NS); if (len>4) fprintf(stderr,"Warning: NS is (%s) too long (%i>4).\n",tmp,(int)len); memcpy(Header1+252, tmp, len); typeof(hdr->NS) k,k2; for (k=0,k2=0; kNS; k++) if (hdr->CHANNEL[k].OnOff) { const char *tmpstr; if (hdr->CHANNEL[k].LeadIdCode) tmpstr = LEAD_ID_TABLE[hdr->CHANNEL[k].LeadIdCode]; else tmpstr = hdr->CHANNEL[k].Label; len = strlen(tmpstr); if (len>16) //fprintf(stderr,"Warning: Label (%s) of channel %i is to long.\n",hdr->CHANNEL[k].Label,k); fprintf(stderr,"Warning: Label of channel %i,%i is too long (%i>16).\n",k,k2, (int)len); memcpy(Header2+16*k2,tmpstr,min(len,16)); len = strlen(hdr->CHANNEL[k].Transducer); if (len>80) fprintf(stderr,"Warning: Transducer of channel %i,%i is too long (%i>80).\n",k,k2, (int)len); memcpy(Header2+80*k2 + 16*NS,hdr->CHANNEL[k].Transducer,min(len,80)); tmpstr = PhysDim3(hdr->CHANNEL[k].PhysDimCode); if (tmpstr) { len = strlen(tmpstr); if (len>8) fprintf(stderr,"Warning: Physical Dimension (%s) of channel %i is too long (%i>8).\n",tmpstr,k,(int)len); memcpy(Header2 + 8*k2 + 96*NS, tmpstr, min(len,8)); } if (ftoa8(tmp,hdr->CHANNEL[k].PhysMin)) fprintf(stderr,"Warning: PhysMin (%f)(%s) of channel %i does not fit into 8 bytes of EDF header.\n",hdr->CHANNEL[k].PhysMin,tmp,k); memcpy(Header2 + 8*k2 + 104*NS, tmp, strlen(tmp)); if (ftoa8(tmp,hdr->CHANNEL[k].PhysMax)) fprintf(stderr,"Warning: PhysMax (%f)(%s) of channel %i does not fit into 8 bytes of EDF header.\n",hdr->CHANNEL[k].PhysMax,tmp,k); memcpy(Header2 + 8*k2 + 112*NS, tmp, strlen(tmp)); if (ftoa8(tmp,hdr->CHANNEL[k].DigMin)) fprintf(stderr,"Warning: DigMin (%f)(%s) of channel %i does not fit into 8 bytes of EDF header.\n",hdr->CHANNEL[k].DigMin,tmp,k); memcpy(Header2 + 8*k2 + 120*NS, tmp, strlen(tmp)); if (ftoa8(tmp,hdr->CHANNEL[k].DigMax)) fprintf(stderr,"Warning: DigMax (%f)(%s) of channel %i does not fit into 8 bytes of EDF header.\n",hdr->CHANNEL[k].DigMax,tmp,k); memcpy(Header2 + 8*k2 + 128*NS, tmp, strlen(tmp)); if (hdr->CHANNEL[k].Notch>0) len = sprintf(tmp,"HP:%fHz LP:%fHz Notch:%fHz",hdr->CHANNEL[k].HighPass,hdr->CHANNEL[k].LowPass,hdr->CHANNEL[k].Notch); else len = sprintf(tmp,"HP:%fHz LP:%fHz",hdr->CHANNEL[k].HighPass,hdr->CHANNEL[k].LowPass); memcpy(Header2+ 80*k2 + 136*NS,tmp,min(80,len)); len = sprintf(tmp,"%i",hdr->CHANNEL[k].SPR); if (len>8) fprintf(stderr,"Warning: SPR (%s) of channel %i is to long (%i)>8.\n",tmp,k,(int)len); memcpy(Header2+ 8*k2 + 216*NS,tmp,min(8,len)); hdr->CHANNEL[k].GDFTYP = ( (hdr->TYPE != BDF) ? 3 : 255+24); k2++; } } else if (hdr->TYPE==HL7aECG) { sopen_HL7aECG_write(hdr); // hdr->FLAG.SWAP = 0; hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); // no byte-swapping } else if (hdr->TYPE==MFER) { uint8_t tag; size_t len, curPos=0; hdr->HeadLen = 32+128+3*6+3 +80000; hdr->AS.Header = (uint8_t*)malloc(hdr->HeadLen); memset(Header1, ' ', hdr->HeadLen); hdr->FILE.LittleEndian = 0; fprintf(stderr,"Warning SOPEN(MFER): write support for MFER format under construction\n"); /* FIXME & TODO: known issues: Label Sampling Rate HeadLen Encoding of data block */ // tag 64: preamble // Header1[curPos] = 64; // len =32; curPos = 34; strncpy(Header1,"@ MFER ",curPos); // Header1[curPos+1] = len; // curPos = len+2; if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 711]:\n"); // tag 23: Manufacturer tag = 23; Header1[curPos] = tag; { char *str = Header1+curPos+2; strncpy(str, hdr->ID.Manufacturer.Name, MAX_LENGTH_MANUF); size_t l2,l1 = strlen(str); l2 = (hdr->ID.Manufacturer.Model==NULL) ? MAX_LENGTH_MANUF*2 : strlen(hdr->ID.Manufacturer.Model); str[l1++]='^'; if (l1+l2 <= MAX_LENGTH_MANUF) { memcpy(str+l1, hdr->ID.Manufacturer.Model, l2); l1 += l2; } l2 = (hdr->ID.Manufacturer.Version==NULL) ? MAX_LENGTH_MANUF*2 : strlen(hdr->ID.Manufacturer.Version); str[l1++]='^'; if (l1+l2 <= MAX_LENGTH_MANUF) { memcpy(str+l1, hdr->ID.Manufacturer.Version, l2); l1 += l2; } l2 = (hdr->ID.Manufacturer.SerialNumber==NULL) ? MAX_LENGTH_MANUF*2 : strlen(hdr->ID.Manufacturer.SerialNumber); str[l1++]='^'; if (l1+l2 <= MAX_LENGTH_MANUF) { memcpy(str+l1, hdr->ID.Manufacturer.SerialNumber, l2); l1 += l2; } len = min(l1, MAX_LENGTH_MANUF); str[len]=0; } Header1[curPos] = tag; if (len<128) { hdr->AS.Header[curPos+1] = len; curPos += len+2; } else fprintf(stderr,"Warning MFER(W) Tag23 (manufacturer) too long len=%i>128\n",(int)len); if (VERBOSE_LEVEL>8) fprintf(stdout,"Write MFER: tag=%i,len%i,curPos=%i\n",tag,(int)len,(int)curPos); // tag 1: Endianity // use default BigEndianity if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-4]:\n"); // tag 4: SPR tag = 4; len = sizeof(uint32_t); Header1[curPos++] = tag; Header1[curPos++] = len; beu32a(hdr->SPR, hdr->AS.Header+curPos); curPos += len; if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-5]:\n"); // tag 5: NS tag = 5; len = sizeof(uint16_t); Header1[curPos++] = tag; Header1[curPos++] = len; beu16a(hdr->NS, hdr->AS.Header+curPos); curPos += len; if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-6]:\n"); // tag 6: NRec tag = 6; len = sizeof(uint32_t); Header1[curPos++] = tag; Header1[curPos++] = len; beu32a(hdr->NRec, hdr->AS.Header+curPos); curPos += len; if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-8]:\n"); // tag 8: Waveform: unidentified tag = 8; len = sizeof(uint8_t); Header1[curPos++] = tag; Header1[curPos++] = len; *(Header1+curPos) = 0; // unidentified curPos += len; if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-129]:\n"); // tag 129: Patient Name if (!hdr->FLAG.ANONYMOUS) { tag = 129; len = strlen(hdr->Patient.Name); Header1[curPos++] = tag; Header1[curPos++] = len; strcpy(Header1+curPos,hdr->Patient.Name); curPos += len; } // tag 130: Patient Id tag = 130; len = strlen(hdr->Patient.Id); Header1[curPos++] = tag; Header1[curPos++] = len; strcpy(Header1+curPos,hdr->Patient.Id); curPos += len; // tag 131: Patient Age if (hdr->Patient.Birthday>0) { tag = 131; len = 7; struct tm *t = gdf_time2tm_time(hdr->Patient.Birthday); hdr->AS.Header[curPos++] = tag; hdr->AS.Header[curPos++] = len; hdr->AS.Header[curPos] = (uint8_t)((hdr->T0 - hdr->Patient.Birthday)/365.25); double tmpf64 = (hdr->T0 - hdr->Patient.Birthday); tmpf64 -= 365.25*floor(tmpf64/365.25); beu16a((uint16_t)tmpf64, Header1+curPos+1); beu16a(t->tm_year+1900, Header1+curPos+3); hdr->AS.Header[curPos+5] = (t->tm_mon+1); hdr->AS.Header[curPos+6] = (t->tm_mday); curPos += len; } if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-132]:\n"); // tag 132: Patient Sex tag = 132; Header1[curPos] = tag; Header1[curPos+1] = 1; Header1[curPos+2] = hdr->Patient.Sex; curPos += 3; // tag 133: Recording time tag = 133; len = 11; { struct tm *t = gdf_time2tm_time(hdr->T0); hdr->AS.Header[curPos++] = tag; hdr->AS.Header[curPos++] = len; beu16a(t->tm_year+1900, hdr->AS.Header+curPos); hdr->AS.Header[curPos+2] = (uint8_t)(t->tm_mon+1); hdr->AS.Header[curPos+3] = (uint8_t)(t->tm_mday); hdr->AS.Header[curPos+4] = (uint8_t)(t->tm_hour); hdr->AS.Header[curPos+5] = (uint8_t)(t->tm_min); hdr->AS.Header[curPos+6] = (uint8_t)(t->tm_sec); memset(hdr->AS.Header+curPos+7, 0, 4); curPos += len; } // tag 9: LeadId // tag 10: gdftyp // tag 11: SampleRate // tag 12: Cal // tag 13: Off hdr->HeadLen = curPos; // tag 63: channel-specific settings if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-63]:\n"); tag = 63; size_t ch; for (ch=0; chNS; ch++) { if (VERBOSE_LEVEL>8) fprintf(stdout,"[MFER 720-63 #%i/%i %i]:\n",(int)ch,hdr->NS,hdr->CHANNEL[ch].LeadIdCode); // FIXME: this is broken len = 0; Header1[curPos++] = tag; if (ch<128) Header1[curPos++] = ch; else { Header1[curPos++] = (ch >> 7) | 0x80; Header1[curPos++] = (ch && 0x7f); } // tag1 9: LeadId size_t ix = curPos; size_t len1 = 0; Header1[ix++] = 9; if (hdr->CHANNEL[ch].LeadIdCode>0) { hdr->AS.Header[ix++] = 2; leu16a(hdr->CHANNEL[ch].LeadIdCode, hdr->AS.Header+ix); len1 = 2; } else { len1 = strlen(hdr->CHANNEL[ch].Label); Header1[ix++] = len1; strcpy(Header1+ix, hdr->CHANNEL[ch].Label); } // tag1 10: gdftyp // tag1 11: SampleRate // tag1 12: Cal // tag1 13: Off len += len1+ix-curPos; hdr->AS.Header[curPos] = len; curPos += len+curPos; } // tag 30: data } else if (hdr->TYPE==SCP_ECG) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i) %s -> SOPEN_SCP_WRITE v%f\n",__FILE__,__LINE__,__func__,hdr->VERSION); sopen_SCP_write(hdr); if (hdr->AS.B4C_ERRNUM) return(hdr); } #ifdef WITH_TMSiLOG else if (hdr->TYPE==TMSiLOG) { // ###FIXME: writing of TMSi-LOG file is experimental and not completed FILE *fid = fopen(hdr->FileName,"wb"); fprintf(fid,"FileId=TMSi PortiLab sample log file\n\rVersion=0001\n\r",NULL); struct tm *t = gdf_time2tm_time(hdr->T0); fprintf(fid,"DateTime=%04d/02d/02d-02d:02d:02d\n\r",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); fprintf(fid,"Format=Float32\n\rLength=%f\n\rSignals=%04i\n\r",hdr->NRec*hdr->SPR/hdr->SampleRate,hdr->NS); const char* fn = strrchr(hdr->FileName,FILESEP); if (!fn) fn=hdr->FileName; size_t len = strcspn(fn,"."); char* fn2 = (char*)malloc(len+1); strncpy(fn2,fn,len); fn2[len]=0; for (k=0; kNS; k++) { fprintf(fid,"Signal%04d.Name=%s\n\r",k+1,hdr->CHANNEL[k].Label); fprintf(fid,"Signal%04d.UnitName=%s\n\r",k+1,PhysDim3(hdr->CHANNEL[k].PhysDimCode)); fprintf(fid,"Signal%04d.Resolution=%f\n\r",k+1,hdr->CHANNEL[k].Cal); fprintf(fid,"Signal%04d.StoreRate=%f\n\r",k+1,hdr->SampleRate); fprintf(fid,"Signal%04d.File=%s.asc\n\r",k+1,fn2); fprintf(fid,"Signal%04d.Index=%04d\n\r",k+1,k+1); } fprintf(fid,"\n\r\n\r"); fclose(fid); // ###FIXME: this belongs into SWRITE // write data file fn2 = (char*) realloc(fn2, strlen(hdr->FileName)+5); strcpy(fn2,hdr->FileName); // Flawfinder: ignore strcpy(strrchr(fn2,'.'),".asc"); // Flawfinder: ignore // hdr->FileName = fn2; fid = fopen(fn2,"wb"); fprintf(fid,"%d\tHz\n\r\n\rN",hdr->SampleRate); for (k=0; kNS; k++) { fprintf(fid,"\t%s(%s)", hdr->CHANNEL[k].Label, PhysDim3(hdr->CHANNEL[k].PhysDimCode)); } for (k1=0; k1SPR*hdr->NRec; k1++) { fprintf(fid,"\n%i",k1); for (k=0; kNS; k++) { // TODO: Row/Column ordering fprintf(fid,"\t%f",hdr->data.block[]); } } fclose(fid); free(fn2); } #endif // WITH_TMSiLOG #endif //ONLYGDF else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Writing of format not supported"); return(NULL); } if ((hdr->TYPE != ASCII) && (hdr->TYPE != ATF) && (hdr->TYPE != BIN) && (hdr->TYPE != HL7aECG) && (hdr->TYPE != TMSiLOG)){ hdr = ifopen(hdr,"wb"); if (!hdr->FILE.COMPRESSION && (hdr->FILE.FID == NULL) ) { biosigERROR(hdr, B4C_CANNOT_WRITE_FILE, "Unable to open file for writing"); return(NULL); } #ifdef ZLIB_H else if (hdr->FILE.COMPRESSION && (hdr->FILE.gzFID == NULL) ){ biosigERROR(hdr, B4C_CANNOT_WRITE_FILE, "Unable to open file for writing"); return(NULL); } #endif if(hdr->TYPE != SCP_ECG){ ifwrite(Header1, sizeof(char), hdr->HeadLen, hdr); } hdr->FILE.OPEN = 2; hdr->FILE.POS = 0; } size_t bpb8 = 0; #ifndef ONLYGDF if (hdr->TYPE==AINF) { hdr->AS.bpb = 4; bpb8 = 32; } else #endif //ONLYGDF hdr->AS.bpb = 0; typeof(hdr->NS) k; for (k=0, hdr->SPR = 1; k < hdr->NS; k++) { hdr->CHANNEL[k].bi = bpb8>>3; hdr->CHANNEL[k].bi8 = bpb8; if (hdr->CHANNEL[k].OnOff) { bpb8 += (GDFTYP_BITS[hdr->CHANNEL[k].GDFTYP] * hdr->CHANNEL[k].SPR); if (hdr->CHANNEL[k].SPR > 0) // ignore sparse channels hdr->SPR = lcm(hdr->SPR, hdr->CHANNEL[k].SPR); } } hdr->AS.bpb8 = bpb8; hdr->AS.bpb = bpb8>>3; if ((hdr->TYPE==GDF) && (bpb8 & 0x07)) { // each block must use whole number of bytes hdr->AS.bpb++; hdr->AS.bpb8 = hdr->AS.bpb<<3; } } // end of branch "write" #ifndef ANDROID if (VERBOSE_LEVEL > 7) { //There is a way to send messages in Android to log, but I dont know it yet. Stoyan //There is problem with some files printing deubg info. //And debug in NDK is bad idea in Android if (hdr->FILE.POS != 0) fprintf(stdout,"Debugging Information: (Format=%d) %s FILE.POS=%d is not zero.\n",hdr->TYPE,hdr->FileName,(int)hdr->FILE.POS); typeof(hdr->NS) k; for (k=0; kNS; k++) if (GDFTYP_BITS[hdr->CHANNEL[k].GDFTYP] % 8) { if (hdr->TYPE==alpha) ; // 12bit alpha is well tested else if ((__BYTE_ORDER == __LITTLE_ENDIAN) && !hdr->FILE.LittleEndian) fprintf(stdout,"GDFTYP=%i [12bit LE/BE] not well tested\n",hdr->CHANNEL[k].GDFTYP); else if ((__BYTE_ORDER == __LITTLE_ENDIAN) && hdr->FILE.LittleEndian) fprintf(stdout,"GDFTYP=%i [12bit LE/LE] not well tested\n",hdr->CHANNEL[k].GDFTYP); else if ((__BYTE_ORDER == __BIG_ENDIAN) && hdr->FILE.LittleEndian) fprintf(stdout,"GDFTYP=%i [12bit BE/LE] not well tested\n",hdr->CHANNEL[k].GDFTYP); else if ((__BYTE_ORDER == __BIG_ENDIAN) && !hdr->FILE.LittleEndian) fprintf(stdout,"GDFTYP=%i [12bit BE/BE] not well tested\n",hdr->CHANNEL[k].GDFTYP); } } if (VERBOSE_LEVEL>7) fprintf(stdout,"sopen{return} %i %s\n", hdr->AS.B4C_ERRNUM,GetFileTypeString(hdr->TYPE) ); #endif return(hdr); } // end of SOPEN /**************************************************************************** bpb8_collapsed_rawdata computes the bytes per block when rawdata is collapsed ****************************************************************************/ size_t bpb8_collapsed_rawdata(HDRTYPE *hdr) { size_t bpb8=0; CHANNEL_TYPE *CHptr; typeof(hdr->NS) k; for (k=0; kNS; k++) { CHptr = hdr->CHANNEL+k; if (CHptr->OnOff) bpb8 += (size_t)CHptr->SPR*GDFTYP_BITS[CHptr->GDFTYP]; } return(bpb8); } /* *************************************************************************** collapse raw data this function is used to remove obsolete channels (e.g. status and annotation channels because the information as been already converted into the event table) that are not needed in GDF. if buf==NULL, hdr->AS.rawdata will be collapsed ****************************************************************************/ void collapse_rawdata(HDRTYPE *hdr, void *buf, size_t count) { CHANNEL_TYPE *CHptr; size_t bpb, k4; size_t bi1=0, bi2=0, SZ; int num3Segments=0,k1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): started\n",__func__,__LINE__); bpb = bpb8_collapsed_rawdata(hdr); if (bpb == hdr->AS.bpb<<3) return; // no collapsing needed if ((bpb & 7) || (hdr->AS.bpb8 & 7)) { biosigERROR(hdr, B4C_RAWDATA_COLLAPSING_FAILED, "collapse_rawdata: does not support bitfields"); } bpb >>= 3; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): bpb=%i/%i\n",__func__,__LINE__,(int)bpb,hdr->AS.bpb); if (buf == NULL) { buf = hdr->AS.rawdata; count = hdr->AS.length; } // prepare idxlist for copying segments within a single block (i.e. record) size_t *idxList= alloca(3*hdr->NS*sizeof(size_t)); CHptr = hdr->CHANNEL; while (1) { SZ = 0; while (!CHptr->OnOff && (CHptr < hdr->CHANNEL+hdr->NS) ) { SZ += (size_t)CHptr->SPR * GDFTYP_BITS[CHptr->GDFTYP]; if (SZ & 7) biosigERROR(hdr, B4C_RAWDATA_COLLAPSING_FAILED, "collapse_rawdata: does not support bitfields"); CHptr++; } bi1 += SZ; SZ = 0; while (CHptr->OnOff && (CHptr < hdr->CHANNEL+hdr->NS)) { SZ += (size_t)CHptr->SPR * GDFTYP_BITS[CHptr->GDFTYP]; if (SZ & 7) biosigERROR(hdr, B4C_RAWDATA_COLLAPSING_FAILED, "collapse_rawdata: does not support bitfields"); CHptr++; } if (SZ > 0) { SZ >>= 3; idxList[num3Segments] = bi2; // offset of destination idxList[num3Segments+1] = bi1; // offset of source idxList[num3Segments+2] = SZ; // size num3Segments += 3; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): #%i src:%i dest:%i size:%i\n",__func__,__LINE__,num3Segments/3,(int)bi1,(int)bi2,(int)SZ); } if (CHptr >= hdr->CHANNEL+hdr->NS) break; bi1 += SZ; bi2 += SZ; } for (k4 = 0; k4 < count; k4++) { void *src = buf + k4*hdr->AS.bpb; void *dest = buf + k4*bpb; for (k1=0; k1 < num3Segments; k1+=3) if ((dest + idxList[k1]) != (src + idxList[k1+1])) memcpy(dest + idxList[k1], src + idxList[k1+1], idxList[k1+2]); } if (buf == hdr->AS.rawdata) { hdr->AS.flag_collapsed_rawdata = 1; // rawdata is now "collapsed" } } /****************************************************************************/ /** SREAD_RAW : segment-based **/ /****************************************************************************/ size_t sread_raw(size_t start, size_t length, HDRTYPE* hdr, char flag, void *buf, size_t bufsize) { /* * Reads LENGTH blocks with HDR.AS.bpb BYTES each * (and HDR.SPR samples). * Rawdata is available in hdr->AS.rawdata. * * start <0: read from current position * >=0: start reading from position start * length : try to read length blocks * * flag!=0 : unused channels (those channels k where HDR.CHANNEL[k].OnOff==0) * are collapsed * * for reading whole data section, bufsize must be length*hdr->AS.bpb (also if flag is set) */ if (buf != NULL) { if (length > (bufsize / hdr->AS.bpb)) { fprintf(stderr, "Warning %s (line %i): bufsize is not large enough for converting %i blocks.\n", \ __func__, __LINE__, (int)length); length = bufsize / hdr->AS.bpb; } if ( (hdr->AS.first <= start) && ((start+length) <= (hdr->AS.first+hdr->AS.length)) ) { /**** copy from rawData if available: - better performance - required for some data formats (e.g. CFS, when hdr->AS.rawdata is populated in SOPEN) ****/ if (!hdr->AS.flag_collapsed_rawdata) { memcpy(buf, hdr->AS.rawdata + (start - hdr->AS.first) * hdr->AS.bpb, bufsize); if (flag) collapse_rawdata(hdr, buf, length); return (length); } else if (flag) { size_t bpb = bpb8_collapsed_rawdata(hdr)>>3; memcpy(buf, hdr->AS.rawdata + (start - hdr->AS.first) * bpb, bufsize); return (bufsize / bpb); } // else if (hdr->AS.flag_collapsed_rawdata && !flag) is handled below } } if (hdr->AS.flag_collapsed_rawdata && !flag) hdr->AS.length = 0; // force reloading of data size_t count, nelem; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): start=%d length=%d nrec=%d POS=%d bpb=%i\n",__func__,__LINE__, \ (int)start,(int)length,(int)hdr->NRec, (int)hdr->FILE.POS, hdr->AS.bpb); if ((nrec_t)start > hdr->NRec) return(0); else if ((ssize_t)start < 0) start = hdr->FILE.POS; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %d %d %d %d\n",__func__,__LINE__, (int)start, (int)length, (int)hdr->NRec, (int)hdr->FILE.POS); // limit reading to end of data block if (hdr->NRec<0) nelem = length; else if (start >= (size_t)hdr->NRec) nelem = 0; else nelem = min(length, hdr->NRec - start); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i %i %i %p\n",__func__,__LINE__, \ (int)start, (int)length, (int)nelem, (int)hdr->NRec, (int)hdr->FILE.POS, hdr->AS.rawdata); if ( (buf == NULL) && (start >= hdr->AS.first) && ( (start + nelem) <= (hdr->AS.first + hdr->AS.length) ) ) { // Caching, no file-IO, data is already loaded into hdr->AS.rawdata hdr->FILE.POS = start; count = nelem; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): \n",__func__,__LINE__); } #ifndef WITHOUT_NETWORK else if (hdr->FILE.Des > 0) { // network connection int s = bscs_requ_dat(hdr->FILE.Des, start, length,hdr); count = hdr->AS.length; if (VERBOSE_LEVEL>7) fprintf(stdout,"sread-raw from network: 222 count=%i\n",(int)count); } #endif else { assert(hdr->TYPE != CFS); // CFS data has been already cached in SOPEN assert(hdr->TYPE != SMR); // CFS data has been already cached in SOPEN if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): \n",__func__,__LINE__); // read required data block(s) if (ifseek(hdr, start*hdr->AS.bpb + hdr->HeadLen, SEEK_SET)<0) { if (VERBOSE_LEVEL>7) fprintf(stdout,"--%i %i %i %i \n",(int)(start*hdr->AS.bpb + hdr->HeadLen), (int)start, (int)hdr->AS.bpb, (int)hdr->HeadLen); return(0); } else hdr->FILE.POS = start; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): bpb=%i\n",__func__,__LINE__,(int)hdr->AS.bpb); // allocate AS.rawdata void* tmpptr = buf; if (buf == NULL) { tmpptr = realloc(hdr->AS.rawdata, hdr->AS.bpb*nelem); if ((tmpptr!=NULL) || (hdr->AS.bpb*nelem==0)) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %i %i \n",__func__,__LINE__,(int)hdr->AS.bpb,(int)nelem); hdr->AS.rawdata = (uint8_t*) tmpptr; } else { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "memory allocation failed"); return(0); } } if (VERBOSE_LEVEL>8) fprintf(stdout,"#sread(%i %li)\n",(int)(hdr->HeadLen + hdr->FILE.POS*hdr->AS.bpb), iftell(hdr)); // read data count = ifread(tmpptr, hdr->AS.bpb, nelem, hdr); if (buf != NULL) { hdr->AS.flag_collapsed_rawdata = 0; // is rawdata not collapsed hdr->AS.first = start; hdr->AS.length= count; } if (count < nelem) { fprintf(stderr,"warning: less than the number of requested blocks read (%i/%i) from file %s - something went wrong\n",(int)count,(int)nelem,hdr->FileName); if (VERBOSE_LEVEL>7) fprintf(stderr,"warning: only %i instead of %i blocks read - something went wrong (bpb=%i,pos=%li)\n",(int)count,(int)nelem,hdr->AS.bpb,iftell(hdr)); } } // (uncollapsed) data is now in buffer hdr->AS.rawdata if (flag) { collapse_rawdata(hdr, NULL, 0); } return(count); } /**************************************************************************** caching: load data of whole file into buffer this will speed up data access, especially in interactive mode ****************************************************************************/ int cachingWholeFile(HDRTYPE* hdr) { sread_raw(0,hdr->NRec,hdr, 0, NULL, 0); return((hdr->AS.first != 0) || (hdr->AS.length != (size_t)hdr->NRec)); } /****************************************************************************/ /** SREAD : segment-based **/ /****************************************************************************/ size_t sread(biosig_data_type* data, size_t start, size_t length, HDRTYPE* hdr) { /* * Reads LENGTH blocks with HDR.AS.bpb BYTES each * (and HDR.SPR samples). * Rawdata is available in hdr->AS.rawdata. * Output data is available in hdr->data.block. * If the request can be completed, hdr->data.block contains * LENGTH*HDR.SPR samples and HDR.NS channels. * The size of the output data is availabe in hdr->data.size. * * hdr->FLAG.LittleEndian controls swapping * * hdr->CHANNEL[k].OnOff controls whether channel k is loaded or not * * data is a pointer to a memory array to write the data. * if data is NULL, memory is allocated and the pointer is returned * in hdr->data.block. * * channel selection is controlled by hdr->CHANNEL[k].OnOff * * start <0: read from current position * >=0: start reading from position start * length : try to read length blocks * * * ToDo: * - sample-based loading * */ size_t count,k1,k2,k4,k5=0,NS;//bi,bi8; size_t toffset; // time offset for rawdata biosig_data_type *data1=NULL; if (VERBOSE_LEVEL>6) fprintf(stdout,"%s( %p, %i, %i, %s ) MODE=%i bpb=%i\n",__func__,data, (int)start, (int)length, hdr->FileName, hdr->FILE.OPEN, (int)hdr->AS.bpb); if ((ssize_t)start < 0) start=hdr->FILE.POS; if (start >= (size_t)hdr->NRec) return(0); switch (hdr->TYPE) { case AXG: case ABF2: case ATF: case SMR: // data is already cached count = hdr->NRec; break; default: count = sread_raw(start, length, hdr, 0, NULL, 0); } if (hdr->AS.B4C_ERRNUM) return(0); toffset = start - hdr->AS.first; // set position of file handle size_t POS = hdr->FILE.POS; hdr->FILE.POS += count; // count number of selected channels for (k1=0,NS=0; k1NS; ++k1) if (hdr->CHANNEL[k1].OnOff) ++NS; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): count=%i pos=[%i,%i,%i,%i], size of data = %ix%ix%ix%i = %i\n", __func__, __LINE__, \ (int)count,(int)start,(int)length,(int)POS,(int)hdr->FILE.POS,(int)hdr->SPR, (int)count, \ (int)NS, (int)sizeof(biosig_data_type), (int)(hdr->SPR * count * NS * sizeof(biosig_data_type))); #ifndef ANDROID //Stoyan: Arm has some problem with log2 - or I dont know how to fix it - it exists but do not work. if (log2(hdr->SPR) + log2(count) + log2(NS) + log2(sizeof(biosig_data_type)) + 1 >= sizeof(size_t)*8) { // used to check the 2GByte limit on 32bit systems biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Size of required data buffer too large (exceeds size_t addressable space)"); return(0); } #endif // transfer RAW into BIOSIG data format if ((data==NULL) || hdr->Calib) { // local data memory required size_t sz = hdr->SPR * count * NS * sizeof(biosig_data_type); void *tmpptr = realloc(hdr->data.block, sz); if (tmpptr!=NULL || !sz) data1 = (biosig_data_type*) tmpptr; else { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "memory allocation failed - not enough memory"); return(0); } hdr->data.block = data1; } else data1 = data; char ALPHA12BIT = (hdr->TYPE==alpha) && (hdr->NS>0) && (hdr->CHANNEL[0].GDFTYP==(255+12)); char MIT12BIT = (hdr->TYPE==MIT ) && (hdr->NS>0) && (hdr->CHANNEL[0].GDFTYP==(255+12)); #if (__BYTE_ORDER == __BIG_ENDIAN) char SWAP = hdr->FILE.LittleEndian; #elif (__BYTE_ORDER == __LITTLE_ENDIAN) char SWAP = !hdr->FILE.LittleEndian; #endif int stride = 1; #ifndef ONLYGDF if (hdr->TYPE==Axona) stride = 64; else if (hdr->TYPE==TMS32) stride = hdr->NS; #endif //ONLYGDF if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): alpha12bit=%i SWAP=%i spr=%i %p\n",__func__,__LINE__, ALPHA12BIT, SWAP, hdr->SPR, hdr->AS.rawdata); for (k1=0,k2=0; k1NS; k1++) { CHANNEL_TYPE *CHptr = hdr->CHANNEL+k1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i#%i: alpha12bit=%i SWAP=%i spr=%i %p | bi=%i bpb=%i \n",__func__,__LINE__, (int)k1, (int)k2, ALPHA12BIT, SWAP, hdr->SPR, hdr->AS.rawdata,(int)CHptr->bi,(int)hdr->AS.bpb ); if (CHptr->OnOff) { /* read selected channels only */ if (CHptr->SPR > 0) { size_t DIV = hdr->SPR/CHptr->SPR; uint16_t GDFTYP = CHptr->GDFTYP; size_t SZ = GDFTYP_BITS[GDFTYP]; int32_t int32_value = 0; uint8_t bitoff = 0; union {int16_t i16; uint16_t u16; uint32_t i32; float f32; uint64_t i64; double f64;} u; // TODO: MIT data types for (k4 = 0; k4 < count; k4++) { uint8_t *ptr1; #ifndef ONLYGDF if (hdr->TYPE == FEF) { ptr1 = CHptr->bufptr; } else #endif //ONLYGDF ptr1 = hdr->AS.rawdata + (k4+toffset)*hdr->AS.bpb + CHptr->bi; for (k5 = 0; k5 < CHptr->SPR; k5++) { biosig_data_type sample_value; uint8_t *ptr = ptr1 + (stride * k5 * SZ >> 3); if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i): k_i = [%d %d %d %d ] 0x%08x[%g] @%p => ",__func__,__LINE__,(int)k1,(int)k2,(int)k4,(int)k5,(int)leu32p(ptr),lef64p(ptr),ptr); switch (GDFTYP) { case 1: sample_value = (biosig_data_type)(*(int8_t*)ptr); break; case 2: sample_value = (biosig_data_type)(*(uint8_t*)ptr); break; case 3: if (SWAP) { sample_value = (biosig_data_type)(int16_t)bswap_16(*(int16_t*)ptr); } else { sample_value = (biosig_data_type)(*(int16_t*)ptr); } break; case 4: if (SWAP) { sample_value = (biosig_data_type)(uint16_t)bswap_16(*(uint16_t*)ptr); } else { sample_value = (biosig_data_type)(*(uint16_t*)ptr); } break; case 5: if (SWAP) { sample_value = (biosig_data_type)(int32_t)bswap_32(*(int32_t*)ptr); } else { sample_value = (biosig_data_type)(*(int32_t*)ptr); } break; case 6: if (SWAP) { sample_value = (biosig_data_type)(uint32_t)bswap_32(*(uint32_t*)ptr); } else { sample_value = (biosig_data_type)(*(uint32_t*)ptr); } break; case 7: if (SWAP) { sample_value = (biosig_data_type)(int64_t)bswap_64(*(int64_t*)ptr); } else { sample_value = (biosig_data_type)(*(int64_t*)ptr); } break; case 8: if (SWAP) { sample_value = (biosig_data_type)(uint64_t)bswap_64(*(uint64_t*)ptr); } else { sample_value = (biosig_data_type)(*(uint64_t*)ptr); } break; case 16: if (SWAP) { u.i32 = bswap_32(*(uint32_t*)(ptr)); sample_value = (biosig_data_type)(u.f32); } else { sample_value = (biosig_data_type)(*(float*)(ptr)); } break; case 17: if (SWAP) { u.i64 = bswap_64(*(uint64_t*)(ptr)); sample_value = (biosig_data_type)(u.f64); } else { sample_value = (biosig_data_type)(*(double*)(ptr)); } break; case 128: // Nihon-Kohden little-endian int16 format u.u16 = leu16p(ptr) + 0x8000; sample_value = (biosig_data_type) (u.i16); break; case 255+12: if (ALPHA12BIT) { // get source address size_t off = (k4+toffset)*hdr->NS*SZ + hdr->CHANNEL[k1].bi8 + k5*SZ; ptr = hdr->AS.rawdata + (off>>3); if (off & 0x07) u.i16 = ptr[1] + ((ptr[0] & 0x0f)<<8); else u.i16 = (ptr[0]<<4) + (ptr[1] >> 4); if (u.i16 & 0x0800) u.i16 -= 0x1000; sample_value = (biosig_data_type)u.i16; } else if (MIT12BIT) { size_t off = (k4+toffset)*hdr->NS*SZ + hdr->CHANNEL[k1].bi8 + k5*SZ; ptr = hdr->AS.rawdata + (off>>3); //bitoff = k5*SZ & 0x07; if (off & 0x07) u.i16 = (((uint16_t)ptr[0] & 0xf0) << 4) + ptr[1]; else //u.i16 = ((uint16_t)ptr[0]<<4) + (ptr[1] & 0x0f); u.i16 = leu16p(ptr) & 0x0fff; if (u.i16 & 0x0800) u.i16 -= 0x1000; sample_value = (biosig_data_type)u.i16; } else if (hdr->FILE.LittleEndian) { bitoff = k5*SZ & 0x07; #if __BYTE_ORDER == __BIG_ENDIAN u.i16 = (leu16p(ptr) >> (4-bitoff)) & 0x0FFF; #elif __BYTE_ORDER == __LITTLE_ENDIAN u.i16 = (leu16p(ptr) >> bitoff) & 0x0FFF; #endif if (u.i16 & 0x0800) u.i16 -= 0x1000; sample_value = (biosig_data_type)u.i16; } else { bitoff = k5*SZ & 0x07; #if __BYTE_ORDER == __BIG_ENDIAN u.i16 = (beu16p(ptr) >> (4-bitoff)) & 0x0FFF; #elif __BYTE_ORDER == __LITTLE_ENDIAN u.i16 = (beu16p(ptr) >> bitoff) & 0x0FFF; #endif if (u.i16 & 0x0800) u.i16 -= 0x1000; sample_value = (biosig_data_type)u.i16; } break; case 511+12: bitoff = k5*SZ & 0x07; if (hdr->FILE.LittleEndian) { #if __BYTE_ORDER == __BIG_ENDIAN sample_value = (biosig_data_type)((leu16p(ptr) >> (4-bitoff)) & 0x0FFF); #elif __BYTE_ORDER == __LITTLE_ENDIAN sample_value = (biosig_data_type)((leu16p(ptr) >> bitoff) & 0x0FFF); #endif } else { #if __BYTE_ORDER == __BIG_ENDIAN sample_value = (biosig_data_type)((beu16p(ptr) >> (4-bitoff)) & 0x0FFF); #elif __BYTE_ORDER == __LITTLE_ENDIAN sample_value = (biosig_data_type)((beu16p(ptr) >> (4-bitoff)) & 0x0FFF); #endif } case 255+24: if (hdr->FILE.LittleEndian) { int32_value = (*(uint8_t*)(ptr)) + (*(uint8_t*)(ptr+1)<<8) + (*(int8_t*)(ptr+2)*(1<<16)); sample_value = (biosig_data_type)int32_value; } else { int32_value = (*(uint8_t*)(ptr+2)) + (*(uint8_t*)(ptr+1)<<8) + (*(int8_t*)(ptr)*(1<<16)); sample_value = (biosig_data_type)int32_value; } break; case 511+24: if (hdr->FILE.LittleEndian) { int32_value = (*(uint8_t*)(ptr)) + (*(uint8_t*)(ptr+1)<<8) + (*(uint8_t*)(ptr+2)<<16); sample_value = (biosig_data_type)int32_value; } else { int32_value = (*(uint8_t*)(ptr+2)) + (*(uint8_t*)(ptr+1)<<8) + (*(uint8_t*)(ptr)<<16); sample_value = (biosig_data_type)int32_value; } break; default: if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) GDFTYP=%i %i %i \n", __FILE__, __LINE__, GDFTYP, (int)k1, (int)k2); biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "Error SREAD: datatype not supported"); return(-1); } // end switch // overflow and saturation detection if ((hdr->FLAG.OVERFLOWDETECTION) && ((sample_value <= CHptr->DigMin) || (sample_value >= CHptr->DigMax))) sample_value = NAN; // missing value if (!hdr->FLAG.UCAL) // scaling sample_value = sample_value * CHptr->Cal + CHptr->Off; if (VERBOSE_LEVEL>8) fprintf(stdout,"%g\n",sample_value); // resampling 1->DIV samples if (hdr->FLAG.ROW_BASED_CHANNELS) { size_t k3; for (k3=0; k3 < DIV; k3++) data1[k2 + (k4*hdr->SPR + k5*DIV + k3)*NS] = sample_value; // row-based channels } else { size_t k3; for (k3=0; k3 < DIV; k3++) data1[k2*count*hdr->SPR + k4*hdr->SPR + k5*DIV + k3] = sample_value; // column-based channels } } // end for (k5 .... } // end for (k4 .... } k2++; }} if (hdr->FLAG.ROW_BASED_CHANNELS) { hdr->data.size[0] = k2; // rows hdr->data.size[1] = hdr->SPR*count; // columns } else { hdr->data.size[0] = hdr->SPR*count; // rows hdr->data.size[1] = k2; // columns } /* read sparse samples */ if (((hdr->TYPE==GDF) && (hdr->VERSION > 1.9)) || (hdr->TYPE==PDP)) { for (k1=0,k2=0; k1NS; k1++) { CHANNEL_TYPE *CHptr = hdr->CHANNEL+k1; // Initialize sparse channels with NANs if (CHptr->OnOff) { /* read selected channels only */ if (CHptr->SPR==0) { // sparsely sampled channels are stored in event table if (hdr->FLAG.ROW_BASED_CHANNELS) { for (k5 = 0; k5 < hdr->SPR*count; k5++) data1[k2 + k5*NS] = CHptr->DigMin; // row-based channels } else { for (k5 = 0; k5 < hdr->SPR*count; k5++) data1[k2*count*hdr->SPR + k5] = CHptr->DigMin; // column-based channels } } k2++; } } double c = hdr->SPR / hdr->SampleRate * hdr->EVENT.SampleRate; size_t *ChanList = (size_t*)calloc(hdr->NS+1,sizeof(size_t)); // Note: ChanList and EVENT.CHN start with index=1 (not 0) size_t ch = 0; for (k1=0; k1NS; k1++) // list of selected channels ChanList[k1+1]= (hdr->CHANNEL[k1].OnOff ? ++ch : 0); for (k1=0; k1EVENT.N; k1++) if (hdr->EVENT.TYP[k1] == 0x7fff) // select non-equidistant sampled value if (ChanList[hdr->EVENT.CHN[k1]] > 0) // if channel is selected if ((hdr->EVENT.POS[k1] >= POS*c) && (hdr->EVENT.POS[k1] < hdr->FILE.POS*c)) { biosig_data_type sample_value; uint8_t *ptr = (uint8_t*)(hdr->EVENT.DUR + k1); k2 = ChanList[hdr->EVENT.CHN[k1]]-1; CHANNEL_TYPE *CHptr = hdr->CHANNEL+k2; size_t DIV = (uint32_t)ceil(hdr->SampleRate/hdr->EVENT.SampleRate); uint16_t GDFTYP = CHptr->GDFTYP; // size_t SZ = GDFTYP_BITS[GDFTYP]>>3; // obsolete int32_t int32_value = 0; if (0); else if (GDFTYP==3) sample_value = (biosig_data_type)lei16p(ptr); else if (GDFTYP==4) sample_value = (biosig_data_type)leu16p(ptr); else if (GDFTYP==16) sample_value = (biosig_data_type)lef32p(ptr); /* else if (GDFTYP==17) sample_value = (biosig_data_type)lef64p(ptr); */ else if (GDFTYP==0) sample_value = (biosig_data_type)(*(char*)ptr); else if (GDFTYP==1) sample_value = (biosig_data_type)(*(int8_t*)ptr); else if (GDFTYP==2) sample_value = (biosig_data_type)(*(uint8_t*)ptr); else if (GDFTYP==5) sample_value = (biosig_data_type)lei32p(ptr); else if (GDFTYP==6) sample_value = (biosig_data_type)leu32p(ptr); /* else if (GDFTYP==7) sample_value = (biosig_data_type)(*(int64_t*)ptr); else if (GDFTYP==8) sample_value = (biosig_data_type)(*(uint64_t*)ptr); */ else if (GDFTYP==255+24) { // assume LITTLE_ENDIAN format int32_value = (*(uint8_t*)(ptr)) + (*(uint8_t*)(ptr+1)<<8) + (*(int8_t*)(ptr+2)*(1<<16)); sample_value = (biosig_data_type)int32_value; } else if (GDFTYP==511+24) { // assume LITTLE_ENDIAN format int32_value = (*(uint8_t*)(ptr)) + (*(uint8_t*)(ptr+1)<<8) + (*(uint8_t*)(ptr+2)<<16); sample_value = (biosig_data_type)int32_value; } else { if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) GDFTYP=%i %i %i \n", __FILE__, __LINE__, GDFTYP,(int)k1,(int)k2); biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "Error SREAD: datatype not supported"); return(0); } // overflow and saturation detection if ((hdr->FLAG.OVERFLOWDETECTION) && ((sample_value<=CHptr->DigMin) || (sample_value>=CHptr->DigMax))) sample_value = NAN; // missing value if (!hdr->FLAG.UCAL) // scaling sample_value = sample_value * CHptr->Cal + CHptr->Off; // resampling 1->DIV samples k5 = (hdr->EVENT.POS[k1]/c - POS)*hdr->SPR; if (hdr->FLAG.ROW_BASED_CHANNELS) { size_t k3; for (k3=0; k3 < DIV; k3++) data1[k2 + (k5 + k3)*NS] = sample_value; } else { size_t k3; for (k3=0; k3 < DIV; k3++) data1[k2 * count * hdr->SPR + k5 + k3] = sample_value; } if (VERBOSE_LEVEL>7) fprintf(stdout,"E%02i: s(%d,%d)= %d %e %e %e\n",(int)k1,(int)k2,hdr->EVENT.CHN[k1],leu32p(ptr),sample_value,(*(double*)(ptr)),(*(float*)(ptr))); } free(ChanList); } else if (hdr->TYPE==TMS32) { // post-processing TMS32 files: last block can contain undefined samples size_t spr = lei32p(hdr->AS.Header+121); if (hdr->FILE.POS*hdr->SPR > spr) for (k2=0; k2SPR; k5 < hdr->SPR*count; k5++) { if (hdr->FLAG.ROW_BASED_CHANNELS) data1[k2 + k5*NS] = NAN; // row-based channels else data1[k2*count*hdr->SPR + k5] = NAN; // column-based channels } } #ifdef CHOLMOD_H if (hdr->Calib) { if (!hdr->FLAG.ROW_BASED_CHANNELS) fprintf(stderr,"Error SREAD: Re-Referencing on column-based data not supported."); else { cholmod_dense X,Y; X.nrow = hdr->data.size[0]; X.ncol = hdr->data.size[1]; X.d = hdr->data.size[0]; X.nzmax= hdr->data.size[1]*hdr->data.size[0]; X.x = data1; X.xtype = CHOLMOD_REAL; X.dtype = CHOLMOD_DOUBLE; Y.nrow = hdr->Calib->ncol; Y.ncol = hdr->data.size[1]; Y.d = Y.nrow; Y.nzmax= Y.nrow * Y.ncol; if (data) Y.x = data; else Y.x = malloc(Y.nzmax*sizeof(double)); Y.xtype = CHOLMOD_REAL; Y.dtype = CHOLMOD_DOUBLE; double alpha[]={1,0},beta[]={0,0}; cholmod_sdmult(hdr->Calib,1,alpha,beta,&X,&Y,&CHOLMOD_COMMON_VAR); if (VERBOSE_LEVEL>8) fprintf(stdout,"%f -> %f\n",*(double*)X.x,*(double*)Y.x); free(X.x); if (data==NULL) hdr->data.block = (biosig_data_type*)Y.x; else hdr->data.block = NULL; hdr->data.size[0] = Y.nrow; } } #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"sread - end \n"); //VERBOSE_LEVEL = V; return(count); } // end of SREAD #ifdef __GSL_MATRIX_DOUBLE_H__ /****************************************************************************/ /** GSL_SREAD : GSL-version of sread **/ /****************************************************************************/ size_t gsl_sread(gsl_matrix* m, size_t start, size_t length, HDRTYPE* hdr) { /* same as sread but return data is of type gsl_matrix */ // TODO: testing size_t count = sread(NULL, start, length, hdr); size_t n = hdr->data.size[0]*hdr->data.size[1]; if (m->owner && m->block) gsl_block_free(m->block); m->block = gsl_block_alloc(n); m->block->data = hdr->data.block; m->size1 = hdr->data.size[1]; m->tda = hdr->data.size[0]; m->size2 = hdr->data.size[0]; m->data = m->block->data; m->owner = 1; hdr->data.block = NULL; return(count); } #endif /****************************************************************************/ /** SWRITE **/ /****************************************************************************/ size_t swrite(const biosig_data_type *data, size_t nelem, HDRTYPE* hdr) { /* * writes NELEM blocks with HDR.AS.bpb BYTES each, */ uint8_t *ptr; size_t count=0,k1,k2,k4,k5,DIV,SZ=0; int GDFTYP; CHANNEL_TYPE* CHptr; biosig_data_type sample_value, iCal, iOff; union { int8_t i8; uint8_t u8; int16_t i16; uint16_t u16; int32_t i32; uint32_t u32; int64_t i64; uint64_t u64; } val; if (VERBOSE_LEVEL>6) fprintf(stdout,"%s( %p, %i, %s ) MODE=%i\n",__func__, data, (int)nelem, hdr->FileName, hdr->FILE.OPEN); // write data #define MAX_INT8 ((int8_t)0x7f) #define MIN_INT8 ((int8_t)0x80) #define MAX_UINT8 ((uint8_t)0xff) #define MIN_UINT8 ((uint8_t)0) #define MAX_INT16 ((int16_t)0x7fff) #define MIN_INT16 ((int16_t)0x8000) #define MAX_UINT16 ((uint16_t)0xffff) #define MIN_UINT16 ((uint16_t)0) #define MAX_INT24 ((int32_t)0x007fffff) #define MIN_INT24 ((int32_t)0xff800000) #define MAX_UINT24 ((uint32_t)0x00ffffff) #define MIN_UINT24 ((uint32_t)0) #define MAX_INT32 ((int32_t)0x7fffffff) #define MIN_INT32 ((int32_t)0x80000000) #define MAX_UINT32 ((uint32_t)0xffffffff) #define MIN_UINT32 ((uint32_t)0) #define MAX_INT64 ((((uint64_t)1)<<63)-1) #define MIN_INT64 ((int64_t)((uint64_t)1)<<63) #define MAX_UINT64 ((uint64_t)0xffffffffffffffffl) #define MIN_UINT64 ((uint64_t)0) size_t bpb8 = bpb8_collapsed_rawdata(hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): <%s> sz=%i\n",__func__,__LINE__,hdr->FileName,(int)(hdr->NRec*bpb8>>3)); if (hdr->TYPE==ATF) { if (VERBOSE_LEVEL>7) fprintf(stdout,"ATF swrite\n"); nrec_t nr = hdr->data.size[(int)hdr->FLAG.ROW_BASED_CHANNELS]; // if collapsed data, use k2, otherwise use k1 assert(nr == hdr->NRec * hdr->SPR); typeof(hdr->NS) k,k2; nrec_t c = 0; unsigned timeChan = getTimeChannelNumber(hdr); if (hdr->data.size[1-hdr->FLAG.ROW_BASED_CHANNELS] < hdr->NS) { // if collapsed data, use k2, otherwise use k1 for (c = 0; c < nr; c++) { char *sep = "\n"; if (timeChan == 0) { fprintf(hdr->FILE.FID,"%s%.16g",sep,(++hdr->FILE.POS)*1000.0/hdr->SampleRate); sep = "\t"; } for (k = 0, k2=0; k < hdr->NS; k++) { if (hdr->CHANNEL[k].OnOff) { size_t idx; if (hdr->FLAG.ROW_BASED_CHANNELS) idx = k2 + c * hdr->data.size[0]; else idx = k2 * hdr->data.size[0] + c; fprintf(hdr->FILE.FID,"%s%.16g",sep,data[idx]); sep = "\t"; k2++; } } } } else { // if not collapsed data, use k1 for (c = 0; c < nr; c++) { char *sep = "\n"; if (timeChan == 0) { fprintf(hdr->FILE.FID,"%s%.16g",sep,(++hdr->FILE.POS)*1000.0/hdr->SampleRate); sep = "\t"; } for (k = 0; k < hdr->NS; k++) { if (hdr->CHANNEL[k].OnOff) { size_t idx; if (hdr->FLAG.ROW_BASED_CHANNELS) idx = k + c * hdr->data.size[0]; else idx = k * hdr->data.size[0] + c; fprintf(hdr->FILE.FID,"%s%.16g", sep, data[idx]); sep = "\t"; } } } } return nr; // end write ATF } if ((hdr->NRec*bpb8>0) && (hdr->TYPE != SCP_ECG)) { // memory allocation for SCP is done in SOPEN_SCP_WRITE Section 6 ptr = (typeof(ptr))realloc(hdr->AS.rawdata, (hdr->NRec*bpb8>>3)+1); if (ptr==NULL) { biosigERROR(hdr, B4C_INSUFFICIENT_MEMORY, "SWRITE: memory allocation failed."); return(0); } hdr->AS.rawdata = (uint8_t*)ptr; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %dx%d %d\n",__func__,__LINE__,(int)hdr->NRec,hdr->SPR,hdr->NS); size_t bi8 = 0; for (k1=0,k2=0; k1NS; k1++) { CHptr = hdr->CHANNEL+k1; if (CHptr->OnOff != 0) { if (CHptr->SPR) { DIV = hdr->SPR/CHptr->SPR; GDFTYP = CHptr->GDFTYP; SZ = GDFTYP_BITS[GDFTYP]; iCal = 1/CHptr->Cal; //iOff = CHptr->DigMin - CHptr->PhysMin*iCal; iOff = -CHptr->Off*iCal; size_t col = (hdr->data.size[1-hdr->FLAG.ROW_BASED_CHANNELS]NS) ? k2 : k1; // if collapsed data, use k2, otherwise use k1 if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): #%i gdftyp=%i %i %i %i %f %f %f %f %i\n", __func__,__LINE__,(int)k1,GDFTYP,(int)bi8,(int)SZ,(int)CHptr->SPR,CHptr->Cal,CHptr->Off,iCal,iOff,(int)bpb8); for (k4 = 0; k4 < (size_t)hdr->NRec; k4++) { if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i): #%i: [%i %i] %i %i %i %i %i\n", __func__,__LINE__,(int)k1,(int)hdr->data.size[0],(int)hdr->data.size[1],(int)k4,(int)0,(int)hdr->SPR,(int)DIV,(int)nelem); for (k5 = 0; k5 < CHptr->SPR; k5++) { if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i): #%i: [%i %i] %i %i %i %i %i\n", __func__,__LINE__,(int)k1,(int)hdr->data.size[0],(int)hdr->data.size[1],(int)k4,(int)k5,(int)hdr->SPR,(int)DIV,(int)nelem); size_t k3=0; if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i): [%i %i %i %i %i] %i %i %i %i %i %i\n", __func__,__LINE__,(int)k1,(int)k2,(int)k3,(int)k4,(int)k5,(int)col, (int)hdr->data.size[0],(int)hdr->data.size[1],(int)hdr->SPR,(int)nelem,(int)hdr->NRec); sample_value = 0.0; if (hdr->FLAG.ROW_BASED_CHANNELS) { for (k3=0; k3 < DIV; k3++) sample_value += data[col + (k4*hdr->SPR + k5*DIV + k3)*hdr->data.size[0]]; } else { for (k3=0; k3 < DIV; k3++) sample_value += data[col*nelem*hdr->SPR + k4*hdr->SPR + k5*DIV + k3]; } sample_value /= DIV; if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i): %f/%i\n",__func__,__LINE__,sample_value,(int)DIV); if (!hdr->FLAG.UCAL) // scaling sample_value = sample_value * iCal + iOff; // get target address //ptr = hdr->AS.rawdata + k4*hdr->AS.bpb + hdr->CHANNEL[k1].bi + k5*SZ; //ptr = hdr->AS.rawdata + (k4*bpb8 + bi8 + k5*SZ)>>3; //size_t off = k4*hdr->AS.bpb8 + hdr->CHANNEL[k1].bi8 + (k5*SZ); size_t off = k4*bpb8 + bi8 + (k5*SZ); ptr = hdr->AS.rawdata + (off>>3); if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i): %i %i %i %f %p %p\n", __func__,__LINE__,(int)k4,(int)k5,(int)(off>>3),sample_value, hdr->AS.Header, ptr); // mapping of raw data type to (biosig_data_type) switch (GDFTYP) { case 3: if (sample_value > MAX_INT16) val.i16 = MAX_INT16; else if (sample_value > MIN_INT16) val.i16 = (int16_t) sample_value; else val.i16 = MIN_INT16; lei16a(val.i16, ptr); break; case 4: if (sample_value > MAX_UINT16) val.u16 = MAX_UINT16; else if (sample_value > MIN_UINT16) val.u16 = (uint16_t) sample_value; else val.u16 = MIN_UINT16; leu16a(val.u16, ptr); break; case 16: lef32a((float)sample_value, ptr); break; case 17: lef64a((double)sample_value, ptr); break; case 0: if (sample_value > MAX_INT8) val.i8 = MAX_INT8; else if (sample_value > MIN_INT8) val.i8 = (int8_t) sample_value; else val.i8 = MIN_INT8; *(int8_t*)ptr = val.i8; break; case 1: if (sample_value > MAX_INT8) val.i8 = MAX_INT8; else if (sample_value > MIN_INT8) val.i8 = (int8_t) sample_value; else val.i8 = MIN_INT8; *(int8_t*)ptr = val.i8; break; case 2: if (sample_value > MAX_UINT8) val.u8 = MAX_UINT8; else if (sample_value > MIN_UINT8) val.u8 = (uint8_t) sample_value; else val.u8 = MIN_UINT8; *(uint8_t*)ptr = val.u8; break; case 5: if (sample_value > ldexp(1.0,31)-1) val.i32 = MAX_INT32; else if (sample_value > ldexp(-1.0,31)) val.i32 = (int32_t) sample_value; else val.i32 = MIN_INT32; lei32a(val.i32, ptr); break; case 6: if (sample_value > ldexp(1.0,32)-1.0) val.u32 = MAX_UINT32; else if (sample_value > 0.0) val.u32 = (uint32_t) sample_value; else val.u32 = MIN_UINT32; leu32a(val.u32, ptr); break; case 7: if (sample_value > ldexp(1.0,63)-1.0) val.i64 = MAX_INT64; else if (sample_value > -ldexp(1.0,63)) val.i64 = (int64_t) sample_value; else val.i64 = MIN_INT64; lei64a(val.i64, ptr); break; case 8: if (sample_value > ldexp(1.0,64)-1.0) val.u64 = (uint64_t)(-1); else if (sample_value > 0.0) val.u64 = (uint64_t) sample_value; else val.u64 = 0; leu64a(val.u64, ptr); break; case 255+24: if (sample_value > MAX_INT24) val.i32 = MAX_INT24; else if (sample_value > MIN_INT24) val.i32 = (int32_t) sample_value; else val.i32 = MIN_INT24; *(uint8_t*)ptr = (uint8_t)(val.i32 & 0x000000ff); *((uint8_t*)ptr+1) = (uint8_t)((val.i32>>8) & 0x000000ff); *((uint8_t*)ptr+2) = (uint8_t)((val.i32>>16) & 0x000000ff); break; case 511+24: if (sample_value > MAX_UINT24) val.i32 = MAX_UINT24; else if (sample_value > MIN_UINT24) val.i32 = (int32_t) sample_value; else val.i32 = MIN_UINT24; *(uint8_t*)ptr = val.i32 & 0x000000ff; *((uint8_t*)ptr+1) = (uint8_t)((val.i32>>8) & 0x000000ff); *((uint8_t*)ptr+2) = (uint8_t)((val.i32>>16) & 0x000000ff); break; case 255+12: case 511+12: { if (GDFTYP == 255+12) { if (sample_value > ((1<<11)-1)) val.i16 = (1<<11)-1; else if (sample_value > -(1<<11)) val.i16 = (int16_t) sample_value; else val.i16 = -(1<<11); } else if (GDFTYP == 511+12) { if (sample_value > ((1<<12)-1)) val.u16 = (1<<12)-1; else if (sample_value > 0) val.u16 = (int16_t) sample_value; else val.u16 = 0; } if (hdr->FILE.LittleEndian) { uint16_t acc = leu16p(ptr); if (off) leu16a( (acc & 0x000F) | (val.u16<<4), ptr); else leu16a( (acc & 0xF000) | (val.u16 & 0x0FFF), ptr); } else { uint16_t acc = beu16p(ptr); if (!off) beu16a( (acc & 0x000F) | (val.u16<<4), ptr); else beu16a( (acc & 0xF000) | (val.u16 & 0x0FFF), ptr); } break; } default: biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "SWRITE: datatype not supported"); return(0); } } // end for k5 } // end for k4 } // end if SPR k2++; bi8 += SZ*CHptr->SPR; if (VERBOSE_LEVEL>7) fprintf(stdout,"swrite 314 %i\n",(int)k2); } // end if OnOff } // end for k1 if (VERBOSE_LEVEL>7) fprintf(stdout,"swrite 315 <%s>\n", hdr->FileName ); #ifndef WITHOUT_NETWORK if (hdr->FILE.Des>0) { if (VERBOSE_LEVEL>7) fprintf(stdout,"bscs_send_dat sz=%i\n",(int)(hdr->NRec*bpb8>>3)); int s = bscs_send_dat(hdr->FILE.Des,hdr->AS.rawdata,hdr->NRec*bpb8>>3); if (VERBOSE_LEVEL>7) fprintf(stdout,"bscs_send_dat succeeded %i\n",s); } else #endif #ifndef ONLYGDF if ((hdr->TYPE == ASCII) || (hdr->TYPE == BIN)) { HDRTYPE H1; H1.CHANNEL = NULL; H1.FILE.COMPRESSION = hdr->FILE.COMPRESSION; if (VERBOSE_LEVEL>7) fprintf(stdout,"swrite ASCII/BIN\n"); k1 = strlen(hdr->FileName); char* fn = (char*)calloc(k1 + 10,1); strcpy(fn, hdr->FileName); char *e = strrchr(fn,'.'); if (e==NULL) { fn[k1] = '.'; e = fn+k1; } e[1] = (hdr->TYPE == ASCII ? 'a' : 's'); e+=2; for (k1=0; k1NS; k1++) if (hdr->CHANNEL[k1].OnOff) { //if (hdr->CHANNEL[k1].OnOff && hdr->CHANNEL[k1].SPR) { /* Off channels and sparse channels (SPR) are not exported; sparse samples are available throught the header file containing the event table. */ CHptr = hdr->CHANNEL+k1; if (hdr->FILE.COMPRESSION) sprintf(e,"%02i_gz",(int)k1+1); else sprintf(e,"%02i",(int)k1+1); if (VERBOSE_LEVEL>7) fprintf(stdout,"#%i: %s\n",(int)k1,fn); H1.FileName = fn; ifopen(&H1,"wb"); if (hdr->TYPE == ASCII) { typeof(hdr->SPR) SPR; if (CHptr->SPR>0) { DIV = hdr->SPR/CHptr->SPR; SPR = CHptr->SPR; } else { DIV = 1; SPR = hdr->SPR; } size_t k2; for (k2=0; k2 < SPR*(size_t)hdr->NRec; k2++) { biosig_data_type i = 0.0; size_t k3; // TODO: row channels if (hdr->FLAG.ROW_BASED_CHANNELS) for (k3=0; k3data.block[k1+(k2*DIV+k3)*hdr->data.size[0]]; else // assumes column channels for (k3=0; k3data.block[hdr->SPR*hdr->NRec*k1+k2*DIV+k3]; /* if (hdr->FLAG.ROW_BASED_CHANNELS) { for (k3=0, sample_value=0.0; k3 < DIV; k3++) sample_value += data[col + (k4*hdr->SPR + k5*DIV + k3)*hdr->data.size[0]]; } else { for (k3=0, sample_value=0.0; k3 < DIV; k3++) sample_value += data[col*nelem*hdr->SPR + k4*hdr->SPR + k5*DIV + k3]; } */ #ifdef ZLIB_H if (H1.FILE.COMPRESSION) gzprintf(H1.FILE.gzFID,"%g\n",i/DIV); else #endif fprintf(H1.FILE.FID,"%g\n",i/DIV); } } else if (hdr->TYPE == BIN) { size_t nbytes = ((size_t)hdr->CHANNEL[k1].SPR * GDFTYP_BITS[hdr->CHANNEL[k1].GDFTYP])>>3; ifwrite(hdr->AS.rawdata+hdr->CHANNEL[k1].bi, nbytes, hdr->NRec, &H1); } ifclose(&H1); } count = hdr->NRec; free(fn); } else #endif //ONLYGDF if ((hdr->TYPE != SCP_ECG) && (hdr->TYPE != HL7aECG)) { // for SCP: writing to file is done in SCLOSE if (VERBOSE_LEVEL>7) fprintf(stdout,"swrite 317 <%s>\n", hdr->FileName ); count = ifwrite((uint8_t*)(hdr->AS.rawdata), hdr->AS.bpb, hdr->NRec, hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"swrite 319 <%i>\n", (int)count); } else { // SCP_ECG, HL7aECG #ifdef ONLYGDF assert(0); #endif //ONLYGDF count = 1; } // set position of file handle hdr->FILE.POS += count; return(count); } // end of SWRITE /****************************************************************************/ /** SEOF **/ /****************************************************************************/ int seof(HDRTYPE* hdr) { return (hdr->FILE.POS >= (size_t)hdr->NRec); } /****************************************************************************/ /** SREWIND **/ /****************************************************************************/ void srewind(HDRTYPE* hdr) { sseek(hdr,0,SEEK_SET); return; } /****************************************************************************/ /** SSEEK **/ /****************************************************************************/ int sseek(HDRTYPE* hdr, ssize_t offset, int whence) { int64_t pos=0; if (whence < 0) pos = offset * hdr->AS.bpb; else if (whence == 0) pos = (hdr->FILE.POS + offset) * hdr->AS.bpb; else if (whence > 0) pos = (hdr->NRec + offset) * hdr->AS.bpb; if ((pos < 0) | (pos > hdr->NRec * hdr->AS.bpb)) return(-1); else if (ifseek(hdr, pos + hdr->HeadLen, SEEK_SET)) return(-1); hdr->FILE.POS = pos / (hdr->AS.bpb); return(0); } // end of SSEEK /****************************************************************************/ /** STELL **/ /****************************************************************************/ ssize_t stell(HDRTYPE* hdr) { ssize_t pos = iftell(hdr); if (pos<0) return(-1); else if ((size_t)pos != (hdr->FILE.POS * hdr->AS.bpb + hdr->HeadLen)) return(-1); else return(hdr->FILE.POS); } // end of STELL /****************************************************************************/ /** SCLOSE **/ /****************************************************************************/ int sclose(HDRTYPE* hdr) { ssize_t pos, len; if (VERBOSE_LEVEL>6) fprintf(stdout,"SCLOSE( %s ) MODE=%i\n",hdr->FileName, hdr->FILE.OPEN); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): sclose\n",__FILE__,__LINE__); if (hdr==NULL) return(0); size_t k; for (k=0; kNS; k++) { // replace Nihon-Kohden code with standard code if (hdr->CHANNEL[k].GDFTYP==128) hdr->CHANNEL[k].GDFTYP=3; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): sclose OPEN=%i %s\n",__FILE__,__LINE__,hdr->FILE.OPEN,GetFileTypeString(hdr->TYPE)); #if defined(WITH_FEF) && !defined(ONLYGDF) if (hdr->TYPE == FEF) sclose_fef_read(hdr); #endif #ifndef WITHOUT_NETWORK if (hdr->FILE.Des>0) { // network connection if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): sclose\n",__FILE__,__LINE__); if (hdr->FILE.OPEN > 1) bscs_send_evt(hdr->FILE.Des,hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): sclose\n",__FILE__,__LINE__); int s = bscs_close(hdr->FILE.Des); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): sclose\n",__FILE__,__LINE__); if (s & ERR_MASK) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): bscs_close failed (err %i %08x)\n",__FILE__,__LINE__,s,s); biosigERROR(hdr, B4C_SCLOSE_FAILED, "bscs_close failed"); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): sclose\n",__FILE__,__LINE__); hdr->FILE.Des = 0; hdr->FILE.OPEN = 0; bscs_disconnect(hdr->FILE.Des); } else #endif if ((hdr->FILE.OPEN>1) && ((hdr->TYPE==GDF) || (hdr->TYPE==EDF) || (hdr->TYPE==BDF))) { if (VERBOSE_LEVEL>7) fprintf(stdout,"sclose(121) nrec= %i\n",(int)hdr->NRec); // WRITE HDR.NRec pos = (iftell(hdr)-hdr->HeadLen); if (hdr->NRec<0) { union { char tmp[88]; int64_t i64; } t; if (pos>0) hdr->NRec = pos/hdr->AS.bpb; else hdr->NRec = 0; if (hdr->TYPE==GDF) { t.i64 = htole64(hdr->NRec); len = sizeof(hdr->NRec); } else { len = sprintf(t.tmp,"%d",(int)hdr->NRec); if (len>8) fprintf(stderr,"Warning: NRec is (%s) to long.\n",t.tmp); } /* ### FIXME : gzseek supports only forward seek */ if (hdr->FILE.COMPRESSION>0) fprintf(stderr,"Warning: writing NRec in gz-file requires gzseek which may not be supported.\n"); ifseek(hdr,236,SEEK_SET); ifwrite(t.tmp,len,1,hdr); } if (VERBOSE_LEVEL>7) fprintf(stdout, "888: File Type=%s ,N#of Events %i,bpb=%i\n",GetFileTypeString(hdr->TYPE),hdr->EVENT.N,hdr->AS.bpb); if ((hdr->TYPE==GDF) && (hdr->EVENT.N>0)) { size_t len = hdrEVT2rawEVT(hdr); ifseek(hdr, hdr->HeadLen + hdr->AS.bpb*hdr->NRec, SEEK_SET); ifwrite(hdr->AS.rawEventData, len, 1, hdr); // write_gdf_eventtable(hdr); } } #ifndef ONLYGDF else if ((hdr->FILE.OPEN>1) && (hdr->TYPE==ATF)) { fprintf(hdr->FILE.FID, "\n"); } else if ((hdr->FILE.OPEN>1) && (hdr->TYPE==SCP_ECG)) { uint16_t crc; uint8_t* ptr; // pointer to memory mapping of the file layout hdr->AS.rawdata = NULL; struct aecg* aECG = (struct aecg*)hdr->aECG; if (aECG->Section5.Length>0) { // compute CRC for Section 5 uint16_t crc = CRCEvaluate(hdr->AS.Header + aECG->Section5.StartPtr+2,aECG->Section5.Length-2); // compute CRC leu16a(crc, hdr->AS.Header + aECG->Section5.StartPtr); } if (aECG->Section6.Length>0) { // compute CRC for Section 6 uint16_t crc = CRCEvaluate(hdr->AS.Header + aECG->Section6.StartPtr+2,aECG->Section6.Length-2); // compute CRC leu16a(crc, hdr->AS.Header + aECG->Section6.StartPtr); } if (aECG->Section7.Length>0) { // compute CRC for Section 7 uint16_t crc = CRCEvaluate(hdr->AS.Header + aECG->Section7.StartPtr+2,aECG->Section7.Length-2); // compute CRC leu16a(crc, hdr->AS.Header + aECG->Section7.StartPtr); } if ((aECG->Section12.Length>0) && (hdr->VERSION > 2.5)) { // compute CRC for Section 12 uint16_t crc = CRCEvaluate(hdr->AS.Header + aECG->Section12.StartPtr+2,aECG->Section12.Length-2); // compute CRC leu16a(crc, hdr->AS.Header + aECG->Section12.StartPtr); } // compute crc and len and write to preamble ptr = hdr->AS.Header; leu32a(hdr->HeadLen, ptr+2); crc = CRCEvaluate(ptr+2,hdr->HeadLen-2); leu16a(crc, ptr); ifwrite(hdr->AS.Header, sizeof(char), hdr->HeadLen, hdr); } else if ((hdr->FILE.OPEN>1) && (hdr->TYPE==HL7aECG)) { sclose_HL7aECG_write(hdr); hdr->FILE.OPEN = 0; } #endif //ONLYGDF if (hdr->FILE.OPEN > 0) { int status = ifclose(hdr); if (status) iferror(hdr); hdr->FILE.OPEN = 0; } return(0); } /****************************************************************************/ /** Error Handling **/ /****************************************************************************/ void biosigERROR(HDRTYPE *hdr, enum B4C_ERROR errnum, const char *errmsg) { /* sets the local and the (deprecated) global error variables B4C_ERRNUM and B4C_ERRMSG the global error variables are kept for backwards compatibility. */ #if (BIOSIG_VERSION < 10500) #ifndef ONLYGDF B4C_ERRNUM = errnum; B4C_ERRMSG = errmsg; #endif //ONLYGDF #endif hdr->AS.B4C_ERRNUM = errnum; hdr->AS.B4C_ERRMSG = errmsg; } #if (BIOSIG_VERSION < 10500) #ifndef ONLYGDF // do not expose deprecated interface in libgdf int serror() { int status = B4C_ERRNUM; fprintf(stderr,"Warning: use of function SERROR() is deprecated - use SERROR2() instead"); if (status) { fprintf(stderr,"ERROR %i: %s\n",B4C_ERRNUM,B4C_ERRMSG); B4C_ERRNUM = B4C_NO_ERROR; } return(status); } #endif //ONLYGDF #endif int serror2(HDRTYPE *hdr) { int status = hdr->AS.B4C_ERRNUM; if (status) { fprintf(stderr,"ERROR %i: %s\n",hdr->AS.B4C_ERRNUM,hdr->AS.B4C_ERRMSG); hdr->AS.B4C_ERRNUM = B4C_NO_ERROR; hdr->AS.B4C_ERRMSG = NULL; } return(status); } char *biosig_get_errormsg(HDRTYPE *hdr) { if (hdr==NULL) return NULL; if (hdr->AS.B4C_ERRNUM==0) return NULL; return strdup(hdr->AS.B4C_ERRMSG); }; int biosig_check_error(HDRTYPE *hdr) { if (hdr==NULL) return B4C_NO_ERROR; return hdr->AS.B4C_ERRNUM; }; /****************************************************************************/ /* Write / Update Event Table in GDF file */ /* */ /* returns 0 in case of success */ /* returns -1 in case of failure */ /****************************************************************************/ int sflush_gdf_event_table(HDRTYPE* hdr) { if ((hdr->TYPE!=GDF) || hdr->FILE.COMPRESSION) return(-1); ssize_t filepos = iftell(hdr); ifclose(hdr); hdr = ifopen(hdr,"rb+"); if (!hdr->FILE.OPEN) { /* file cannot be opened in write mode */ hdr = ifopen(hdr,"rb"); return(-1); } size_t len = hdrEVT2rawEVT(hdr); ifseek(hdr, hdr->HeadLen + hdr->AS.bpb*hdr->NRec, SEEK_SET); ifwrite(hdr->AS.rawEventData, len, 1, hdr); // write_gdf_eventtable(hdr); ifseek(hdr,filepos,SEEK_SET); return(0); } void fprintf_json_double(FILE *fid, const char* Name, double val) { fprintf(fid,"\t\t\"%s\"\t: %g", Name, val); } /****************************************************************************/ /** HDR2ASCII **/ /** displaying header information **/ /****************************************************************************/ int asprintf_hdr2json(char **str, HDRTYPE *hdr) { size_t k; char tmp[41]; char flag_comma = 0; size_t sz = 25*50 + hdr->NS * 16 * 50 + hdr->EVENT.N * 6 * 50; // rough estimate of memory needed size_t c = 0; *str = (char*) realloc(*str, sz); #define STR ((*str)+c) if (VERBOSE_LEVEL>7) fprintf(stdout, "asprintf_hdr2json: sz=%i\n", (int)sz); size_t NumberOfSweeps = (hdr->SPR*hdr->NRec > 0); size_t NumberOfUserSpecifiedEvents = 0; for (k = 0; k < hdr->EVENT.N; k++) { if (hdr->EVENT.TYP[k] < 255) NumberOfUserSpecifiedEvents++; else if (hdr->EVENT.TYP[k]==0x7ffe) NumberOfSweeps++; } c += sprintf(STR, "\n{\n"); c += sprintf(STR, "\t\"TYPE\"\t: \"%s\",\n",GetFileTypeString(hdr->TYPE)); c += sprintf(STR, "\t\"VERSION\"\t: %4.2f,\n",hdr->VERSION); c += sprintf(STR, "\t\"Filename\"\t: \"%s\",\n",hdr->FileName); c += sprintf(STR, "\t\"NumberOfChannels\"\t: %i,\n",(int)hdr->NS); c += sprintf(STR, "\t\"NumberOfRecords\"\t: %i,\n",(int)hdr->NRec); c += sprintf(STR, "\t\"SamplesPerRecords\"\t: %i,\n",(int)hdr->SPR); c += sprintf(STR, "\t\"NumberOfSamples\"\t: %i,\n",(int)(hdr->NRec*hdr->SPR)); if ((0.0 <= hdr->SampleRate) && (hdr->SampleRate < INFINITY)) c += sprintf(STR, "\t\"Samplingrate\"\t: %f,\n",hdr->SampleRate); snprintf_gdfdatetime(tmp, 40, hdr->T0); c += sprintf(STR, "\t\"StartOfRecording\"\t: \"%s\",\n",tmp); c += sprintf(STR, "\t\"TimezoneMinutesEastOfUTC\"\t: %i,\n", hdr->tzmin); c += sprintf(STR, "\t\"NumberOfSweeps\"\t: %d,\n",(unsigned)NumberOfSweeps); c += sprintf(STR, "\t\"NumberOfGroupsOrUserSpecifiedEvents\"\t: %d,\n", (unsigned)NumberOfUserSpecifiedEvents); c += sprintf(STR, "\t\"Patient\"\t: {\n"); if (strlen(hdr->Patient.Name)) { c += sprintf(STR, "\t\t\"Name\"\t: \"%s\",\n", hdr->Patient.Name); char Name[MAX_LENGTH_NAME+1]; strcpy(Name, hdr->Patient.Name); char *lastname = strtok(Name,"\x1f"); char *firstname = strtok(NULL,"\x1f"); char *secondlastname = strtok(NULL,"\x1f"); c += sprintf(STR, "\t\t\"Lastname\"\t: \"%s\",\n", lastname); c += sprintf(STR, "\t\t\"Firstname\"\t: \"%s\",\n", firstname); c += sprintf(STR, "\t\t\"Second_Lastname\"\t: \"%s\",\n", secondlastname); } if (hdr->Patient.Id) c += sprintf(STR, "\t\t\"Id\"\t: \"%s\",\n", hdr->Patient.Id); if (hdr->Patient.Weight) c += sprintf(STR, "\t\t\"Weight\"\t: \"%i kg\",\n", hdr->Patient.Weight); if (hdr->Patient.Height) c += sprintf(STR, "\t\t\"Height\"\t: \"%i cm\",\n", hdr->Patient.Height); if (hdr->Patient.Birthday>0) c += sprintf(STR, "\t\t\"Age\"\t: %i,\n", (int)((hdr->T0 - hdr->Patient.Birthday)/ldexp(365.25,32)) ); c += sprintf(STR, "\t\t\"Gender\"\t: \"%s\"\n", hdr->Patient.Sex==1 ? "Male" : "Female"); // no comma at the end because its the last element c += sprintf(STR, "\t},\n"); // end-of-Patient if (hdr->ID.Manufacturer.Name || hdr->ID.Manufacturer.Model || hdr->ID.Manufacturer.Version || hdr->ID.Manufacturer.SerialNumber) { c += sprintf(STR,"\t\"Manufacturer\"\t: {\n"); flag_comma = 0; if (hdr->ID.Manufacturer.Name) { c += sprintf(STR,"\t\t\"Name\"\t: \"%s\"", hdr->ID.Manufacturer.Name); flag_comma = 1; } if (hdr->ID.Manufacturer.Model) { if (flag_comma) c += sprintf(STR,",\n"); c += sprintf(STR,"\t\t\"Model\"\t: \"%s\"", hdr->ID.Manufacturer.Model); flag_comma = 1; } if (hdr->ID.Manufacturer.Version) { if (flag_comma) c += sprintf(STR,",\n"); c += sprintf(STR,"\t\t\"Version\"\t: \"%s\"", hdr->ID.Manufacturer.Version); flag_comma = 1; } if (hdr->ID.Manufacturer.SerialNumber) { if (flag_comma) c += sprintf(STR,",\n"); c += sprintf(STR,"\t\t\"SerialNumber\"\t: \"%s\"", hdr->ID.Manufacturer.SerialNumber); } c += sprintf(STR,"\n\t},\n"); // end-of-Manufacturer } c += sprintf(STR,"\t\"CHANNEL\"\t: ["); if (VERBOSE_LEVEL>7) fprintf(stdout, "asprintf_hdr2json: count=%i\n", (int)c); for (k = 0; k < hdr->NS; k++) { if (sz < c + 1000) { // double allocated memory sz *= 2; *str = (char*) realloc(*str, sz); } CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (k>0) c += sprintf(STR,","); c += sprintf(STR,"\n\t\t{\n"); c += sprintf(STR,"\t\t\"ChannelNumber\"\t: %i,\n", (int)k+1); c += sprintf(STR,"\t\t\"Label\"\t: \"%s\",\n", hc->Label); double fs = hdr->SampleRate * hc->SPR/hdr->SPR; if ((0.0 <= fs) && (fs < INFINITY)) c += sprintf(STR, "\t\t\"Samplingrate\"\t: %f,\n", fs); if ( hc->Transducer && strlen(hc->Transducer) ) c += sprintf(STR,"\t\t\"Transducer\"\t: \"%s\",\n", hc->Transducer); if (!isnan(hc->PhysMax)) c += sprintf(STR,"\t\t\"PhysicalMaximum\"\t: %g,\n", hc->PhysMax); if (!isnan(hc->PhysMin)) c += sprintf(STR,"\t\t\"PhysicalMinimum\"\t: %g,\n", hc->PhysMin); if (!isnan(hc->DigMax)) c += sprintf(STR,"\t\t\"DigitalMaximum\"\t: %f,\n", hc->DigMax); if (!isnan(hc->DigMin)) c += sprintf(STR,"\t\t\"DigitalMinimum\"\t: %f,\n", hc->DigMin); if (!isnan(hc->Cal)) c += sprintf(STR,"\t\t\"scaling\"\t: %g,\n", hc->Cal); if (!isnan(hc->Off)) c += sprintf(STR,"\t\t\"offset\"\t: %g,\n", hc->Off); if (!isnan(hc->TOffset)) c += sprintf(STR,"\t\t\"TimeDelay\"\t: %g", hc->TOffset); uint8_t flag = (0 < hc->LowPass && hc->LowPassHighPass && hc->HighPassNotch && hc->NotchLowPass, flag & 0x06 ? ',' : ' '); if (flag & 0x02) c += sprintf(STR, "\t\t\t\"Highpass\"\t: %g%c\n", hc->HighPass, flag & 0x04 ? ',' : ' ' ); if (flag & 0x04) c += sprintf(STR, "\t\t\t\"Notch\"\t: %g\n", hc->Notch); c += sprintf(STR, "\n\t\t},\n"); } switch (hc->PhysDimCode & 0xffe0) { case 4256: // Volt if (!isnan(hc->Impedance)) c += sprintf(STR, "\t\t\"Impedance\"\t: %g,\n", hc->Impedance); break; case 4288: // Ohm if (!isnan(hc->fZ)) c += sprintf(STR, "\t\t\"fZ\"\t: %g,\n", hc->fZ); break; } c += sprintf(STR,"\t\t\"PhysicalUnit\"\t: \"%s\"", PhysDim3(hc->PhysDimCode)); c += sprintf(STR, "\n\t\t}"); // end-of-CHANNEL } c += sprintf(STR, "\n\t]"); // end-of-CHANNELS if (VERBOSE_LEVEL>7) fprintf(stdout, "asprintf_hdr2json: count=%i\n", (int)c); if (hdr->EVENT.N>0) { c += sprintf(STR, ",\n\t\"EVENT\"\t: ["); flag_comma = 0; for (k = 0; k < hdr->EVENT.N; k++) { if ( hdr->EVENT.TYP[k] == 0 ) continue; if (sz < c + 1000) { // double allocated memory sz *= 2; *str = (char*) realloc(*str, sz); } if ( flag_comma ) c += sprintf(STR,","); c += sprintf(STR, "\n\t\t{\n"); c += sprintf(STR, "\t\t\"TYP\"\t: \"0x%04x\",\n", hdr->EVENT.TYP[k]); c += sprintf(STR, "\t\t\"POS\"\t: %f", hdr->EVENT.POS[k]/hdr->EVENT.SampleRate); if (hdr->EVENT.CHN && hdr->EVENT.DUR) { if (hdr->EVENT.CHN[k]) c += sprintf(STR, ",\n\t\t\"CHN\"\t: %d", hdr->EVENT.CHN[k]); if (hdr->EVENT.TYP[k] != 0x7fff) c += sprintf(STR, ",\n\t\t\"DUR\"\t: %f", hdr->EVENT.DUR[k]/hdr->EVENT.SampleRate); } if (hdr->EVENT.TimeStamp != NULL && hdr->EVENT.TimeStamp[k] != 0) { char buf[255]; snprintf_gdfdatetime(buf, sizeof(buf), hdr->EVENT.TimeStamp[k]); c += sprintf(STR,",\n\t\t\"TimeStamp\"\t: \"%s\"", buf); } if (hdr->EVENT.TYP[k] == 0x7fff) { // c += sprintf(STR, ",\n\t\t\"Description\"\t: \"[sparse sample]\""); typeof(hdr->NS) chan = hdr->EVENT.CHN[k] - 1; double val = dur2val(hdr->EVENT.DUR[k], hdr->CHANNEL[chan].GDFTYP); val *= hdr->CHANNEL[chan].Cal; val += hdr->CHANNEL[chan].Off; if (isfinite(val)) c += sprintf(STR, ",\n\t\t\"Value\"\t: %g", val); // no comma at the end because its the last element } else { const char *tmpstr = GetEventDescription(hdr,k); if (tmpstr != NULL) c += sprintf(STR, ",\n\t\t\"Description\"\t: \"%s\"", tmpstr); // no comma at the end because its the last element } c += sprintf(STR, "\n\t\t}"); flag_comma = 1; } c += sprintf(STR, "\n\t]"); // end-of-EVENT } c += sprintf(STR, "\n}\n"); if (VERBOSE_LEVEL>7) fprintf(stdout, "asprintf_hdr2json: count=%i\n", (int)c); return (0); #undef STR } /****************************************************************************/ /** HDR2ASCII **/ /** displaying header information **/ /****************************************************************************/ #if (BIOSIG_VERSION < 10500) // for backwards compatibility ATT_DEPREC int hdr2json( HDRTYPE *hdr, FILE *fid) { return fprintf_hdr2json(fid, hdr); } // deprecated since Oct 2012, v1.4.0 #endif int fprintf_hdr2json(FILE *fid, HDRTYPE* hdr) { size_t k; char tmp[41]; char flag_comma = 0; size_t NumberOfSweeps = (hdr->SPR*hdr->NRec > 0); size_t NumberOfUserSpecifiedEvents = 0; for (k = 0; k < hdr->EVENT.N; k++) { if (hdr->EVENT.TYP[k] < 255) NumberOfUserSpecifiedEvents++; else if (hdr->EVENT.TYP[k]==0x7ffe) NumberOfSweeps++; } fprintf(fid,"{\n"); fprintf(fid,"\t\"TYPE\"\t: \"%s\",\n",GetFileTypeString(hdr->TYPE)); fprintf(fid,"\t\"VERSION\"\t: %4.2f,\n",hdr->VERSION); fprintf(fid,"\t\"Filename\"\t: \"%s\",\n",hdr->FileName); fprintf(fid,"\t\"NumberOfChannels\"\t: %i,\n",(int)hdr->NS); fprintf(fid,"\t\"NumberOfRecords\"\t: %i,\n",(int)hdr->NRec); fprintf(fid,"\t\"SamplesPerRecords\"\t: %i,\n",(int)hdr->SPR); fprintf(fid,"\t\"NumberOfSamples\"\t: %i,\n",(int)(hdr->NRec*hdr->SPR)); if ((0.0 <= hdr->SampleRate) && (hdr->SampleRate < INFINITY)) fprintf(fid,"\t\"Samplingrate\"\t: %f,\n", hdr->SampleRate); snprintf_gdfdatetime(tmp, 40, hdr->T0); fprintf(fid,"\t\"StartOfRecording\"\t: \"%s\",\n",tmp); fprintf(fid,"\t\"TimezoneMinutesEastOfUTC\"\t: %i,\n", hdr->tzmin); fprintf(fid,"\t\"NumberOfSweeps\"\t: %d,\n",(unsigned)NumberOfSweeps); fprintf(fid,"\t\"NumberOfGroupsOrUserSpecifiedEvents\"\t: %d,\n",(unsigned)NumberOfUserSpecifiedEvents); fprintf(fid,"\t\"Patient\"\t: {\n"); if (strlen(hdr->Patient.Name)) { fprintf(fid, "\t\t\"Name\"\t: \"%s\",\n", hdr->Patient.Name); char Name[MAX_LENGTH_NAME+1]; strcpy(Name, hdr->Patient.Name); char *lastname = strtok(Name,"\x1f"); char *firstname = strtok(NULL,"\x1f"); char *secondlastname = strtok(NULL,"\x1f"); fprintf(fid, "\t\t\"Lastname\"\t: \"%s\",\n", lastname); fprintf(fid, "\t\t\"Firstname\"\t: \"%s\",\n", firstname); fprintf(fid, "\t\t\"Second_Lastname\"\t: \"%s\",\n", secondlastname); } if (hdr->Patient.Id) fprintf(fid,"\t\t\"Id\"\t: \"%s\",\n", hdr->Patient.Id); if (hdr->Patient.Weight) fprintf(fid,"\t\t\"Weight\"\t: \"%i kg\",\n", hdr->Patient.Weight); if (hdr->Patient.Height) fprintf(fid,"\t\t\"Height\"\t: \"%i cm\",\n", hdr->Patient.Height); if (hdr->Patient.Birthday>0) fprintf(fid,"\t\t\"Age\"\t: %i,\n", (int)((hdr->T0 - hdr->Patient.Birthday)/ldexp(365.25,32)) ); fprintf(fid,"\t\t\"Gender\"\t: \"%s\"\n", hdr->Patient.Sex==1 ? "Male" : "Female"); // no comma at the end because its the last element fprintf(fid,"\t},\n"); // end-of-Patient if (hdr->ID.Manufacturer.Name || hdr->ID.Manufacturer.Model || hdr->ID.Manufacturer.Version || hdr->ID.Manufacturer.SerialNumber) { fprintf(fid,"\t\"Manufacturer\"\t: {\n"); flag_comma = 0; if (hdr->ID.Manufacturer.Name) { fprintf(fid,"\t\t\"Name\"\t: \"%s\"", hdr->ID.Manufacturer.Name); flag_comma = 1; } if (hdr->ID.Manufacturer.Model) { if (flag_comma) fprintf(fid,",\n"); fprintf(fid,"\t\t\"Model\"\t: \"%s\"", hdr->ID.Manufacturer.Model); flag_comma = 1; } if (hdr->ID.Manufacturer.Version) { if (flag_comma) fprintf(fid,",\n"); fprintf(fid,"\t\t\"Version\"\t: \"%s\"", hdr->ID.Manufacturer.Version); flag_comma = 1; } if (hdr->ID.Manufacturer.SerialNumber) { if (flag_comma) fprintf(fid,",\n"); fprintf(fid,"\t\t\"SerialNumber\"\t: \"%s\"", hdr->ID.Manufacturer.SerialNumber); // no comma at the end because its the last element } fprintf(fid,"\n\t},\n"); // end-of-Manufacturer } fprintf(fid,"\t\"CHANNEL\"\t: ["); for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; if (k>0) fprintf(fid,","); fprintf(fid,"\n\t\t{\n"); fprintf(fid,"\t\t\"ChannelNumber\"\t: %i,\n", (int)k+1); fprintf(fid,"\t\t\"Label\"\t: \"%s\",\n", hc->Label); double fs = hdr->SampleRate * hc->SPR/hdr->SPR; if ((0.0 <= fs) && (fs < INFINITY)) fprintf(fid,"\t\t\"Samplingrate\"\t: %f,\n", fs); if ( hc->Transducer && strlen(hc->Transducer) ) fprintf(fid,"\t\t\"Transducer\"\t: \"%s\",\n", hc->Transducer); if (!isnan(hc->PhysMax)) fprintf(fid,"\t\t\"PhysicalMaximum\"\t: %g,\n", hc->PhysMax); if (!isnan(hc->PhysMin)) fprintf(fid,"\t\t\"PhysicalMinimum\"\t: %g,\n", hc->PhysMin); if (!isnan(hc->DigMax)) fprintf(fid,"\t\t\"DigitalMaximum\"\t: %f,\n", hc->DigMax); if (!isnan(hc->DigMin)) fprintf(fid,"\t\t\"DigitalMinimum\"\t: %f,\n", hc->DigMin); if (!isnan(hc->Cal)) fprintf(fid,"\t\t\"scaling\"\t: %g,\n", hc->Cal); if (!isnan(hc->Off)) fprintf(fid,"\t\t\"offset\"\t: %g,\n", hc->Off); if (!isnan(hc->TOffset)) fprintf(fid,"\t\t\"TimeDelay\"\t: %g,\n", hc->TOffset); uint8_t flag = (0 < hc->LowPass && hc->LowPassHighPass && hc->HighPassNotch && hc->NotchLowPass, flag & 0x06 ? ',' : ' '); if (flag & 0x02) fprintf(fid,"\t\t\t\"Highpass\"\t: %g%c\n",hc->HighPass, flag & 0x04 ? ',' : ' ' ); if (flag & 0x04) fprintf(fid,"\t\t\t\"Notch\"\t: %g\n",hc->Notch); fprintf(fid,"\n\t\t},\n"); } switch (hc->PhysDimCode & 0xffe0) { case 4256: // Volt if (!isnan(hc->Impedance)) fprintf(fid,"\t\t\"Impedance\"\t: %g,\n", hc->Impedance); break; case 4288: // Ohm if (!isnan(hc->fZ)) fprintf(fid,"\t\t\"fZ\"\t: %g,\n", hc->fZ); break; } fprintf(fid,"\t\t\"PhysicalUnit\"\t: \"%s\"", PhysDim3(hc->PhysDimCode)); // no comma at the end because its the last element fprintf(fid,"\n\t\t}"); // end-of-CHANNEL } fprintf(fid,"\n\t]"); // end-of-CHANNELS if (hdr->EVENT.N>0) { flag_comma = 0; fprintf(fid,",\n\t\"EVENT\"\t: ["); for (k = 0; k < hdr->EVENT.N; k++) { if ( hdr->EVENT.TYP[k] == 0 ) continue; if ( flag_comma ) fprintf(fid,","); fprintf(fid,"\n\t\t{\n"); fprintf(fid,"\t\t\"TYP\"\t: \"0x%04x\",\n", hdr->EVENT.TYP[k]); fprintf(fid,"\t\t\"POS\"\t: %f", hdr->EVENT.POS[k]/hdr->EVENT.SampleRate); if (hdr->EVENT.CHN && hdr->EVENT.DUR) { if (hdr->EVENT.CHN[k]) fprintf(fid,",\n\t\t\"CHN\"\t: %d", hdr->EVENT.CHN[k]); if (hdr->EVENT.TYP[k] != 0x7fff) fprintf(fid,",\n\t\t\"DUR\"\t: %f", hdr->EVENT.DUR[k]/hdr->EVENT.SampleRate); } if (hdr->EVENT.TimeStamp != NULL && hdr->EVENT.TimeStamp[k] != 0) { char buf[255]; snprintf_gdfdatetime(buf,sizeof(buf), hdr->EVENT.TimeStamp[k]); fprintf(fid,",\n\t\t\"TimeStamp\"\t: \"%s\"", buf); } if ((hdr->EVENT.TYP[k] == 0x7fff) && (hdr->TYPE==GDF)) { //fprintf(fid,"\t\t\"Description\"\t: [neds]\n"); // no comma at the end because its the last element //fprintf(fid,",\n\t\t\"Description\"\t: \"[sparse sample]\""); typeof(hdr->NS) chan = hdr->EVENT.CHN[k] - 1; double val = dur2val(hdr->EVENT.DUR[k], hdr->CHANNEL[chan].GDFTYP); val *= hdr->CHANNEL[chan].Cal; val += hdr->CHANNEL[chan].Off; if (isfinite(val)) fprintf(fid,",\n\t\t\"Value\"\t: %g", val); // no comma at the end because its the last element } else { const char *str = GetEventDescription(hdr,k); if (str != NULL) fprintf(fid,",\n\t\t\"Description\"\t: \"%s\"",str); // no comma at the end because its the last element } fprintf(fid,"\n\t\t}"); flag_comma = 1; } fprintf(fid,"\n\t]"); // end-of-EVENT } fprintf(fid,"\n}\n"); return (0); } /****************************************************************************/ /** HDR2ASCII **/ /** displaying header information **/ /****************************************************************************/ int hdr2ascii(HDRTYPE* hdr, FILE *fid, int VERBOSE) { CHANNEL_TYPE* cp; struct tm *T0; float age; if (VERBOSE==7) { char tmp[60]; snprintf_gdfdatetime(tmp, sizeof(tmp), hdr->T0); fprintf(fid,"\tStartOfRecording: %s\nbci2000: %p\n",tmp,hdr->AS.bci2000); return(0); } if (VERBOSE==-1) { return(fprintf_hdr2json(fid, hdr)); } if (VERBOSE>0) { /* demographic information */ fprintf(fid,"\n===========================================\n[FIXED HEADER]\n"); // fprintf(fid,"\nPID:\t|%s|\nPatient:\n",hdr->AS.PID); fprintf(fid, "Recording:\n\tID : %s\n",hdr->ID.Recording); fprintf(fid, "\tInstitution : %s\n",hdr->ID.Hospital); fprintf(fid, "\tTechnician : %s\t# default: localuser\n",hdr->ID.Technician); char tmp[60]; strncpy(tmp,(char*)&hdr->ID.Equipment,8); tmp[8] = 0; fprintf(fid, "\tEquipment : %s\n",tmp); if (VERBOSE_LEVEL>8) fprintf(fid, "\t %#.16"PRIx64"\n",(uint64_t)hdr->ID.Equipment); uint8_t k,IPv6=0; for (k=4; k<16; k++) IPv6 |= hdr->IPaddr[k]; if (IPv6) fprintf(fid, "\tIPv6 address : %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",hdr->IPaddr[0],hdr->IPaddr[1],hdr->IPaddr[2],hdr->IPaddr[3],hdr->IPaddr[4],hdr->IPaddr[5],hdr->IPaddr[6],hdr->IPaddr[7],hdr->IPaddr[8],hdr->IPaddr[9],hdr->IPaddr[10],hdr->IPaddr[11],hdr->IPaddr[12],hdr->IPaddr[13],hdr->IPaddr[14],hdr->IPaddr[15]); else fprintf(fid, "\tIPv4 address : %u.%u.%u.%u",hdr->IPaddr[0],hdr->IPaddr[1],hdr->IPaddr[2],hdr->IPaddr[3]); fprintf(fid,"\t # default:local host\nManufacturer:\n\tName : %s\n",hdr->ID.Manufacturer.Name); fprintf(fid, "\tModel : %s\n",hdr->ID.Manufacturer.Model); fprintf(fid, "\tVersion : %s\n",hdr->ID.Manufacturer.Version); fprintf(fid, "\tSerialNumber : %s\n",hdr->ID.Manufacturer.SerialNumber); fprintf(fid, "Patient:\n\tID : %s\n",hdr->Patient.Id); if (strlen(hdr->Patient.Name)) { fprintf(fid, "\tName : %s\n",hdr->Patient.Name); char Name[MAX_LENGTH_NAME+1]; strcpy(Name, hdr->Patient.Name); char *lastname = strtok(Name,"\x1f"); char *firstname = strtok(NULL,"\x1f"); char *secondlastname = strtok(NULL,"\x1f"); fprintf(fid,"\t\tLastname : %s\n",lastname); fprintf(fid,"\t\tFirstname : %s\n",firstname); fprintf(fid,"\t\tSecondLastName : %s\n",secondlastname); } if (hdr->Patient.Birthday>0) age = (hdr->T0 - hdr->Patient.Birthday)/ldexp(365.25,32); else age = NAN; if (hdr->Patient.Height) fprintf(fid,"\tHeight : %i cm\n",hdr->Patient.Height); if (hdr->Patient.Height) fprintf(stdout,"\tWeight : %i kg\n",hdr->Patient.Weight); const char *Gender[] = {"unknown","male","female","unknown"}; const char *EyeImpairment[] = {"unknown","no","yes","corrected"}; const char *HeartImpairment[] = {"unknown","no","yes","pacemaker"}; fprintf(fid,"\tGender : %s\n",Gender[hdr->Patient.Sex]); fprintf(fid,"\tEye Impairment : %s\n",EyeImpairment[hdr->Patient.Impairment.Visual]); fprintf(fid,"\tHeart Impairment: %s\n",HeartImpairment[hdr->Patient.Impairment.Heart]); if (hdr->Patient.Birthday) { snprintf_gdfdatetime(tmp, sizeof(tmp), hdr->T0); fprintf(fid,"\tAge : %4.1f years\n\tBirthday : (%.6f) %s ",age,ldexp(hdr->Patient.Birthday,-32),tmp); } else fprintf(fid,"\tAge : ----\n\tBirthday : unknown\n"); snprintf_gdfdatetime(tmp, sizeof(tmp), hdr->T0); fprintf(fid,"\tStartOfRecording: (%.6f) %s",ldexp(hdr->T0,-32),tmp); fprintf(fid,"\tTimezone : %+i min\n\n", hdr->tzmin); if (hdr->AS.bci2000 != NULL) { if (VERBOSE < 4) { size_t c = min(39,strcspn(hdr->AS.bci2000,"\xa\xd")); strncpy(tmp, hdr->AS.bci2000, c); tmp[c]=0; fprintf(fid,"BCI2000 [%i]\t\t: <%s...>\n",(int)strlen(hdr->AS.bci2000),tmp); } else { fprintf(fid,"BCI2000 [%i]:\n%s\n",(int)strlen(hdr->AS.bci2000),hdr->AS.bci2000); } } fprintf(fid,"bpb=%i\n",hdr->AS.bpb); fprintf(fid,"row-based=%i\n",hdr->FLAG.ROW_BASED_CHANNELS); fprintf(fid,"uncalib =%i\n",hdr->FLAG.UCAL); fprintf(fid,"OFdetect =%i\n",hdr->FLAG.OVERFLOWDETECTION); } if (VERBOSE>1) { /* display header information */ fprintf(fid,"FileName:\t%s\nType :\t%s\nVersion :\t%4.2f\nHeadLen :\t%i\n",hdr->FileName,GetFileTypeString(hdr->TYPE),hdr->VERSION,hdr->HeadLen); // fprintf(fid,"NoChannels:\t%i\nSPR:\t\t%i\nNRec:\t\t%Li\nDuration[s]:\t%u/%u\nFs:\t\t%f\n",hdr->NS,hdr->SPR,hdr->NRec,hdr->Dur[0],hdr->Dur[1],hdr->SampleRate); fprintf(fid,"NoChannels:\t%i\nSPR:\t\t%i\nNRec:\t\t%li\nFs:\t\t%f\n",hdr->NS,hdr->SPR,(long)hdr->NRec,hdr->SampleRate); fprintf(fid,"Events/Annotations:\t%i\nEvents/SampleRate:\t%f\n",hdr->EVENT.N,hdr->EVENT.SampleRate); } if (VERBOSE>2) { /* channel settings */ fprintf(fid,"\n[CHANNEL HEADER] %p",hdr->CHANNEL); fprintf(fid,"\nNo LeadId Label\tFs[Hz]\tSPR\tGDFTYP\tCal\tOff\tPhysDim\tPhysMax \tPhysMin \tDigMax \tDigMin \tHighPass\tLowPass \tNotch \tdelay [s]\tX\tY\tZ"); size_t k; #ifdef CHOLMOD_H typeof(hdr->NS) NS = hdr->NS; if (hdr->Calib) NS += hdr->Calib->ncol; for (k=0; kNS) cp = hdr->CHANNEL+k; else cp = hdr->rerefCHANNEL + k - hdr->NS; #else for (k=0; kNS; k++) { cp = hdr->CHANNEL+k; #endif const char *tmpstr = cp->Label; if (tmpstr==NULL || strlen(tmpstr)==0) tmpstr = LEAD_ID_TABLE[cp->LeadIdCode]; fprintf(fid,"\n#%02i: %3i %i %-17s\t%5f %5i", (int)k+1, cp->LeadIdCode, cp->bi8, tmpstr, cp->SPR*hdr->SampleRate/hdr->SPR, cp->SPR); if (cp->GDFTYP<20) fprintf(fid," %s ",gdftyp_string[cp->GDFTYP]); else if (cp->GDFTYP>511) fprintf(fid, " bit%i ", cp->GDFTYP-511); else if (cp->GDFTYP>255) fprintf(fid, " bit%i ", cp->GDFTYP-255); tmpstr = PhysDim3(cp->PhysDimCode); if (tmpstr==NULL) tmpstr="\0"; fprintf(fid,"%e %e %s\t%g\t%g\t%5f\t%5f\t%5f\t%5f\t%5f\t%5g\t%5f\t%5f\t%5f", cp->Cal, cp->Off, tmpstr, cp->PhysMax, cp->PhysMin, cp->DigMax, cp->DigMin,cp->HighPass,cp->LowPass,cp->Notch,cp->TOffset, cp->XYZ[0],cp->XYZ[1],cp->XYZ[2]); //fprintf(fid,"\t %3i", cp->SPR); } } if (VERBOSE>3) { /* channel settings */ fprintf(fid,"\n\n[EVENT TABLE %i] N=%i Fs=%f", (hdr->EVENT.TimeStamp!=NULL) + (hdr->EVENT.TYP!=NULL) + (hdr->EVENT.POS!=NULL) + (hdr->EVENT.CHN!=NULL) + (hdr->EVENT.DUR!=NULL), hdr->EVENT.N,hdr->EVENT.SampleRate); fprintf(fid,"\nNo\tTYP\tPOS\tCHN\tDUR/VAL\tDesc"); size_t k; for (k=0; kEVENT.N; k++) { fprintf(fid,"\n%5i\t0x%04x\t%d",(int)(k+1),hdr->EVENT.TYP[k],hdr->EVENT.POS[k]); if (hdr->EVENT.TimeStamp != NULL && hdr->EVENT.TimeStamp[k] != 0) { char buf[255]; snprintf_gdfdatetime(buf,sizeof(buf), hdr->EVENT.TimeStamp[k]); fprintf(fid,"\t%s",buf); } if (hdr->EVENT.TYP[k] == 0x7fff) fprintf(fid,"\t%d",hdr->EVENT.CHN[k]); else if (hdr->EVENT.DUR != NULL) fprintf(fid,"\t%d\t%5d",hdr->EVENT.CHN[k],hdr->EVENT.DUR[k]); if ((hdr->EVENT.TYP[k] == 0x7fff) && (hdr->TYPE==GDF)) { typeof(hdr->NS) chan = hdr->EVENT.CHN[k]-1; double val = dur2val(hdr->EVENT.DUR[k], hdr->CHANNEL[chan].GDFTYP); val *= hdr->CHANNEL[chan].Cal; val += hdr->CHANNEL[chan].Off; fprintf(fid, "\t%g %s\t## sparse sample", val, PhysDim3(hdr->CHANNEL[chan].PhysDimCode)); // no comma at the end because its the last element } else { const char *str = GetEventDescription(hdr,k); if (str) fprintf(fid,"\t\t%s",str); } } } if (VERBOSE>4) { const char* StatusString[] = {"Original (not overread)", "Confirmed", "Overread (not confirmed)", "unknown"}; #if (BIOSIG_VERSION >= 10500) if (hdr->SCP.Section7) { fprintf(stdout,"\n\n=== SCP Section 7: Global measurements ===\n"); fprintf(stdout,"\n\n (report of this section is not implemented yet \n"); } if (hdr->SCP.Section8) { struct tm t; t.tm_year = leu16p(hdr->SCP.Section8+1)-1900; t.tm_mon = hdr->SCP.Section8[3]-1; t.tm_mday = hdr->SCP.Section8[4]; t.tm_hour = hdr->SCP.Section8[5]; t.tm_min = hdr->SCP.Section8[6]; t.tm_sec = hdr->SCP.Section8[7]; uint8_t NumberOfStatements = hdr->SCP.Section8[8]; fprintf(stdout,"\n\n=== SCP Section 8: Storage of full text interpretive statements ===\n"); fprintf(stdout,"Report %04i-%02i-%02i %02ih%02im%02is (Status=%s) %i statements\n",t.tm_year+1900,t.tm_mon+1,t.tm_mday,t.tm_hour,t.tm_min,t.tm_sec,StatusString[min(hdr->SCP.Section8[0],3)], NumberOfStatements); uint32_t curSectPos = 9; uint8_t k; for (k=0; k < NumberOfStatements;k++) { if (curSectPos+3 > hdr->SCP.Section8Length) break; fprintf(stdout, "%s\n", (char*)(hdr->SCP.Section8+curSectPos+3)); curSectPos += 3+leu16p(hdr->SCP.Section8+curSectPos+1); } } if (hdr->SCP.Section9) { struct tm t; t.tm_year = leu16p(hdr->SCP.Section9+1)-1900; t.tm_mon = hdr->SCP.Section9[3]-1; t.tm_mday = hdr->SCP.Section9[4]; t.tm_hour = hdr->SCP.Section9[5]; t.tm_min = hdr->SCP.Section9[6]; t.tm_sec = hdr->SCP.Section9[7]; uint8_t NumberOfStatements = hdr->SCP.Section9[8]; fprintf(stdout,"\n\n=== SCP Section 9: Storing manufacturer specific interpretive statements and data related to the overreading trail ===\n"); fprintf(stdout,"Report %04i-%02i-%02i %02ih%02im%02is (Status=%s) %i statements\n",t.tm_year+1900,t.tm_mon+1,t.tm_mday,t.tm_hour,t.tm_min,t.tm_sec,StatusString[min(hdr->SCP.Section8[0],3)], NumberOfStatements); uint32_t curSectPos = 9; uint8_t k; for (k=0; k < NumberOfStatements;k++) { if (curSectPos+3 > hdr->SCP.Section9Length) break; fprintf(stdout, "%s\n", (char*)(hdr->SCP.Section9+curSectPos+3)); curSectPos += 3+leu16p(hdr->SCP.Section9+curSectPos+1); } } if (hdr->SCP.Section10) { fprintf(stdout,"\n\n=== SCP Section 10: Lead measurement block ===\n"); fprintf(stdout,"\n\n (report of this section is not implemented yet \n"); } if (hdr->SCP.Section11) { struct tm t; t.tm_year = leu16p(hdr->SCP.Section11+1)-1900; t.tm_mon = hdr->SCP.Section11[3]-1; t.tm_mday = hdr->SCP.Section11[4]; t.tm_hour = hdr->SCP.Section11[5]; t.tm_min = hdr->SCP.Section11[6]; t.tm_sec = hdr->SCP.Section11[7]; uint8_t NumberOfStatements = hdr->SCP.Section11[8]; fprintf(stdout,"\n\n=== SCP Section 11: Storage of the universal ECG interpretive statement codes ===\n"); fprintf(stdout,"Report %04i-%02i-%02i %02ih%02im%02is (Status=%s) %i statements\n",t.tm_year+1900,t.tm_mon+1,t.tm_mday,t.tm_hour,t.tm_min,t.tm_sec,StatusString[min(hdr->SCP.Section8[0],3)], NumberOfStatements); uint32_t curSectPos = 9; uint8_t k; for (k=0; k < NumberOfStatements;k++) { if (curSectPos+3 > hdr->SCP.Section11Length) break; fprintf(stdout, "%s\n", (char*)(hdr->SCP.Section11+curSectPos+3)); curSectPos += 3+leu16p(hdr->SCP.Section11+curSectPos+1); } } #else if (hdr->aECG && (hdr->TYPE==SCP_ECG)) { struct aecg* aECG = (struct aecg*)hdr->aECG; fprintf(stdout,"\nInstitution Number: %i\n",aECG->Section1.Tag14.INST_NUMBER); fprintf(stdout,"DepartmentNumber : %i\n",aECG->Section1.Tag14.DEPT_NUMBER); fprintf(stdout,"Device Id : %i\n",aECG->Section1.Tag14.DEVICE_ID); fprintf(stdout,"Device Type : %i\n",aECG->Section1.Tag14.DeviceType); fprintf(stdout,"Manufacture code : %i\n",aECG->Section1.Tag14.MANUF_CODE); fprintf(stdout,"MOD_DESC : %s\n",aECG->Section1.Tag14.MOD_DESC); fprintf(stdout,"Version : %i\n",aECG->Section1.Tag14.VERSION); fprintf(stdout,"ProtCompLevel : %i\n",aECG->Section1.Tag14.PROT_COMP_LEVEL); fprintf(stdout,"LangSuppCode : %i\n",aECG->Section1.Tag14.LANG_SUPP_CODE); fprintf(stdout,"ECG_CAP_DEV : %i\n",aECG->Section1.Tag14.ECG_CAP_DEV); fprintf(stdout,"Mains Frequency : %i\n",aECG->Section1.Tag14.MAINS_FREQ); /* fprintf(stdout,"ANAL_PROG_REV_NUM : %s\n",aECG->Section1.Tag14.ANAL_PROG_REV_NUM); fprintf(stdout,"SERIAL_NUMBER_ACQ_DEV: %s\n",aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV); fprintf(stdout,"ACQ_DEV_SYS_SW_ID : %i\n",aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID); fprintf(stdout,"ACQ_DEV_SCP_SW : %i\n",aECG->Section1.Tag14.ACQ_DEV_SCP_SW); */ fprintf(stdout,"ACQ_DEV_MANUF : %s\n",aECG->Section1.Tag14.ACQ_DEV_MANUF); fprintf(stdout,"Compression HUFFMAN : %i\n",aECG->FLAG.HUFFMAN); fprintf(stdout,"Compression REF-BEAT: %i\n",aECG->FLAG.REF_BEAT); fprintf(stdout,"Compression BIMODAL : %i\n",aECG->FLAG.BIMODAL); fprintf(stdout,"Compression DIFF : %i\n",aECG->FLAG.DIFF); if ((aECG->systolicBloodPressure > 0.0) || (aECG->diastolicBloodPressure > 0.0)) fprintf(stdout,"Blood pressure (systolic/diastolic) : %3.0f/%3.0f mmHg\n",aECG->systolicBloodPressure,aECG->diastolicBloodPressure); uint8_t k; if (aECG->Section8.NumberOfStatements>0) { fprintf(stdout,"\n\nReport %04i-%02i-%02i %02ih%02im%02is (Status=%s)\n",aECG->Section8.t.tm_year+1900,aECG->Section8.t.tm_mon+1,aECG->Section8.t.tm_mday,aECG->Section8.t.tm_hour,aECG->Section8.t.tm_min,aECG->Section8.t.tm_sec,StatusString[min(aECG->Section8.Confirmed,3)]); for (k=0; kSection8.NumberOfStatements;k++) { fprintf(stdout,"%s\n",aECG->Section8.Statements[k]); } } if ( aECG->Section11.NumberOfStatements > 0 ) { fprintf(stdout,"\n\nReport %04i-%02i-%02i %02ih%02im%02is (Status=%s)\n",aECG->Section11.t.tm_year+1900,aECG->Section11.t.tm_mon+1,aECG->Section11.t.tm_mday,aECG->Section11.t.tm_hour,aECG->Section11.t.tm_min,aECG->Section11.t.tm_sec,StatusString[min(aECG->Section11.Confirmed,3)]); for (k=0; kSection11.NumberOfStatements;k++) { fprintf(stdout,"%s\n",aECG->Section11.Statements[k]); } } fprintf(stdout,"\n\nSection9:\n%s\n\n",aECG->Section9.StartPtr); } #endif // BIOSIGVERSION < 10500 } fprintf(fid,"\n\n"); return(0); } /* end of HDR2ASCII */ /****************************************************************************/ /** **/ /** EOF **/ /** **/ /****************************************************************************/ stimfit-0.16.7/src/biosig/biosig4c++/t210/0000775000175000017500000000000014764352501013420 5stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_cadwell_read.c0000664000175000017500000003035714752215315017324 /* Copyright (C) 2021 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "../biosig.h" /****************************************************************************** read CADWELL file formats (EAS, EZ3, ARC) ******************************************************************************/ void sopen_cadwell_read(HDRTYPE* hdr) { if (VERBOSE_LEVEL > 8) fprintf(stdout,"%s (line %d) %s(hdr)\n", __FILE__, __LINE__, __func__); if (hdr->TYPE==EAS) { /* 12 bit ADC ? 200 Hz 77*800 samples EEGData section has a periodicity of 202*2 (404 bytes) 800samples*16channels*2byte=25600 = 0x6400) */ hdr->NS = 16; // so far all example files had 16 channels hdr->SPR = 1; hdr->NRec = 0; hdr->SampleRate = 250; unsigned lengthHeader0 = leu32p(hdr->AS.Header + 0x30); unsigned lengthHeader1 = leu32p(hdr->AS.Header + 0x34); // this is varying amoung data sets - meaning unknown assert(lengthHeader0==0x0400); for (int k=0; k*0x20 < lengthHeader1; k++) { char *sectName = hdr->AS.Header + 0x6c + k*0x20; size_t sectPos= leu32p(hdr->AS.Header + 0x7c + k*0x20); size_t sectN1 = leu32p(hdr->AS.Header + 0x80 + k*0x20); size_t sectN2 = leu32p(hdr->AS.Header + 0x84 + k*0x20); size_t sectN3 = leu32p(hdr->AS.Header + 0x88 + k*0x20); if (!sectPos || memcmp("SctHdr\0\0", hdr->AS.Header+sectPos, 8) || memcmp(hdr->AS.Header+sectPos+8, sectName, 16)) { if (VERBOSE_LEVEL > 8) fprintf(stdout,"%s (line %d): break loop (0x%x %s)\n",__FILE__,__LINE__, sectPos, sectName); break; } uint64_t curSec, nextSec; int flag=1; do { curSec = leu64p(hdr->AS.Header + sectPos + 24); nextSec = leu64p(hdr->AS.Header + sectPos + 32); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): 0x%08x %s 0x%08lx 0x%08lx \n",__FILE__,__LINE__, sectPos, sectName, curSec, nextSec); if (flag && !strcmp(sectName,"EEGData")) { if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): 0x%08x %s 0x%08lx 0x%08lx \n",__FILE__,__LINE__, sectPos, sectName, curSec, nextSec); FILE *fid2=fopen("tmp.bin","w"); fwrite(hdr->AS.Header + curSec+120, 1, nextSec-curSec-120,fid2); fclose(fid2); FILE *fid=fopen("tmp.asc","w"); for (size_t k0=curSec+8*15; k0 < nextSec; k0+=2) { fprintf(fid,"%d\n",bei16p(hdr->AS.Header + curSec + k0+1)); } fclose(fid); flag = 0; } sectPos = nextSec; } while (nextSec != (size_t)-1L); } biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format EAS(Cadwell): unsupported "); } else if (hdr->TYPE==EZ3) { hdr->VERSION = strtod((char*)hdr->AS.Header+21, NULL); // 16 bit ADC ? // 250 Hz ? if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d)0x%8x\n",__FILE__,__LINE__,hdr->HeadLen); uint32_t posH1 = leu32p(hdr->AS.Header + 0x10); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d)0x%8x\n",__FILE__,__LINE__,posH1); uint32_t posH1b = leu32p(hdr->AS.Header + 0x20); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d)0x%8x\n",__FILE__,__LINE__,posH1b); uint32_t posH2 = leu32p(hdr->AS.Header + 0x38); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d)0x%8x\n",__FILE__,__LINE__,posH2); uint32_t posH2b = leu32p(hdr->AS.Header + posH1 + 0x38); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d) 0x%08x 0x%08x 0x%08x 0x%08x \n",__FILE__,__LINE__,posH1,posH1b,posH2,posH2b); assert(posH1==posH1b); assert(posH2==posH2b); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d)\n",__FILE__,__LINE__); // start date/time { char *tmp = hdr->AS.Header + 0x5c; struct tm t; t.tm_year = strtol(tmp,&tmp,10)-1900; t.tm_mon = strtol(tmp+1,&tmp,10)-1; t.tm_mday = strtol(tmp+1,&tmp,10); t.tm_hour = strtol(tmp+1,&tmp,10); t.tm_min = strtol(tmp+1,&tmp,10); t.tm_sec = strtol(tmp+1,&tmp,10); hdr->T0 = tm_time2gdf_time(&t); } uint32_t pos0 = posH1+0x40; for (size_t k = posH1+0x40; k < posH2; k += 0x30) { char *tmp = hdr->AS.Header + k + 1; uint32_t pos = leu32p(hdr->AS.Header + k + 0x28); if (tmp[0]=='\0') break; if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): Label=<%s> %10d(0x%08x) [sz=%d]\n",__FILE__,__LINE__, tmp, pos, pos, pos-pos0); if (posAS.Header+pos+16); // related to size current block, seems to match next pos-pos0-64, V16+pos+64 is next pos. uint32_t V20=leu32p(hdr->AS.Header+pos+20); // always(?) 0 uint32_t V24=leu32p(hdr->AS.Header+pos+24); // related to block type, or position, seems to be a decimal number, 0,1,27000,151000,329000 uint32_t V32=leu32p(hdr->AS.Header+pos+32); // import for EEG001 blocks ? char* next = hdr->AS.Header+pos+40; // string, refers to name of next block ?? uint32_t nextpos = leu32p(hdr->AS.Header + k + 0x28 + 0x30); uint32_t V64=leu32p(hdr->AS.Header+pos+64); // maybe some size information of a subblock ? uint32_t V68=leu32p(hdr->AS.Header+pos+68); // ? uint32_t V72=leu32p(hdr->AS.Header+pos+72); // ? uint32_t V76=leu32p(hdr->AS.Header+pos+76); // ? seems to refer to next block uint32_t V80=leu32p(hdr->AS.Header+pos+80); // ? seems to refer to next block uint32_t V324=leu32p(hdr->AS.Header+pos+324); // seems to be the same as V24, at least when V64 is large enough uint32_t V236=leu32p(hdr->AS.Header+pos+236); // seems to be important for EEG001 blocks ? uint32_t V237=leu32p(hdr->AS.Header+pos+237); // seems to be important for EEG001 blocks ? uint32_t V244=leu32p(hdr->AS.Header+pos+244); // seems to be important for EEG001 blocks ? uint32_t V245=leu32p(hdr->AS.Header+pos+245); // seems to be important for EEG001 blocks ? uint32_t V260=leu32p(hdr->AS.Header+pos+260); // seems to be important for EEG001 blocks ? uint32_t V261=leu32p(hdr->AS.Header+pos+261); // seems to be important for EEG001 blocks ? uint32_t V332=leu32p(hdr->AS.Header+pos+332); // seems to be important for EEG001 blocks ? char TMP[1024]; strcpy(TMP, "cadwell.debug."); strcat(TMP, next); FILE* fid = fopen(TMP,"a"); fprintf(fid,"%d\n",pos); fclose(fid); pos0=pos; if (VERBOSE_LEVEL > 7) { if (memcmp(hdr->AS.Header+pos,"EasyDCWYAAA\0@\0\0\0",16) || leu32p(hdr->AS.Header+pos+20) ) fprintf(stdout,"%s (line %d): unexpected header info <%s><%s>0x08x\n",__FILE__,__LINE__, hdr->AS.Header+pos, hdr->AS.Header+pos+12, V20); if (nextpos != V16+pos+64) fprintf(stdout,"%s (line %d): unexpected header info %d!=%d\n",__FILE__,__LINE__, nextpos, V16+pos+64); fprintf(stdout,"%s (line %d): unknown header info (block type, position ?) %8d(0x%08x) <%s><%s>\n",__FILE__,__LINE__, V24, V24, tmp, next); if (( V64 > 328) && (V24 != V324)) fprintf(stdout,"%s (line %d): *(@+64) %ld(0x%16lx) *(@+324) %d(0x%08x)\n",__FILE__,__LINE__, V64, V64, V324, V324); } #if 0 if (!strncmp(tmp,"EEG001",7)) { // it seems all EEG001 data blocks do contain these "magic" values if (V64 != 0x02f3504dL) fprintf(stdout,"%s (line %d): [%s] *(@+64) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V64, V64); if (V68 != 0x4da8564a) fprintf(stdout,"%s (line %d): [%s] *(@+68) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V68, V68); if (V72 != 0x03b) fprintf(stdout,"%s (line %d): [%s] *(@+72) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V72, V72); } else if (!strncmp(next,"EVENT001",9)) { // it seems all EEG001 data blocks do contain these "magic" values if (V64 != 0x100) fprintf(stdout,"%s (line %d): [%s] *(@+64) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V64, V64); if (V68 != 0xffffff00) fprintf(stdout,"%s (line %d): [%s] *(@+68) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V68, V68); if (V72 != 0x1ff) fprintf(stdout,"%s (line %d): [%s] *(@+72) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V72, V72); } else { // it seems all EEG001 data blocks do contain these "magic" values if (V64 != 0x100) fprintf(stdout,"%s (line %d): [%s] *(@+64) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V64, V64); if (V68 != 0xffffff00) fprintf(stdout,"%s (line %d): [%s] *(@+68) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V68, V68); if (V72 != 0x01ff) fprintf(stdout,"%s (line %d): [%s] *(@+72) %20d(0x%16x)\n",__FILE__,__LINE__, tmp, V72, V72); } #endif if (!strncmp(next, "EEG001",7)) { /* positions with differences in the range of [0..371] 16 17 24 25 32 237 238 245 261 262 324 325 332 */ if (V76 != 0x2addcb81L) fprintf(stdout,"%s (line %d): [%s] *(@+76) %20d(0x%16x)\n",__FILE__,__LINE__, next, V76, V76); if (V80 != 0x02) fprintf(stdout,"%s (line %d): [%s] *(@+80) %20d(0x%16x)\n",__FILE__,__LINE__, next, V80, V80); if (V32 != 1000) fprintf(stdout,"%s (line %d): [%s] *(@+32) %20d(0x%16x)\n",__FILE__,__LINE__, next, V32, V32); if (V237 != V24) fprintf(stdout,"%s (line %d): [%s] *(@+237) %20d(0x%16x)\n",__FILE__,__LINE__, next, V237, V237); if (V245 != 1000) fprintf(stdout,"%s (line %d): [%s] *(@+245) %20d(0x%16x)\n",__FILE__,__LINE__, next, V245, V245); if (V261 != V24) fprintf(stdout,"%s (line %d): [%s] *(@+261) %20d(0x%16x)\n",__FILE__,__LINE__, next, V261, V261); if (V324 != V24) fprintf(stdout,"%s (line %d): [%s(?)] *(@+324) %20d(0x%16x)\n",__FILE__,__LINE__, next, V324, V324); if (V332 != 250) // sampling rate, SPR ? fprintf(stdout,"%s (line %d): [%s/SPR(?)] *(@+332) %20d(0x%16x)\n",__FILE__,__LINE__, next, V332, V332); if (V332*4 != V32 || V32 != V245) fprintf(stdout,"%s (line %d): [%s(?)] V32,V245,4xV332 do not match %d != %d != %d\n",__FILE__,__LINE__, next, V32, V245, V332); /* start at 372-872: block1 block2 615-1114: block2 1433- next interval seem seem to have variable lengths (signed) int16 blocklengths 308 samples, 250 real samples + ? */ strcpy(TMP, "cadwell.debug.eeg.txt"); FILE* fid = fopen(TMP,"a"); for (size_t kk=0; kkAS.Header+pos+371+kk*2); int16_t v2=lei16p(hdr->AS.Header+pos+371+(V332*2+63*2)+kk*2); int16_t v3=lei16p(hdr->AS.Header+pos+371+(V332*2+63*2)*2+kk*2); fprintf(fid, "%d\t%d\t%d\n", v1,v2,v3); } fclose(fid); } else if (!strncmp(next,"EVENT001",9)) { /* positions with differences in the range of [0..2051] 18 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 1217 1402 after 2052, almost all bytes a diffent */ if (V76 != 0) fprintf(stdout,"%s (line %d): EVENT *(@+76) %20d(0x%16x)\n",__FILE__,__LINE__, V76, V76); if (V80 != 0x20c00) fprintf(stdout,"%s (line %d): EVENT *(@+80) %20d(0x%16x)\n",__FILE__,__LINE__, V80, V80); for (int kk=536; kk<556; kk+=4) { uint32_t v = leu32p(hdr->AS.Header+pos+kk); fprintf(stdout,"%s (line %d): [%s] *(@+%10d)\t%d(0x%16x)\n",__FILE__,__LINE__, next, kk, v, v); } if (hdr->AS.Header[pos+165]!='E' || hdr->AS.Header[pos+202]!='t' ) { if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %d): unexpected info in EVENT header <%c><%c>\n",__FILE__,__LINE__, hdr->AS.Header[pos+165],hdr->AS.Header[pos+202]); } } else { if (V76 != 0) fprintf(stdout,"%s (line %d): [%s]->[%s] *(@+76) %20d(0x%16x)\n",__FILE__,__LINE__, tmp,next, V76, V76); if (V80 != 0x20c00) fprintf(stdout,"%s (line %d): [%s]->[%s] *(@+80) %20d(0x%16x)\n",__FILE__,__LINE__, tmp,next, V80, V80); } } biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format EZ3(Cadwell): unsupported "); } else if (hdr->TYPE==ARC) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format ARC(Cadwell): unsupported "); } } stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_heka_read.c0000664000175000017500000011054614752215315016620 /* Copyright (C) 2008-2013,2018 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #ifdef _WIN32 // Can't include sys/stat.h or sopen is declared twice. #include struct stat { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; _dev_t st_rdev; _off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; }; int __cdecl stat(const char *_Filename,struct stat *_Stat); #else #include #endif #include "../biosig.h" /* TODO: - need to separate sopen_heka() and sread_heka() - data swapping */ #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) /**************************************************************************** rational : computes the rational approximation of a floating point number such that n/d is an approximation for r with an relative error smaller than tol see Octave's rat.m ****************************************************************************/ void rational (double x, double tol, long *n, long *d) { if (x != x) { // i.e. isnan(x) *n = 0; *d = 0; return; } if (!isfinite(x)) { *n = x>0; // i.e. sign(x) *d = 0; return; } tol *= fabs(x); *n = lround(x); *d = 1; double frac = x - *n; long lastn = 1, lastd = 0; while (fabs((*d) * x - (*n) ) >= fabs((*d) * tol)) { double flip = 1.0/frac; long step = lround(flip); frac = flip - step; long nextn = *n, nextd = *d; *n = *n * step + lastn; *d = *d * step + lastd; lastn = nextn; lastd = nextd; } if (*d < 0) { *n = - *n; *d = - *d; } } /**************************************************************************** heka2gdftime converts heka time format into gdftime ****************************************************************************/ gdf_time heka2gdftime(double t) { t -= 1580970496; if (t<0) t += 4294967296; t += 9561652096; return (uint64_t)ldexp(t/(24.0*60*60) + 584755, 32); // +datenum(1601,1,1)); } /**************************************************************************** sopen_heka reads heka format if itx is not null, the file is converted into an ITX formated file and streamed to itx, too. ****************************************************************************/ void sopen_heka(HDRTYPE* hdr, FILE *itx) { size_t count = hdr->HeadLen; if (hdr->TYPE==HEKA) { uint32_t Levels=0; uint16_t k; int32_t Counts[5], counts[5]; memset(Counts,0,20); memset(counts,0,20); uint32_t StartOfData=0,StartOfPulse=0; union { struct { int32_t Root; int32_t Group; int32_t Series; int32_t Sweep; int32_t Trace; } Rec; int32_t all[5]; } Sizes; memset(&Sizes,0,20); // HEKA PatchMaster file format count = hdr->HeadLen; struct stat FileBuf; stat(hdr->FileName,&FileBuf); hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, FileBuf.st_size); if (count < 1024) count += ifread(hdr->AS.Header+count, 1, 1024-count, hdr); hdr->HeadLen = count; char SWAP = ( hdr->FILE.LittleEndian && (__BYTE_ORDER == __BIG_ENDIAN)) \ || (!hdr->FILE.LittleEndian && (__BYTE_ORDER == __LITTLE_ENDIAN)); if (SWAP) { // FIXME: support HEKA files that require swapping, it might be releated to the version of the HEKA format biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster format: this is not fully supported yet."); } /* get file size and read whole file */ count += ifread(hdr->AS.Header+count, 1, FileBuf.st_size - count, hdr); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %i bytes read\n",__FILE__,__LINE__,__func__, (int)count); // double oTime = lef64p(hdr->AS.Header+40); // not used, do not forget to swap if needed uint32_t nItems = *(uint32_t*)(hdr->AS.Header+48); Levels = *(int32_t*)(hdr->AS.Header+4); if (SWAP) { nItems = bswap_32(nItems); Levels = bswap_32(Levels); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): nItems=%d Levels=%d\n",__FILE__,__LINE__,__func__, nItems,Levels); if (Levels>5) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster format with more than 5 levels not supported"); return; } memcpy(Sizes.all, hdr->AS.Header+8, sizeof(uint32_t)*Levels); if (SWAP) { for (int l=0; l < Levels; l++) Sizes.all[l] = bswap_32(Sizes.all[l]); } if (VERBOSE_LEVEL>6) for (int l=0; l < Levels; l++) fprintf(stdout,"%s (line %i) %s(...): Sizes[level=%d]=%d\n",__FILE__,__LINE__,__func__, l, Sizes.all[l]); if (hdr->VERSION == 0) { StartOfPulse = 8 + 4 * Levels; } else if (hdr->VERSION == 1) { Sizes.Rec.Root = 544; Sizes.Rec.Group = 128; Sizes.Rec.Series = 1120; Sizes.Rec.Sweep = 160; Sizes.Rec.Trace = 296; } else if (hdr->VERSION == 2) for (k=0; k < min(12,nItems); k++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): HEKA nItems=%i\n",__func__,__LINE__, k); uint32_t start = *(uint32_t*)(hdr->AS.Header+k*16+64); uint32_t length = *(uint32_t*)(hdr->AS.Header+k*16+64+4); if (SWAP) { start = bswap_32(start); length = bswap_32(length); } uint8_t *ext = hdr->AS.Header + k*16 + 64 + 8; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): HEKA #%i: <%s> [%i:+%i]\n",__func__,__LINE__,k,ext,start,length); if (!start) break; if ((start+8) > count) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, "Heka/Patchmaster: file is corrupted - segment with pulse data is not available!"); return; } if (!memcmp(ext,".pul\0\0\0\0",8)) { // find pulse data ifseek(hdr, start, SEEK_SET); //magic = *(int32_t*)(hdr->AS.Header+start); Levels = *(int32_t*)(hdr->AS.Header+start+4); if (SWAP) Levels = bswap_32(Levels); if (Levels>5) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster format with more than 5 levels not supported"); return; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): HEKA #%i Levels=%i\n",__func__,__LINE__,k,Levels); memcpy(Sizes.all,hdr->AS.Header+start+8,sizeof(int32_t)*Levels); if (SWAP) { int l; for (l=0; l < Levels; l++) Sizes.all[l] = bswap_32(Sizes.all[l]); } if (VERBOSE_LEVEL>7) {int l; for (l=0; l < Levels; l++) fprintf(stdout,"%s (line %i): HEKA #%i %i\n",__func__,__LINE__,l, Sizes.all[l]); } StartOfPulse = start + 8 + 4 * Levels; } else if (!memcmp(ext,".dat\0\0\0\0",8)) { StartOfData = start; } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): \n",__FILE__,__LINE__,__func__); // if (!Sizes) free(Sizes); Sizes=NULL; /* DONE: HEKA, check channel number and label pass 1: + get number of sweeps + get number of channels + check whether all traces of a single sweep have the same SPR, and Fs + check whether channelnumber (TrAdcChannel), scaling (DataScaler) and Label fit among all sweeps + extract the total number of samples + physical units + level 4 may have no children + count event descriptions Level2/SeLabel pass 2: + initialize data to NAN + skip sweeps if selected channel is not in it + Y scale, physical scale + Event.CodeDescription, Events, resampling */ uint32_t k1=0, k2=0, k3=0, k4=0; uint32_t K1=0, K2=0, K3=0, K4=0, K5=0; double t; size_t pos; // read K1 if (SWAP) { K1 = bswap_32(*(uint32_t*)(hdr->AS.Header + StartOfPulse + Sizes.Rec.Root)); hdr->VERSION = bswap_32(*(uint32_t*)(hdr->AS.Header + StartOfPulse)); union { double f64; uint64_t u64; } c; c.u64 = bswap_64(*(uint64_t*)(hdr->AS.Header + StartOfPulse + 520)); t = c.f64; } else { K1 = (*(uint32_t*)(hdr->AS.Header + StartOfPulse + Sizes.Rec.Root)); hdr->VERSION = (*(uint32_t*)(hdr->AS.Header + StartOfPulse)); t = (*(double*)(hdr->AS.Header + StartOfPulse + 520)); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): \n",__FILE__,__LINE__,__func__); hdr->T0 = heka2gdftime(t); // this is when when heka was started, data is recorded later. hdr->SampleRate = 0.0; double *DT = NULL; // list of sampling intervals per channel hdr->SPR = 0; /******************************************************************************************************* HEKA: read structural information *******************************************************************************************************/ pos = StartOfPulse + Sizes.Rec.Root + 4; size_t EventN=0; for (k1=0; k17) fprintf(stdout,"HEKA L1 @%i=\t%i/%i \n",(int)(pos+StartOfData),k1,K1); pos += Sizes.Rec.Group+4; // read number of children K2 = (*(uint32_t*)(hdr->AS.Header+pos-4)); hdr->AS.auxBUF = (uint8_t*)realloc(hdr->AS.auxBUF,K2*33); // used to store name of series for (k2=0; k2AS.Header+pos+4); // max 32 bytes strncpy((char*)hdr->AS.auxBUF + 33*k2, (char*)hdr->AS.Header+pos+4, 32); hdr->AS.auxBUF[33*k2+32] = 0; SeLabel = (char*)hdr->AS.auxBUF + 33*k2; double tt = *(double*)(hdr->AS.Header+pos+136); // time of series. TODO: this time should be taken into account Delay.u64 = bswap_64(*(uint64_t*)(hdr->AS.Header+pos+472+176)); gdf_time t = heka2gdftime(tt); if (VERBOSE_LEVEL>7) { char tmp[60]; snprintf_gdfdate(tmp, sizeof(tmp), t); fprintf(stdout,"HEKA L2 @%i=%s %f\t%i/%i %i/%i t=%.17g %s\n",(int)(pos+StartOfData),SeLabel,Delay.f64,k1,K1,k2,K2,ldexp(t,-32),tmp); } pos += Sizes.Rec.Series + 4; // read number of children K3 = (*(uint32_t*)(hdr->AS.Header+pos-4)); if (EventN <= hdr->EVENT.N + K3 + 2) { EventN = max(max(16,EventN),hdr->EVENT.N+K3+2) * 2; if (reallocEventTable(hdr, EventN) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return; }; } if (!hdr->AS.SegSel[0] && !hdr->AS.SegSel[1] && !hdr->AS.SegSel[2]) { // in case of reading the whole file (no sweep selection), include marker for start of series FreeTextEvent(hdr, hdr->EVENT.N, SeLabel); hdr->EVENT.POS[hdr->EVENT.N] = hdr->SPR; // within reading the structure, hdr->SPR is used as a intermediate variable counting the number of samples #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = t; #endif hdr->EVENT.N++; } for (k3=0; k3NRec++; // increase number of sweeps size_t SPR = 0, spr = 0; gdf_time t = heka2gdftime(*(double*)(hdr->AS.Header+pos+48)); // time of sweep. TODO: this should be taken into account if (VERBOSE_LEVEL>7) { char tmp[60]; snprintf_gdfdate(tmp, sizeof(tmp), t); fprintf(stdout,"HEKA L3 @%i= %fHz\t%i/%i %i/%i %i/%i %s\n",(int)(pos+StartOfData),hdr->SampleRate,k1,K1,k2,K2,k3,K3,tmp); } char flagSweepSelected = (hdr->AS.SegSel[0]==0 || k1+1==hdr->AS.SegSel[0]) && (hdr->AS.SegSel[1]==0 || k2+1==hdr->AS.SegSel[1]) && (hdr->AS.SegSel[2]==0 || k3+1==hdr->AS.SegSel[2]); // hdr->SPR if (hdr->SPR==0) hdr->T0 = t; // start time of first recording determines the start time of the recording else if (flagSweepSelected && hdr->SPR > 0) { // marker for start of sweep hdr->EVENT.POS[hdr->EVENT.N] = hdr->SPR; // within reading the structure, hdr->SPR is used as a intermediate variable counting the number of samples hdr->EVENT.TYP[hdr->EVENT.N] = 0x7ffe; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[hdr->EVENT.N] = t; #endif hdr->EVENT.N++; } pos += Sizes.Rec.Sweep + 4; // read number of children K4 = (*(uint32_t*)(hdr->AS.Header+pos-4)); for (k4=0; k4AS.Header+pos+36)); uint32_t DataPos = (*(uint32_t*)(hdr->AS.Header+pos+40)); spr = (*(uint32_t*)(hdr->AS.Header+pos+44)); double DataScaler= (*(double*)(hdr->AS.Header+pos+72)); double Toffset = (*(double*)(hdr->AS.Header+pos+80)); // time offset of uint16_t pdc = PhysDimCode((char*)(hdr->AS.Header + pos + 96)); double dT = (*(double*)(hdr->AS.Header+pos+104)); //double XStart = (*(double*)(hdr->AS.Header+pos+112)); uint16_t XUnits = PhysDimCode((char*)(hdr->AS.Header+pos+120)); double YRange = (*(double*)(hdr->AS.Header+pos+128)); double YOffset = (*(double*)(hdr->AS.Header+pos+136)); double Bandwidth = (*(double*)(hdr->AS.Header+pos+144)); //double PipetteResistance = (*(double*)(hdr->AS.Header+pos+152)); double RsValue = (*(double*)(hdr->AS.Header+pos+192)); uint8_t ValidYRange = hdr->AS.Header[pos+220]; uint16_t AdcChan = (*(uint16_t*)(hdr->AS.Header+pos+222)); /* obsolete: range is defined by DigMin/DigMax * DataScaler + YOffset double PhysMin = (*(double*)(hdr->AS.Header+pos+224)); double PhysMax = (*(double*)(hdr->AS.Header+pos+232)); */ if (VERBOSE_LEVEL>7) fprintf(stdout, "%s (line %i): %i %i %i %i %i %g %g 0x%x xUnits=%i %g %g %g %g %i %i\n", __FILE__,__LINE__, k1, k2, k3, k4, ns, DataScaler, Toffset, pdc, XUnits, YRange, YOffset, Bandwidth, RsValue, ValidYRange, AdcChan); switch (hdr->AS.Header[pos+70]) { case 0: gdftyp = 3; //int16 /* It seems that the range is 1.024*(2^15-1)/2^15 nA or V and symetric around zero. i.e. YOffset is zero */ DigMax = ldexp(1.0,15) - 1.0; DigMin = -DigMax; break; case 1: gdftyp = 5; //int32 DigMax = ldexp(1.0, 31) - 1.0; DigMin = -DigMax; break; case 2: gdftyp = 16; //float32 DigMax = 1e9; DigMin = -1e9; break; case 3: gdftyp = 17; //float64 DigMax = 1e9; DigMin = -1e9; break; default: DigMax = NAN; DigMin = NAN; biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: data type not supported"); }; if (SWAP) { AdcChan = bswap_16(AdcChan); ns = bswap_32(ns); DataPos = bswap_32(DataPos); spr = bswap_32(spr); // avoid breaking strict-aliasing rules union { double f64; uint64_t u64; } c; c.f64 = dT; c.u64 = bswap_64(c.u64); dT = c.f64; c.f64 = YRange; c.u64 = bswap_64(c.u64); YRange = c.f64; c.f64 = YOffset; c.u64 = bswap_64(c.u64); YOffset = c.f64; //c.f64 = PhysMax; c.u64 = bswap_64(c.u64); PhysMax = c.f64; //c.f64 = PhysMin; c.u64 = bswap_64(c.u64); PhysMin = c.f64; c.f64 = Toffset; c.u64 = bswap_64(c.u64); Toffset = c.f64; c.f64 = DataScaler; c.u64 = bswap_64(c.u64); DataScaler = c.f64; } if (YOffset != 0.0) fprintf(stderr,"!!! WARNING !!! HEKA: the offset is not zero - " "this case is not tested and might result in incorrect scaling of " "the data,\n!!! YOU ARE WARNED !!!\n"); // scale to standard units - no prefix double Cal = DataScaler * PhysDimScale(pdc); double Off = YOffset * PhysDimScale(pdc); pdc &= 0xffe0; float Fs = 1.0 / ( dT * PhysDimScale(XUnits) ) ; // float is used to avoid spurios accuracy, round to single precision accuracy if (flagSweepSelected) { if (hdr->SampleRate <= 0.0) hdr->SampleRate = Fs; if (fabs(hdr->SampleRate - Fs) > 1e-9*Fs) { long DIV1 = 1, DIV2 = 1; rational(hdr->SampleRate*dT*PhysDimScale(XUnits), 1e-6, &DIV2, &DIV1); if (DIV1 > 1) { if ( ((size_t)DIV1 * hdr->SPR) > 0xffffffffffffffff) { fprintf(stderr,"!!! WARNING sopen_heka(%s) !!! due to resampling, the data will have more then 2^31 samples !!!\n", hdr->FileName); biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"HEKA file has more than 2^32 samples - this is not supported yet"); } hdr->SPR *= DIV1; hdr->SampleRate *= DIV1; hdr->EVENT.SampleRate = hdr->SampleRate; size_t n = 0; while (n < hdr->EVENT.N) hdr->EVENT.POS[n++] *= DIV1; } if (DIV2 > 1) spr *= DIV2; } // samples per sweep if (k4==0) SPR = spr; else if (SPR != spr) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: number of samples among channels within a single sweep do not match."); return; } } char *Label = (char*)hdr->AS.Header+pos+4; for (ns=0; ns < hdr->NS; ns++) { if (!strcmp(hdr->CHANNEL[ns].Label,Label)) break; } if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA L4 @%i= #%i,%i, %s %f %fHz\t%i/%i %i/%i %i/%i %i/%i \n",(int)(pos+StartOfData),ns,AdcChan,Label,hdr->SampleRate,Fs,k1,K1,k2,K2,k3,K3,k4,K4); CHANNEL_TYPE *hc; if (ns >= hdr->NS) { hdr->NS = ns + 1; #ifdef WITH_TIMESTAMPCHANNEL // allocate memory for an extra time stamp channel, which is define only after the end of the channel loop - see below hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, (hdr->NS + 1) * sizeof(CHANNEL_TYPE)); #else hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); #endif hc = hdr->CHANNEL + ns; strncpy(hc->Label, Label, max(32, MAX_LENGTH_LABEL)); hc->Label[max(32,MAX_LENGTH_LABEL)] = 0; hc->Transducer[0] = 0; hc->SPR = 1; hc->PhysDimCode = pdc; hc->OnOff = 1; hc->GDFTYP = gdftyp; hc->LeadIdCode = 0; hc->DigMin = DigMin; hc->DigMax = DigMax; // TODO: case of non-zero YOffset is not tested // hc->PhysMax = DigMax * Cal + Off; hc->PhysMin = DigMin * Cal + Off; hc->Cal = Cal; hc->Off = Off; hc->TOffset = Toffset; #ifndef NDEBUG double Cal2 = (hc->PhysMax - hc->PhysMin) / (hc->DigMax - hc->DigMin); double Off2 = hc->PhysMin - Cal2 * hc->DigMin; double Off3 = hc->PhysMax - Cal2 * hc->DigMax; assert(fabs(Cal-Cal2) < 1e-8 * Cal); assert(fabs(Off-Off2) < 1e-8 * Cal); assert(fabs(Off-Off3) < 1e-8 * Cal); #endif /* TODO: fix remaining channel header */ /* LowPass, HighPass, Notch, Impedance, */ hc->HighPass = NAN; hc->LowPass = (Bandwidth > 0) ? Bandwidth : NAN; hc->Notch = NAN; hc->Impedance = (RsValue > 0) ? RsValue : NAN; DT = (double*) realloc(DT, hdr->NS*sizeof(double)); DT[ns] = dT; } else { /* channel has been already defined in earlier sweep. check compatibility and adapt internal format when needed */ hc = hdr->CHANNEL + ns; double PhysMax = DigMax * Cal + Off; double PhysMin = DigMin * Cal + Off; // get max value to avoid false positive saturation detection when scaling changes if (hc->PhysMax < PhysMax) hc->PhysMax = PhysMax; if (hc->PhysMin > PhysMin) hc->PhysMin = PhysMin; if (hc->GDFTYP < gdftyp) { /* when data type changes, use the largest data type */ if (4 < hc->GDFTYP && hc->GDFTYP < 9 && gdftyp==16) /* (U)INT32, (U)INT64 + FLOAT32 -> DOUBLE */ hc->GDFTYP = 17; else hc->GDFTYP = gdftyp; } else if (hc->GDFTYP > gdftyp) { /* when data type changes, use the largest data type */ if (4 < gdftyp && gdftyp < 9 && hc->GDFTYP==16) /* (U)INT32, (U)INT64 + FLOAT32 -> DOUBLE */ hc->GDFTYP = 17; } if (fabs(hc->Cal - Cal) > 1e-9*Cal) { /* when scaling changes from sweep to sweep, use floating point numbers internally. */ if (hc->GDFTYP < 5) // int16 or smaller hc->GDFTYP = 16; else if (hc->GDFTYP < 9) // int32, int64 -> double hc->GDFTYP = 17; } if ((pdc & 0xFFE0) != (hc->PhysDimCode & 0xFFE0)) { fprintf(stdout, "ERROR: [%i,%i,%i,%i] Yunits in %s do not match %04x(%s) ! %04x(%s)\n",k1,k2,k3,k4, Label, pdc, PhysDim3(pdc), hc->PhysDimCode, PhysDim3(hc->PhysDimCode)); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: Yunits do not match"); } if ( ( VERBOSE_LEVEL > 7 ) && ( fabs( DT[ns] - dT) > 1e-9 * dT) ) { fprintf(stdout, "%s (line %i) different sampling rates [%i,%i,%i,%i]#%i,%f/%f \n",__FILE__,__LINE__,(int)k1,(int)k2,(int)k3,(int)k4,(int)ns, 1.0/DT[ns],1.0/dT); } } if (YOffset) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: YOffset is not zero"); } if (hdr->AS.Header[pos+220] != 1) { fprintf(stderr,"WARNING Heka/Patchmaster: ValidYRange not set to 1 but %i in sweep [%i,%i,%i,%i]\n", hdr->AS.Header[pos+220],k1+1,k2+1,k3+1,k4+1); } if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA L6 @%i= #%i,%i, %s %f-%fHz\t%i/%i %i/%i %i/%i %i/%i \n",(int)(pos+StartOfData),ns,AdcChan,Label,hdr->SampleRate,Fs,k1,K1,k2,K2,k3,K3,k4,K4); pos += Sizes.Rec.Trace+4; // read number of children -- this should be 0 - ALWAYS; K5 = (*(uint32_t*)(hdr->AS.Header+pos-4)); if (K5) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: Level 4 has some children"); } } // end loop k4 // if sweep is selected, add number of samples to counter if (flagSweepSelected) { if ( hdr->SPR > 0xffffffffffffffffu-SPR) { biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"HEKA file has more than 2^32 samples - this is not supported yet"); } hdr->SPR += SPR; } } // end loop k3 } // end loop k2 } // end loop k1 #ifndef NO_BI if (DT) free(DT); #else size_t *BI = (size_t*) DT; // DT is not used anymore, use space for BI #endif DT = NULL; #ifdef WITH_TIMESTAMPCHANNEL { /* define time stamp channel, memory is already allocated above */ CHANNEL_TYPE *hc = hdr->CHANNEL + hdr->NS; hc->GDFTYP = 7; // corresponds to int64_t, gdf_time strcpy(hc->Label,"Timestamp"); hc->Transducer[0]=0; hc->PhysDimCode = 2272; // units: days [d] hc->LeadIdCode = 0; hc->SPR = 1; hc->Cal = ldexp(1.0, -32); hc->Off = 0.0; hc->OnOff = 1; hc->DigMax = ldexp( 1.0, 61); hc->DigMin = 0; hc->PhysMax = hc->DigMax * hc->Cal; hc->PhysMin = hc->DigMin * hc->Cal; hc->TOffset = 0.0; hc->Impedance = NAN; hc->HighPass = NAN; hc->LowPass = NAN; hc->Notch = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; hdr->NS++; } #endif hdr->NRec = 1; hdr->AS.bpb = 0; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; hc->Cal = (hc->PhysMax - hc->PhysMin) / (hc->DigMax - hc->DigMin); hc->Off = hc->PhysMin - hc->DigMin * hc->Cal; #ifndef NO_BI hc->bi = hdr->AS.bpb; #else BI[k] = hdr->AS.bpb; #endif hc->SPR = hdr->SPR; hdr->AS.bpb += hc->SPR * (GDFTYP_BITS[hc->GDFTYP]>>3); // multiplation must not exceed 32 bit limit } if (hdr->AS.B4C_ERRNUM) { #ifdef NO_BI if (BI) free(BI); #endif return; } hdr->ID.Manufacturer.Name = "HEKA/Patchmaster"; /****************************************************************************** SREAD_HEKA void sread_heka(HDRTYPE* hdr, FILE *itx, ... ) { ******************************************************************************/ if (VERBOSE_LEVEL > 7) fprintf(stdout,"HEKA: 400: %"PRIi64" %"PRIi32" %"PRIi64"\n",hdr->NRec, hdr->AS.bpb, hdr->NRec * (size_t)hdr->AS.bpb); size_t sz = hdr->NRec * (size_t)hdr->AS.bpb; if (sz/hdr->NRec < hdr->AS.bpb) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "memory allocation failed - more than 2GB required but platform supports only 32 bit!"); return; } void* tmpptr = realloc(hdr->AS.rawdata, sz); if (tmpptr!=NULL) hdr->AS.rawdata = (uint8_t*) tmpptr; else { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "memory allocation failed - not enough memory!"); return; } assert(hdr->NRec >= 0); memset(hdr->AS.rawdata, 0xff, hdr->NRec * (size_t)hdr->AS.bpb); // initialize with NAN's #ifdef NO_BI #define _BI (BI[k]) #else #define _BI (hc->bi) #endif /* initialize with NAN's */ for (k=0; kNS; k++) { size_t k1; CHANNEL_TYPE *hc = hdr->CHANNEL+k; switch (hc->GDFTYP) { case 3: for (k1=0; k1SPR; k1++) { *(uint16_t*)(hdr->AS.rawdata + _BI + k1 * 2) = 0x8000; } break; case 5: for (k1=0; k1SPR; k1++) *(uint32_t*)(hdr->AS.rawdata + _BI + k1 * 4) = 0x80000000; break; case 7: for (k1=0; k1SPR; k1++) *(int64_t*)(hdr->AS.rawdata + _BI + k1 * 4) = 0x8000000000000000LL; break; case 16: for (k1=0; k1SPR; k1++) *(float*)(hdr->AS.rawdata + _BI + k1 * 4) = NAN; break; case 17: for (k1=0; k1SPR; k1++) *(double*)(hdr->AS.rawdata + _BI + k1 * 8) = NAN; break; } } #undef _BI char *WAVENAME = NULL; if (itx) { fprintf(itx, "IGOR\r\nX Silent 1\r\n"); const char *fn = strrchr(hdr->FileName,'\\'); if (fn) fn++; else fn = strrchr(hdr->FileName,'/'); if (fn) fn++; else fn = hdr->FileName; size_t len = strspn(fn,"."); WAVENAME = (char*)malloc(strlen(hdr->FileName)+7); if (len) strncpy(WAVENAME, fn, len); else strcpy(WAVENAME, fn); // Flawfinder: ignore } if (VERBOSE_LEVEL>7) hdr2ascii(hdr,stdout,4); /******************************************************************************************************* HEKA: read data blocks *******************************************************************************************************/ uint32_t SPR = 0; pos = StartOfPulse + Sizes.Rec.Root + 4; for (k1=0; k17) fprintf(stdout,"HEKA+L1 @%i=\t%i/%i \n",(int)(pos+StartOfData),k1,K1); pos += Sizes.Rec.Group+4; // read number of children K2 = (*(uint32_t*)(hdr->AS.Header+pos-4)); for (k2=0; k2AS.Header+pos+4); // max 32 bytes Delay.u64 = bswap_64(*(uint64_t*)(hdr->AS.Header+pos+472+176)); if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA+L2 @%i=%s %f\t%i/%i %i/%i \n",(int)(pos+StartOfData),SeLabel,Delay.f64,k1,K1,k2,K2); /* move to reading of data */ pos += Sizes.Rec.Series+4; // read number of children K3 = (*(uint32_t*)(hdr->AS.Header+pos-4)); for (k3=0; k3NS-1]) #else #define _BI (hdr->CHANNEL[hdr->NS-1].bi) #endif gdf_time t = heka2gdftime(*(double*)(hdr->AS.Header+pos+48)); // time of sweep. TODO: this should be taken into account *(int64_t*)(hdr->AS.rawdata + _BI + SPR * 8) = t; #undef _BI #endif // WITH_TIMESTAMPCHANNEL // read sweep char flagSweepSelected = (hdr->AS.SegSel[0]==0 || k1+1==hdr->AS.SegSel[0]) && (hdr->AS.SegSel[1]==0 || k2+1==hdr->AS.SegSel[1]) && (hdr->AS.SegSel[2]==0 || k3+1==hdr->AS.SegSel[2]); if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA+L3 @%i=\t%i/%i %i/%i %i/%i sel=%i\n",(int)(pos+StartOfData),k1,K1,k2,K2,k3,K3,flagSweepSelected); pos += Sizes.Rec.Sweep + 4; // read number of children K4 = (*(uint32_t*)(hdr->AS.Header+pos-4)); size_t DIV=1; for (k4=0; k4AS.Header+pos+36)); uint32_t DataPos = (*(uint32_t*)(hdr->AS.Header+pos+40)); spr = (*(uint32_t*)(hdr->AS.Header+pos+44)); double DataScaler= (*(double*)(hdr->AS.Header+pos+72)); double Toffset = (*(double*)(hdr->AS.Header+pos+80)); // time offset of uint16_t pdc = PhysDimCode((char*)(hdr->AS.Header + pos + 96)); char *physdim = (char*)(hdr->AS.Header + pos + 96); double dT = (*(double*)(hdr->AS.Header+pos+104)); // double XStart = (*(double*)(hdr->AS.Header+pos+112)); // uint16_t XUnits = PhysDimCode((char*)(hdr->AS.Header+pos+120)); double YRange = (*(double*)(hdr->AS.Header+pos+128)); double YOffset = (*(double*)(hdr->AS.Header+pos+136)); // double Bandwidth = (*(double*)(hdr->AS.Header+pos+144)); uint16_t AdcChan = (*(uint16_t*)(hdr->AS.Header+pos+222)); /* double PhysMin = (*(double*)(hdr->AS.Header+pos+224)); double PhysMax = (*(double*)(hdr->AS.Header+pos+232)); */ switch (hdr->AS.Header[pos+70]) { case 0: gdftyp = 3; break; // int16 case 1: gdftyp = 5; break; // int32 case 2: gdftyp = 16; break; // float32 case 3: gdftyp = 17; break; // float64 default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster unknown data type is used"); }; if (SWAP) { AdcChan = bswap_16(AdcChan); ns = bswap_32(ns); DataPos = bswap_32(DataPos); spr = bswap_32(spr); // avoid breaking strict-aliasing rules union { double f64; uint64_t u64; } c; c.f64 = dT; c.u64 = bswap_64(c.u64); dT = c.f64; c.f64 = YRange; c.u64 = bswap_64(c.u64); YRange = c.f64; c.f64 = YOffset; c.u64 = bswap_64(c.u64); YOffset = c.f64; /* c.f64 = PhysMax; c.u64 = bswap_64(c.u64); PhysMax = c.f64; c.f64 = PhysMin; c.u64 = bswap_64(c.u64); PhysMin = c.f64; */ c.f64 = Toffset; c.u64 = bswap_64(c.u64); Toffset = c.f64; } double Fs = round(1.0 / dT); DIV = round(hdr->SampleRate / Fs); char *Label = (char*)(hdr->AS.Header+pos+4); for (ns=0; ns < hdr->NS; ns++) { if (!strcmp(hdr->CHANNEL[ns].Label, Label)) break; } CHANNEL_TYPE *hc = hdr->CHANNEL+ns; if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA+L4 @%i= #%i,%i,%i/%i %s\t%i/%i %i/%i %i/%i %i/%i DIV=%i,%i,%i\n",(int)(pos+StartOfData),ns,AdcChan,spr,SPR,Label,k1,K1,k2,K2,k3,K3,k4,K4,(int)DIV,gdftyp,hc->GDFTYP); if (itx) { uint32_t k5; double Cal = DataScaler; assert(hdr->CHANNEL[ns].Off==0.0); double Off = 0.0; fprintf(itx, "\r\nWAVES %s_%i_%i_%i_%i\r\nBEGIN\r\n", WAVENAME,k1+1,k2+1,k3+1,k4+1); switch (hc->GDFTYP) { case 3: for (k5 = 0; k5 < spr; ++k5) fprintf(itx,"% e\n", (double)*(int16_t*)(hdr->AS.Header + DataPos + k5 * 2) * Cal + Off); break; case 5: for (k5 = 0; k5 < spr; ++k5) fprintf(itx,"% e\n", (double)*(int32_t*)(hdr->AS.Header + DataPos + k5 * 4) * Cal + Off); break; case 16: for (k5 = 0; k5 < spr; ++k5) fprintf(itx,"% e\n", (double)*(float*)(hdr->AS.Header + DataPos + k5 * 4) * Cal + Off); break; case 17: for (k5 = 0; k5 < spr; ++k5) fprintf(itx,"% e\n", *(double*)(hdr->AS.Header + DataPos + k5 * 8) * Cal + Off); break; } fprintf(itx, "END\r\nX SetScale/P x, %g, %g, \"s\", %s_%i_%i_%i_%i\r\n", Toffset, dT, WAVENAME, k1+1,k2+1,k3+1,k4+1); fprintf(itx, "X SetScale y,0,0,\"%s\", %s_%i_%i_%i_%i\n", physdim, WAVENAME, k1+1,k2+1,k3+1,k4+1); } #ifdef NO_BI #define _BI (BI[ns]) #else #define _BI (hc->bi) #endif // no need to check byte order because File.Endian is set and endian conversion is done in sread if ((DIV==1) && (gdftyp == hc->GDFTYP)) { uint16_t sz = GDFTYP_BITS[hc->GDFTYP]>>3; memcpy(hdr->AS.rawdata + _BI + SPR * sz, hdr->AS.Header + DataPos, spr * sz); } else if (1) { double Cal = DataScaler * PhysDimScale(pdc) / hdr->CHANNEL[ns].Cal; assert(Cal==1.0 || hc->GDFTYP > 15); // when scaling changes, target data type is always float/double -> see above uint32_t k5,k6; switch (gdftyp) { case 3: switch (hc->GDFTYP) { case 3: for (k5 = 0; k5 < spr; ++k5) { int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2); for (k6 = 0; k6 < DIV; ++k6) *(int16_t*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 2) = ival; } break; case 5: for (k5 = 0; k5 < spr; ++k5) { int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2); for (k6 = 0; k6 < DIV; ++k6) *(int32_t*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = (int32_t)ival; } break; case 16: for (k5 = 0; k5 < spr; ++k5) { int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2); for (k6 = 0; k6 < DIV; ++k6) *(float*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = (float)ival * Cal; } break; case 17: for (k5 = 0; k5 < spr; ++k5) { int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2); for (k6 = 0; k6 < DIV; ++k6) *(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = (double)ival * Cal; } break; } break; case 5: switch (hc->GDFTYP) { case 5: for (k5 = 0; k5 < spr; ++k5) { int32_t ival = *(int32_t*)(hdr->AS.Header + DataPos + k5 * 4); for (k6 = 0; k6 < DIV; ++k6) *(int32_t*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = ival; } break; case 16: for (k5 = 0; k5 < spr; ++k5) { int32_t ival = *(int32_t*)(hdr->AS.Header + DataPos + k5 * 4); for (k6 = 0; k6 < DIV; ++k6) *(float*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = (float)ival * Cal; } break; case 17: for (k5 = 0; k5 < spr; ++k5) { int32_t ival = *(int32_t*)(hdr->AS.Header + DataPos + k5 * 4); for (k6 = 0; k6 < DIV; ++k6) *(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = (double)ival * Cal; } break; } break; case 16: switch (hc->GDFTYP) { case 16: for (k5 = 0; k5 < spr; ++k5) { float ival = *(float*)(hdr->AS.Header + DataPos + k5 * 4); for (k6 = 0; k6 < DIV; ++k6) *(float*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = ival * Cal; } break; case 17: for (k5 = 0; k5 < spr; ++k5) { float ival = *(float*)(hdr->AS.Header + DataPos + k5 * 4); for (k6 = 0; k6 < DIV; ++k6) *(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = (double)ival * Cal; } break; } break; case 17: switch (hc->GDFTYP) { case 17: for (k5 = 0; k5 < spr; ++k5) { double ival = *(double*)(hdr->AS.Header + DataPos + k5 * 8); for (k6 = 0; k6 < DIV; ++k6) *(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = ival * Cal; } break; } break; } } #undef _BI pos += Sizes.Rec.Trace+4; } if (flagSweepSelected) SPR += spr * DIV; } } } #ifdef NO_BI if (BI) free(BI); #endif hdr->AS.first = 0; hdr->AS.length = hdr->NRec; free(hdr->AS.Header); hdr->AS.Header = NULL; if (VERBOSE_LEVEL>7) fprintf(stdout,"End of SOPEN_HEKA\n"); } else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster format has unsupported version number"); } } #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/t210/axon_structs.h0000664000175000017500000002656114752215315016255 // // This file is part of the Axon Library. // // Copyright (c) 2008-2009 Jakub Nowacki // // The Axon Binary Format is property of Molecular Devices. // All rights to the Axon Binary Format are reserved to Molecular Devices. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // /* modified for use with biosig Copyright (C) 2013 Alois Schlögl, This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /*! \file * \brief Header containing all structures of ABF */ #ifndef INC_PROTOCOLSTRUCTS_HPP #define INC_PROTOCOLSTRUCTS_HPP #pragma once #pragma pack(push, 1) //#define UINT unsigned int //#define LONGLONG long long #define bool int // GUID is normally defined in the Windows Platform SDK struct GUID { uint32_t Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; }; // All these structs are persisted to file -> their sizes must NOT be changed without careful // attention to versioning issues in order to maintain compatibility. typedef struct ABF_Section { unsigned int uBlockIndex; // ABF block number of the first entry unsigned int uBytes; // size in bytes of of each entry long long llNumEntries; // number of entries in this section } ABF_Section; #define ABF_FILESIGNATURE 0x32464241 // PC="ABF2", MAC="2FBA" struct ABF_FileInfo { unsigned int uFileSignature; unsigned int uFileVersionNumber; // After this point there is no need to be the same as the ABF 1 equivalent. unsigned int uFileInfoSize; unsigned int uActualEpisodes; unsigned int uFileStartDate; unsigned int uFileStartTimeMS; unsigned int uStopwatchTime; short nFileType; short nDataFormat; short nSimultaneousScan; short nCRCEnable; unsigned int uFileCRC; struct GUID FileGUID; unsigned int uCreatorVersion; unsigned int uCreatorNameIndex; unsigned int uModifierVersion; unsigned int uModifierNameIndex; unsigned int uProtocolPathIndex; // New sections in ABF 2 - protocol stuff ... ABF_Section ProtocolSection; // the protocol ABF_Section ADCSection; // one for each ADC channel ABF_Section DACSection; // one for each DAC channel ABF_Section EpochSection; // one for each epoch ABF_Section ADCPerDACSection; // one for each ADC for each DAC ABF_Section EpochPerDACSection; // one for each epoch for each DAC ABF_Section UserListSection; // one for each user list ABF_Section StatsRegionSection; // one for each stats region ABF_Section MathSection; ABF_Section StringsSection; // ABF 1 sections ... ABF_Section DataSection; // Data ABF_Section TagSection; // Tags ABF_Section ScopeSection; // Scope config ABF_Section DeltaSection; // Deltas ABF_Section VoiceTagSection; // Voice Tags ABF_Section SynchArraySection; // Synch Array ABF_Section AnnotationSection; // Annotations ABF_Section StatsSection; // Stats config char sUnused[148]; // size = 512 bytes }; struct ABF_ProtocolInfo { short nOperationMode; float fADCSequenceInterval; bool bEnableFileCompression; char sUnused1[3]; unsigned int uFileCompressionRatio; float fSynchTimeUnit; float fSecondsPerRun; ABFLONG lNumSamplesPerEpisode; ABFLONG lPreTriggerSamples; ABFLONG lEpisodesPerRun; ABFLONG lRunsPerTrial; ABFLONG lNumberOfTrials; short nAveragingMode; short nUndoRunCount; short nFirstEpisodeInRun; float fTriggerThreshold; short nTriggerSource; short nTriggerAction; short nTriggerPolarity; float fScopeOutputInterval; float fEpisodeStartToStart; float fRunStartToStart; ABFLONG lAverageCount; float fTrialStartToStart; short nAutoTriggerStrategy; float fFirstRunDelayS; short nChannelStatsStrategy; ABFLONG lSamplesPerTrace; ABFLONG lStartDisplayNum; ABFLONG lFinishDisplayNum; short nShowPNRawData; float fStatisticsPeriod; ABFLONG lStatisticsMeasurements; short nStatisticsSaveStrategy; float fADCRange; float fDACRange; ABFLONG lADCResolution; ABFLONG lDACResolution; short nExperimentType; short nManualInfoStrategy; short nCommentsEnable; ABFLONG lFileCommentIndex; short nAutoAnalyseEnable; short nSignalType; short nDigitalEnable; short nActiveDACChannel; short nDigitalHolding; short nDigitalInterEpisode; short nDigitalDACChannel; short nDigitalTrainActiveLogic; short nStatsEnable; short nStatisticsClearStrategy; short nLevelHysteresis; ABFLONG lTimeHysteresis; short nAllowExternalTags; short nAverageAlgorithm; float fAverageWeighting; short nUndoPromptStrategy; short nTrialTriggerSource; short nStatisticsDisplayStrategy; short nExternalTagType; short nScopeTriggerOut; short nLTPType; short nAlternateDACOutputState; short nAlternateDigitalOutputState; float fCellID[3]; short nDigitizerADCs; short nDigitizerDACs; short nDigitizerTotalDigitalOuts; short nDigitizerSynchDigitalOuts; short nDigitizerType; char sUnused[304]; // size = 512 bytes }; struct ABF_MathInfo { short nMathEnable; short nMathExpression; unsigned int uMathOperatorIndex; unsigned int uMathUnitsIndex; float fMathUpperLimit; float fMathLowerLimit; short nMathADCNum[2]; char sUnused[16]; float fMathK[6]; char sUnused2[64]; // size = 128 bytes }; struct ABF_ADCInfo { // The ADC this struct is describing. short nADCNum; short nTelegraphEnable; short nTelegraphInstrument; float fTelegraphAdditGain; float fTelegraphFilter; float fTelegraphMembraneCap; short nTelegraphMode; float fTelegraphAccessResistance; short nADCPtoLChannelMap; short nADCSamplingSeq; float fADCProgrammableGain; float fADCDisplayAmplification; float fADCDisplayOffset; float fInstrumentScaleFactor; float fInstrumentOffset; float fSignalGain; float fSignalOffset; float fSignalLowpassFilter; float fSignalHighpassFilter; char nLowpassFilterType; char nHighpassFilterType; float fPostProcessLowpassFilter; char nPostProcessLowpassFilterType; bool bEnabledDuringPN; short nStatsChannelPolarity; ABFLONG lADCChannelNameIndex; ABFLONG lADCUnitsIndex; char sUnused[46]; // size = 128 bytes }; struct ABF_DACInfo { // The DAC this struct is describing. short nDACNum; short nTelegraphDACScaleFactorEnable; float fInstrumentHoldingLevel; float fDACScaleFactor; float fDACHoldingLevel; float fDACCalibrationFactor; float fDACCalibrationOffset; ABFLONG lDACChannelNameIndex; ABFLONG lDACChannelUnitsIndex; ABFLONG lDACFilePtr; ABFLONG lDACFileNumEpisodes; short nWaveformEnable; short nWaveformSource; short nInterEpisodeLevel; float fDACFileScale; float fDACFileOffset; ABFLONG lDACFileEpisodeNum; short nDACFileADCNum; short nConditEnable; ABFLONG lConditNumPulses; float fBaselineDuration; float fBaselineLevel; float fStepDuration; float fStepLevel; float fPostTrainPeriod; float fPostTrainLevel; short nMembTestEnable; short nLeakSubtractType; short nPNPolarity; float fPNHoldingLevel; short nPNNumADCChannels; short nPNPosition; short nPNNumPulses; float fPNSettlingTime; float fPNInterpulse; short nLTPUsageOfDAC; short nLTPPresynapticPulses; ABFLONG lDACFilePathIndex; float fMembTestPreSettlingTimeMS; float fMembTestPostSettlingTimeMS; short nLeakSubtractADCIndex; char sUnused[124]; // size = 256 bytes }; struct ABF_EpochInfoPerDAC { // The Epoch / DAC this struct is describing. short nEpochNum; short nDACNum; // One full set of epochs (ABF_EPOCHCOUNT) for each DAC channel ... short nEpochType; float fEpochInitLevel; float fEpochLevelInc; ABFLONG lEpochInitDuration; ABFLONG lEpochDurationInc; ABFLONG lEpochPulsePeriod; ABFLONG lEpochPulseWidth; char sUnused[18]; // size = 48 bytes }; struct ABF_EpochInfo { // The Epoch this struct is describing. short nEpochNum; // Describes one epoch short nDigitalValue; short nDigitalTrainValue; short nAlternateDigitalValue; short nAlternateDigitalTrainValue; bool bEpochCompression; // Compress the data from this epoch using uFileCompressionRatio char sUnused[21]; // size = 32 bytes }; struct ABF_StatsRegionInfo { // The stats region this struct is describing. short nRegionNum; short nADCNum; short nStatsActiveChannels; short nStatsSearchRegionFlags; short nStatsSelectedRegion; short nStatsSmoothing; short nStatsSmoothingEnable; short nStatsBaseline; ABFLONG lStatsBaselineStart; ABFLONG lStatsBaselineEnd; // Describes one stats region ABFLONG lStatsMeasurements; ABFLONG lStatsStart; ABFLONG lStatsEnd; short nRiseBottomPercentile; short nRiseTopPercentile; short nDecayBottomPercentile; short nDecayTopPercentile; short nStatsSearchMode; short nStatsSearchDAC; short nStatsBaselineDAC; char sUnused[78]; // size = 128 bytes }; struct ABF_UserListInfo { // The user list this struct is describing. short nListNum; // Describes one user list short nULEnable; short nULParamToVary; short nULRepeat; ABFLONG lULParamValueListIndex; char sUnused[52]; // size = 64 bytes }; struct ABF_SynchArray { ABFLONG lStart; ABFLONG lLength; }; // Strings section structure not defined by Axon #pragma pack(pop) // return to default packing #endif // INC_PROTOCOLSTRUCTS_HPP stimfit-0.16.7/src/biosig/biosig4c++/t210/abfheadr.h0000775000175000017500000017032714752215315015260 //*********************************************************************************************** // // Copyright (c) 1993-2003 Axon Instruments. // All rights reserved. // Permission is granted to freely use, modify and copy the code in this file. // //*********************************************************************************************** // HEADER: ABFHEADR.H. // PURPOSE: Defines the ABFFileHeader structure, and provides prototypes for // functions implemented in ABFHEADR.CPP for reading and writing // ABFFileHeader's. // REVISIONS: // 1.1 - Version 1.1 was released in April 1992. // 1.2 - Added nDataFormat so that data can optionally be stored in floating point format. // - Added lClockChange to control the multiplexed ADC sample number after which the second sampling interval commences. // 1.3 - Change 4-byte sFileType string to long lFileSignature. // - #define ABF_NATIVESIGNATURE & ABF_REVERSESIGNATURE for byte order detection. // - Added support for Bells during before or after acquisitions // - Added parameters to describe hysteresis during event detected acquisitions: nLevelHysteresis and lTimeHysteresis. // - Dropped support for BASIC and Pascal. // - Added the ABF Scope Config section to store scope configuration information // 1.4 - Remove support for big-endian machines. // 1.5 - Change ABFSignal parameters from UUTop & UUBottom to // fDisplayGain & fDisplayOffset. // - Added and changed parameters in the 'File Structure', 'Display Parameters', // 'DAC Output File', 'Autopeak Measurements' and 'Unused space and end of header' sections of the ABF file header. // - Expanded the ABF API and error return codes // 1.6 - Expanded header to 5120 bytes and added extra parameters to support 2 waveform channels PRC // 1.65 - Telegraph support added. // 1.67 - Train epochs, multiple channel and multiple region stats // 1.68 - ABFScopeConfig expanded // 1.69 - Added user entered percentile levels for rise and decay stats // 1.70 - Added data reduction - AjD // 1.71 - Added epoch resistance // 1.72 - Added alternating outputs // 1.73 - Added post-processing lowpass filter settings. When filtering is done in Clampfit it is stored in the header. // 1.74 - Added channel_count_acquired // 1.75 - Added polarity for each channel // 1.76 - Added digital trigger out flag // 1.77 - Added major, minor and bugfix version numbers // 1.78 - Added separate entries for alternating DAC and digital outputs // 1.79 - Removed data reduction (now minidigi only) // 1.80 - Added stats mode for each region: mode is cursor region, epoch etc // 1.81 - Added multi input signal P / N leak subtraction // 1.82 - Cyclic Redundancy Code (CRC). // 1.83 - Added Modifier application name / version number // // Added 64bit support according to Jakub Nowacki's implementation in libaxon: // http://libaxon.sourceforge.net /* modified for use with biosig Copyright (C) 2013 Alois Schlögl, This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef INC_ABFHEADR_H #define INC_ABFHEADR_H #include #include //#include "AxAbffio32.h" #ifdef __cplusplus extern "C" { #endif // // Constants used in defining the ABF file header // #define ABF_ADCCOUNT 16 // number of ADC channels supported. #define ABF_DACCOUNT 4 // number of DAC channels supported. #define ABF_WAVEFORMCOUNT 2 // number of DAC channels which support waveforms. #define ABF_EPOCHCOUNT 10 // number of waveform epochs supported. #define ABF_BELLCOUNT 2 // Number of auditory signals supported. #define ABF_ADCUNITLEN 8 // length of ADC units strings #define ABF_ADCNAMELEN 10 // length of ADC channel name strings #define ABF_DACUNITLEN 8 // length of DAC units strings #define ABF_DACNAMELEN 10 // length of DAC channel name strings #define ABF_VARPARAMLISTLEN 80 // length of conditioning string #define ABF_USERLISTLEN 256 // length of the user list (V1.6) #define ABF_USERLISTCOUNT 4 // number of independent user lists (V1.6) #define ABF_OLDFILECOMMENTLEN 56 // length of file comment string (pre V1.6) #define ABF_FILECOMMENTLEN 128 // length of file comment string (V1.6) #define ABF_CREATORINFOLEN 16 // length of file creator info string #define ABF_OLDDACFILENAMELEN 12 // old length of the DACFile name string #define ABF_OLDDACFILEPATHLEN 60 // old length of the DACFile path string #define ABF_DACFILEPATHLEN 84 // length of full path for DACFile #define ABF_PATHLEN 256 // length of full path, used for DACFile and Protocol name. #define ABF_ARITHMETICOPLEN 2 // length of the Arithmetic operator field #define ABF_ARITHMETICUNITSLEN 8 // length of arithmetic units string #define ABF_TAGCOMMENTLEN 56 // length of tag comment string #define ABF_LONGDESCRIPTIONLEN 56 // length of long description entry #define ABF_NOTENAMELEN 10 // length of the name component of a note #define ABF_NOTEVALUELEN 8 // length of the value component of a note #define ABF_NOTEUNITSLEN 8 // length of the units component of a note #define ABF_BLOCKSIZE 512 // Size of block alignment in ABF files. #define ABF_MACRONAMELEN 64 // Size of a Clampfit macro name. #define ABF_CURRENTVERSION ABF_V183 // Current file format version number #define ABF_PREVIOUSVERSION 1.5F // Previous file format version number (for old header size) #define ABF_V16 1.6F // Version number when the header size changed. #define ABF_HEADERSIZE 6144 // Size of a Version 1.6 or later header #define ABF_OLDHEADERSIZE 2048 // Size of a Version 1.5 or earlier header #define ABF_NATIVESIGNATURE 0x20464241 // PC="ABF ", MAC=" FBA" #define ABF_REVERSESIGNATURE 0x41424620 // PC=" FBA", MAC="ABF " #define PCLAMP6_MAXSWEEPLENGTH 16384 // Maximum multiplexed sweep length supported by pCLAMP6 apps. #define PCLAMP7_MAXSWEEPLEN_PERCHAN 1032258 // Maximum per channel sweep length supported by pCLAMP7 apps. #define ABF_MAX_TRIAL_SAMPLES 0x7FFFFFFF // Maximum length of acquisition supported (samples) // INT_MAX is used instead of UINT_MAX because of the signed // values in the ABF header. #define ABF_MAX_SWEEPS_PER_AVERAGE 65500 // The maximum number of sweeps that can be combined into a // cumulative average (nAverageAlgorithm=ABF_INFINITEAVERAGE). #define ABF_STATS_REGIONS 8 // The number of independent statistics regions. #define ABF_BASELINE_REGIONS 1 // The number of independent baseline regions. #ifdef _MAC #define ABF_OLDPCLAMP ABF_REVERSESIGNATURE #else #define ABF_OLDPCLAMP ABF_NATIVESIGNATURE #endif // // Constant definitions for nFileType // #define ABF_ABFFILE 1 #define ABF_FETCHEX 2 #define ABF_CLAMPEX 3 // // Constant definitions for nDataFormat // #define ABF_INTEGERDATA 0 #define ABF_FLOATDATA 1 // // Constant definitions for nOperationMode // #define ABF_VARLENEVENTS 1 #define ABF_FIXLENEVENTS 2 // (ABF_FIXLENEVENTS == ABF_LOSSFREEOSC) #define ABF_LOSSFREEOSC 2 #define ABF_GAPFREEFILE 3 #define ABF_HIGHSPEEDOSC 4 #define ABF_WAVEFORMFILE 5 // // Constant definitions for nParamToVary // #define ABF_CONDITNUMPULSES 0 #define ABF_CONDITBASELINEDURATION 1 #define ABF_CONDITBASELINELEVEL 2 #define ABF_CONDITSTEPDURATION 3 #define ABF_CONDITSTEPLEVEL 4 #define ABF_CONDITPOSTTRAINDURATION 5 #define ABF_CONDITPOSTTRAINLEVEL 6 #define ABF_EPISODESTARTTOSTART 7 #define ABF_INACTIVEHOLDING 8 #define ABF_DIGITALHOLDING 9 #define ABF_PNNUMPULSES 10 #define ABF_PARALLELVALUE 11 #define ABF_EPOCHINITLEVEL (ABF_PARALLELVALUE + ABF_EPOCHCOUNT) #define ABF_EPOCHINITDURATION (ABF_EPOCHINITLEVEL + ABF_EPOCHCOUNT) #define ABF_EPOCHTRAINPERIOD (ABF_EPOCHINITDURATION + ABF_EPOCHCOUNT) #define ABF_EPOCHTRAINPULSEWIDTH (ABF_EPOCHTRAINPERIOD + ABF_EPOCHCOUNT) // Next value is (ABF_EPOCHINITDURATION + ABF_EPOCHCOUNT) // // Constants for nAveragingMode // #define ABF_NOAVERAGING 0 #define ABF_SAVEAVERAGEONLY 1 #define ABF_AVERAGESAVEALL 2 // // Constants for nAverageAlgorithm // #define ABF_INFINITEAVERAGE 0 #define ABF_SLIDINGAVERAGE 1 // // Constants for nEpochType // #define ABF_EPOCHDISABLED 0 // disabled epoch #define ABF_EPOCHSTEPPED 1 // stepped waveform #define ABF_EPOCHRAMPED 2 // ramp waveform #define ABF_EPOCH_TYPE_RECTANGLE 3 // rectangular pulse train #define ABF_EPOCH_TYPE_TRIANGLE 4 // triangular waveform #define ABF_EPOCH_TYPE_COSINE 5 // cosinusoidal waveform #define ABF_EPOCH_TYPE_RESISTANCE 6 // resistance waveform #define ABF_EPOCH_TYPE_BIPHASIC 7 // biphasic pulse train // // Constants for epoch resistance // #define ABF_MIN_EPOCH_RESISTANCE_DURATION 8 // // Constants for nWaveformSource // #define ABF_WAVEFORMDISABLED 0 // disabled waveform #define ABF_EPOCHTABLEWAVEFORM 1 #define ABF_DACFILEWAVEFORM 2 // // Constants for nInterEpisodeLevel & nDigitalInterEpisode // #define ABF_INTEREPI_USEHOLDING 0 #define ABF_INTEREPI_USELASTEPOCH 1 // // Constants for nExperimentType // #define ABF_VOLTAGECLAMP 0 #define ABF_CURRENTCLAMP 1 #define ABF_SIMPLEACQUISITION 2 // // Constants for nAutosampleEnable // #define ABF_AUTOSAMPLEDISABLED 0 #define ABF_AUTOSAMPLEAUTOMATIC 1 #define ABF_AUTOSAMPLEMANUAL 2 // // Constants for nAutosampleInstrument // #define ABF_INST_UNKNOWN 0 // Unknown instrument (manual or user defined telegraph table). #define ABF_INST_AXOPATCH1 1 // Axopatch-1 with CV-4-1/100 #define ABF_INST_AXOPATCH1_1 2 // Axopatch-1 with CV-4-0.1/100 #define ABF_INST_AXOPATCH1B 3 // Axopatch-1B(inv.) CV-4-1/100 #define ABF_INST_AXOPATCH1B_1 4 // Axopatch-1B(inv) CV-4-0.1/100 #define ABF_INST_AXOPATCH201 5 // Axopatch 200 with CV 201 #define ABF_INST_AXOPATCH202 6 // Axopatch 200 with CV 202 #define ABF_INST_GENECLAMP 7 // GeneClamp #define ABF_INST_DAGAN3900 8 // Dagan 3900 #define ABF_INST_DAGAN3900A 9 // Dagan 3900A #define ABF_INST_DAGANCA1_1 10 // Dagan CA-1 Im=0.1 #define ABF_INST_DAGANCA1 11 // Dagan CA-1 Im=1.0 #define ABF_INST_DAGANCA10 12 // Dagan CA-1 Im=10 #define ABF_INST_WARNER_OC725 13 // Warner OC-725 #define ABF_INST_WARNER_OC725C 14 // Warner OC-725 #define ABF_INST_AXOPATCH200B 15 // Axopatch 200B #define ABF_INST_DAGANPCONE0_1 16 // Dagan PC-ONE Im=0.1 #define ABF_INST_DAGANPCONE1 17 // Dagan PC-ONE Im=1.0 #define ABF_INST_DAGANPCONE10 18 // Dagan PC-ONE Im=10 #define ABF_INST_DAGANPCONE100 19 // Dagan PC-ONE Im=100 #define ABF_INST_WARNER_BC525C 20 // Warner BC-525C #define ABF_INST_WARNER_PC505 21 // Warner PC-505 #define ABF_INST_WARNER_PC501 22 // Warner PC-501 #define ABF_INST_DAGANCA1_05 23 // Dagan CA-1 Im=0.05 #define ABF_INST_MULTICLAMP700 24 // MultiClamp 700 #define ABF_INST_TURBO_TEC 25 // Turbo Tec #define ABF_INST_OPUSXPRESS6000 26 // OpusXpress 6000A // // Constants for nManualInfoStrategy // #define ABF_ENV_DONOTWRITE 0 #define ABF_ENV_WRITEEACHTRIAL 1 #define ABF_ENV_PROMPTEACHTRIAL 2 // // Constants for nTriggerSource // #define ABF_TRIGGERLINEINPUT -5 // Start on line trigger (DD1320 only) #define ABF_TRIGGERTAGINPUT -4 #define ABF_TRIGGERFIRSTCHANNEL -3 #define ABF_TRIGGEREXTERNAL -2 #define ABF_TRIGGERSPACEBAR -1 // >=0 = ADC channel to trigger off. // // Constants for nTrialTriggerSource // #define ABF_TRIALTRIGGER_SWSTARTONLY -6 // Start on software message, end when protocol ends. #define ABF_TRIALTRIGGER_SWSTARTSTOP -5 // Start and end on software messages. #define ABF_TRIALTRIGGER_LINEINPUT -4 // Start on line trigger (DD1320 only) #define ABF_TRIALTRIGGER_SPACEBAR -3 // Start on spacebar press. #define ABF_TRIALTRIGGER_EXTERNAL -2 // Start on external trigger high #define ABF_TRIALTRIGGER_NONE -1 // Start immediately (default). // >=0 = ADC channel to trigger off. // Not implemented as yet... // // Constants for nTriggerPolarity. // #define ABF_TRIGGER_RISINGEDGE 0 #define ABF_TRIGGER_FALLINGEDGE 1 // // Constants for nTriggerAction // #define ABF_TRIGGER_STARTEPISODE 0 #define ABF_TRIGGER_STARTRUN 1 #define ABF_TRIGGER_STARTTRIAL 2 // N.B. Discontinued in favor of nTrialTriggerSource // // Constants for nDrawingStrategy // #define ABF_DRAW_NONE 0 #define ABF_DRAW_REALTIME 1 #define ABF_DRAW_FULLSCREEN 2 #define ABF_DRAW_ENDOFRUN 3 // // Constants for nTiledDisplay // #define ABF_DISPLAY_SUPERIMPOSED 0 #define ABF_DISPLAY_TILED 1 // // Constants for nDataDisplayMode // #define ABF_DRAW_POINTS 0 #define ABF_DRAW_LINES 1 // // Constants for nArithmeticExpression // #define ABF_SIMPLE_EXPRESSION 0 #define ABF_RATIO_EXPRESSION 1 // // Constants for nLowpassFilterType & nHighpassFilterType // #define ABF_FILTER_NONE 0 #define ABF_FILTER_EXTERNAL 1 #define ABF_FILTER_SIMPLE_RC 2 #define ABF_FILTER_BESSEL 3 #define ABF_FILTER_BUTTERWORTH 4 // // Constants for nPNPosition // #define ABF_PN_BEFORE_EPISODE 0 #define ABF_PN_AFTER_EPISODE 1 // // Constants for nPNPolarity // #define ABF_PN_OPPOSITE_POLARITY -1 #define ABF_PN_SAME_POLARITY 1 // // Constants for nAutopeakPolarity // #define ABF_PEAK_NEGATIVE -1 #define ABF_PEAK_ABSOLUTE 0 #define ABF_PEAK_POSITIVE 1 // // Constants for nAutopeakSearchMode // #define ABF_PEAK_SEARCH_SPECIFIED -2 #define ABF_PEAK_SEARCH_ALL -1 // nAutopeakSearchMode 0..9 = epoch in waveform 0's epoch table // nAutopeakSearchMode 10..19 = epoch in waveform 1's epoch table // // Constants for nAutopeakBaseline // #define ABF_PEAK_BASELINE_SPECIFIED -3 #define ABF_PEAK_BASELINE_NONE -2 #define ABF_PEAK_BASELINE_FIRSTHOLDING -1 #define ABF_PEAK_BASELINE_LASTHOLDING -4 // // Constants for lAutopeakMeasurements // #define ABF_PEAK_MEASURE_PEAK 0x00000001 #define ABF_PEAK_MEASURE_PEAKTIME 0x00000002 #define ABF_PEAK_MEASURE_ANTIPEAK 0x00000004 #define ABF_PEAK_MEASURE_ANTIPEAKTIME 0x00000008 #define ABF_PEAK_MEASURE_MEAN 0x00000010 #define ABF_PEAK_MEASURE_STDDEV 0x00000020 #define ABF_PEAK_MEASURE_INTEGRAL 0x00000040 #define ABF_PEAK_MEASURE_MAXRISESLOPE 0x00000080 #define ABF_PEAK_MEASURE_MAXRISESLOPETIME 0x00000100 #define ABF_PEAK_MEASURE_MAXDECAYSLOPE 0x00000200 #define ABF_PEAK_MEASURE_MAXDECAYSLOPETIME 0x00000400 #define ABF_PEAK_MEASURE_RISETIME 0x00000800 #define ABF_PEAK_MEASURE_DECAYTIME 0x00001000 #define ABF_PEAK_MEASURE_HALFWIDTH 0x00002000 #define ABF_PEAK_MEASURE_BASELINE 0x00004000 #define ABF_PEAK_MEASURE_RISESLOPE 0x00008000 #define ABF_PEAK_MEASURE_DECAYSLOPE 0x00010000 #define ABF_PEAK_MEASURE_REGIONSLOPE 0x00020000 #define ABF_PEAK_MEASURE_ALL 0x0002FFFF // All of the above OR'd together. // // Constants for nStatsActiveChannels // #define ABF_PEAK_SEARCH_CHANNEL0 0x0001 #define ABF_PEAK_SEARCH_CHANNEL1 0x0002 #define ABF_PEAK_SEARCH_CHANNEL2 0x0004 #define ABF_PEAK_SEARCH_CHANNEL3 0x0008 #define ABF_PEAK_SEARCH_CHANNEL4 0x0010 #define ABF_PEAK_SEARCH_CHANNEL5 0x0020 #define ABF_PEAK_SEARCH_CHANNEL6 0x0040 #define ABF_PEAK_SEARCH_CHANNEL7 0x0080 #define ABF_PEAK_SEARCH_CHANNEL8 0x0100 #define ABF_PEAK_SEARCH_CHANNEL9 0x0200 #define ABF_PEAK_SEARCH_CHANNEL10 0x0400 #define ABF_PEAK_SEARCH_CHANNEL11 0x0800 #define ABF_PEAK_SEARCH_CHANNEL12 0x1000 #define ABF_PEAK_SEARCH_CHANNEL13 0x2000 #define ABF_PEAK_SEARCH_CHANNEL14 0x4000 #define ABF_PEAK_SEARCH_CHANNEL15 0x8000 #define ABF_PEAK_SEARCH_CHANNELSALL 0xFFFF // All of the above OR'd together. // Bit flag settings for nStatsSearchRegionFlags // #define ABF_PEAK_SEARCH_REGION0 0x01 #define ABF_PEAK_SEARCH_REGION1 0x02 #define ABF_PEAK_SEARCH_REGION2 0x04 #define ABF_PEAK_SEARCH_REGION3 0x08 #define ABF_PEAK_SEARCH_REGION4 0x10 #define ABF_PEAK_SEARCH_REGION5 0x20 #define ABF_PEAK_SEARCH_REGION6 0x40 #define ABF_PEAK_SEARCH_REGION7 0x80 #define ABF_PEAK_SEARCH_REGIONALL 0xFF // All of the above OR'd together. // // Constants for lStatisticsMeasurements // #define ABF_STATISTICS_ABOVETHRESHOLD 0x00000001 #define ABF_STATISTICS_EVENTFREQUENCY 0x00000002 #define ABF_STATISTICS_MEANOPENTIME 0x00000004 #define ABF_STATISTICS_MEANCLOSEDTIME 0x00000008 #define ABF_STATISTICS_ALL 0x0000000F // All the above OR'd together. // // Constants for nStatisticsSaveStrategy // #define ABF_STATISTICS_NOAUTOSAVE 0 #define ABF_STATISTICS_AUTOSAVE 1 #define ABF_STATISTICS_AUTOSAVE_AUTOCLEAR 2 // // Constants for nStatisticsDisplayStrategy // #define ABF_STATISTICS_DISPLAY 0 #define ABF_STATISTICS_NODISPLAY 1 // // Constants for nStatisticsClearStrategy // determines whether to clear statistics after saving. // #define ABF_STATISTICS_NOCLEAR 0 #define ABF_STATISTICS_CLEAR 1 // // Constants for nDACFileEpisodeNum // #define ABF_DACFILE_SKIPFIRSTSWEEP -1 #define ABF_DACFILE_USEALLSWEEPS 0 // >0 = The specific sweep number. // // Constants for nUndoPromptStrategy // #define ABF_UNDOPROMPT_ONABORT 0 #define ABF_UNDOPROMPT_ALWAYS 1 // // Constants for nAutoAnalyseEnable // #define ABF_AUTOANALYSE_DISABLED 0 #define ABF_AUTOANALYSE_DEFAULT 1 #define ABF_AUTOANALYSE_RUNMACRO 2 // // Constants for post nPostprocessLowpassFilterType // #define ABF_POSTPROCESS_FILTER_NONE 0 #define ABF_POSTPROCESS_FILTER_ADAPTIVE 1 #define ABF_POSTPROCESS_FILTER_BESSEL 2 #define ABF_POSTPROCESS_FILTER_BOXCAR 3 #define ABF_POSTPROCESS_FILTER_BUTTERWORTH 4 #define ABF_POSTPROCESS_FILTER_CHEBYSHEV 5 #define ABF_POSTPROCESS_FILTER_GAUSSIAN 6 #define ABF_POSTPROCESS_FILTER_RC 7 #define ABF_POSTPROCESS_FILTER_RC8 8 #define ABF_POSTPROCESS_FILTER_NOTCH 9 // // Miscellaneous constants // #define ABF_FILTERDISABLED 100000.0F // Large frequency to disable lowpass filters #define ABF_UNUSED_CHANNEL -1 // Unused ADC and DAC channels. // // The output sampling sequence identifier for a seperate digital out channel. // #define ABF_DIGITAL_OUT_CHANNEL -1 #define ABF_PADDING_OUT_CHANNEL -2 // // maximum values for various parameters (used by ABFH_CheckUserList). // #define ABF_CTPULSECOUNT_MAX 10000 #define ABF_CTBASELINEDURATION_MAX 100000.0F #define ABF_CTSTEPDURATION_MAX 100000.0F #define ABF_CTPOSTTRAINDURATION_MAX 100000.0F #define ABF_SWEEPSTARTTOSTARTTIME_MAX 100000.0F #define ABF_PNPULSECOUNT_MAX 8 #define ABF_DIGITALVALUE_MAX 0xFF #define ABF_EPOCHDIGITALVALUE_MAX 0x0F // // LTP Types - Reflects whether the header is used for LTP as baseline or induction. // #define ABF_LTP_TYPE_NONE 0 #define ABF_LTP_TYPE_BASELINE 1 #define ABF_LTP_TYPE_INDUCTION 2 // // LTP Usage of DAC - Reflects whether the analog output will be used presynaptically or postsynaptically. // #define ABF_LTP_DAC_USAGE_NONE 0 #define ABF_LTP_DAC_USAGE_PRESYNAPTIC 1 #define ABF_LTP_DAC_USAGE_POSTSYNAPTIC 2 // // Header Version Numbers // #define ABF_V166 1.66F #define ABF_V167 1.67F #define ABF_V168 1.68F #define ABF_V169 1.69F #define ABF_V170 1.70F #define ABF_V171 1.71F #define ABF_V172 1.72F #define ABF_V173 1.73F #define ABF_V174 1.74F #define ABF_V175 1.75F #define ABF_V176 1.76F #define ABF_V177 1.77F #define ABF_V178 1.78F #define ABF_V179 1.79F #define ABF_V180 1.80F #define ABF_V181 1.81F #define ABF_V182 1.82F #define ABF_V183 1.83F // // pack structure on byte boundaries // #ifndef RC_INVOKED #pragma pack(push, 1) #endif // // Definition of the ABF header structure. // struct ABFFileHeader // The total header length = 6144 bytes. { // GROUP #1 - File ID and size information. (40 bytes) ABFLONG lFileSignature; float fFileVersionNumber; short nOperationMode; ABFLONG lActualAcqLength; short nNumPointsIgnored; ABFLONG lActualEpisodes; ABFLONG lFileStartDate; // YYYYMMDD ABFLONG lFileStartTime; ABFLONG lStopwatchTime; float fHeaderVersionNumber; short nFileType; short nMSBinFormat; // GROUP #2 - File Structure (78 bytes) ABFLONG lDataSectionPtr; ABFLONG lTagSectionPtr; ABFLONG lNumTagEntries; ABFLONG lScopeConfigPtr; ABFLONG lNumScopes; ABFLONG _lDACFilePtr; ABFLONG _lDACFileNumEpisodes; char sUnused001[4]; ABFLONG lDeltaArrayPtr; ABFLONG lNumDeltas; ABFLONG lVoiceTagPtr; ABFLONG lVoiceTagEntries; ABFLONG lUnused002; ABFLONG lSynchArrayPtr; ABFLONG lSynchArraySize; short nDataFormat; short nSimultaneousScan; ABFLONG lStatisticsConfigPtr; ABFLONG lAnnotationSectionPtr; ABFLONG lNumAnnotations; char sUnused003[2]; // GROUP #3 - Trial hierarchy information (82 bytes) /** The number of input channels we acquired. Do not access directly - use CABFHeader::get_channel_count_acquired */ short channel_count_acquired; /** The number of input channels we recorded. Do not access directly - use CABFHeader::get_channel_count_recorded */ short nADCNumChannels; float fADCSampleInterval; /*{{ The documentation says these two sample intervals are the interval between multiplexed samples, but not all digitisers work like that. Instead, these are the per-channel sample rate divided by the number of channels. If the user chose 100uS and has two channels, this value will be 50uS. }}*/ float fADCSecondSampleInterval; /*{{ // The two sample intervals must be an integer multiple (or submultiple) of each other. if (fADCSampleInterval > fADCSecondSampleInterval) ASSERT(fmod(fADCSampleInterval, fADCSecondSampleInterval) == 0.0); if (fADCSecondSampleInterval, fADCSampleInterval) ASSERT(fmod(fADCSecondSampleInterval, fADCSampleInterval) == 0.0); }}*/ float fSynchTimeUnit; float fSecondsPerRun; /** * The total number of samples per episode, for the recorded channels only. * This does not include channels which are acquired but not recorded. * * This is the number of samples per episode per channel, times the number of recorded channels. * * If you want the samples per episode for one channel, you must divide this by get_channel_count_recorded(). */ ABFLONG lNumSamplesPerEpisode; ABFLONG lPreTriggerSamples; ABFLONG lEpisodesPerRun; ABFLONG lRunsPerTrial; ABFLONG lNumberOfTrials; short nAveragingMode; short nUndoRunCount; short nFirstEpisodeInRun; float fTriggerThreshold; short nTriggerSource; short nTriggerAction; short nTriggerPolarity; float fScopeOutputInterval; float fEpisodeStartToStart; float fRunStartToStart; float fTrialStartToStart; ABFLONG lAverageCount; ABFLONG lClockChange; short nAutoTriggerStrategy; // GROUP #4 - Display Parameters (44 bytes) short nDrawingStrategy; short nTiledDisplay; short nEraseStrategy; // N.B. Discontinued. Use scope config entry instead. short nDataDisplayMode; ABFLONG lDisplayAverageUpdate; short nChannelStatsStrategy; ABFLONG lCalculationPeriod; // N.B. Discontinued. Use fStatisticsPeriod. ABFLONG lSamplesPerTrace; ABFLONG lStartDisplayNum; ABFLONG lFinishDisplayNum; short nMultiColor; short nShowPNRawData; float fStatisticsPeriod; ABFLONG lStatisticsMeasurements; short nStatisticsSaveStrategy; // GROUP #5 - Hardware information (16 bytes) float fADCRange; float fDACRange; ABFLONG lADCResolution; ABFLONG lDACResolution; // GROUP #6 Environmental Information (118 bytes) short nExperimentType; short _nAutosampleEnable; short _nAutosampleADCNum; short _nAutosampleInstrument; float _fAutosampleAdditGain; float _fAutosampleFilter; float _fAutosampleMembraneCap; short nManualInfoStrategy; float fCellID1; float fCellID2; float fCellID3; char sCreatorInfo[ABF_CREATORINFOLEN]; char _sFileComment[ABF_OLDFILECOMMENTLEN]; short nFileStartMillisecs; // Milliseconds portion of lFileStartTime short nCommentsEnable; char sUnused003a[8]; // GROUP #7 - Multi-channel information (1044 bytes) short nADCPtoLChannelMap[ABF_ADCCOUNT]; short nADCSamplingSeq[ABF_ADCCOUNT]; char sADCChannelName[ABF_ADCCOUNT][ABF_ADCNAMELEN]; char sADCUnits[ABF_ADCCOUNT][ABF_ADCUNITLEN]; float fADCProgrammableGain[ABF_ADCCOUNT]; float fADCDisplayAmplification[ABF_ADCCOUNT]; float fADCDisplayOffset[ABF_ADCCOUNT]; float fInstrumentScaleFactor[ABF_ADCCOUNT]; float fInstrumentOffset[ABF_ADCCOUNT]; float fSignalGain[ABF_ADCCOUNT]; float fSignalOffset[ABF_ADCCOUNT]; float fSignalLowpassFilter[ABF_ADCCOUNT]; float fSignalHighpassFilter[ABF_ADCCOUNT]; char sDACChannelName[ABF_DACCOUNT][ABF_DACNAMELEN]; char sDACChannelUnits[ABF_DACCOUNT][ABF_DACUNITLEN]; float fDACScaleFactor[ABF_DACCOUNT]; float fDACHoldingLevel[ABF_DACCOUNT]; short nSignalType; char sUnused004[10]; // GROUP #8 - Synchronous timer outputs (14 bytes) short nOUTEnable; short nSampleNumberOUT1; short nSampleNumberOUT2; short nFirstEpisodeOUT; short nLastEpisodeOUT; short nPulseSamplesOUT1; short nPulseSamplesOUT2; // GROUP #9 - Epoch Waveform and Pulses (184 bytes) short nDigitalEnable; short _nWaveformSource; short nActiveDACChannel; short _nInterEpisodeLevel; short _nEpochType[ABF_EPOCHCOUNT]; float _fEpochInitLevel[ABF_EPOCHCOUNT]; float _fEpochLevelInc[ABF_EPOCHCOUNT]; short _nEpochInitDuration[ABF_EPOCHCOUNT]; short _nEpochDurationInc[ABF_EPOCHCOUNT]; short nDigitalHolding; short nDigitalInterEpisode; short nDigitalValue[ABF_EPOCHCOUNT]; char sUnavailable1608[4]; // was float fWaveformOffset; short nDigitalDACChannel; char sUnused005[6]; // GROUP #10 - DAC Output File (98 bytes) float _fDACFileScale; float _fDACFileOffset; char sUnused006[2]; short _nDACFileEpisodeNum; short _nDACFileADCNum; char _sDACFilePath[ABF_DACFILEPATHLEN]; // GROUP #11 - Presweep (conditioning) pulse train (44 bytes) short _nConditEnable; short _nConditChannel; ABFLONG _lConditNumPulses; float _fBaselineDuration; float _fBaselineLevel; float _fStepDuration; float _fStepLevel; float _fPostTrainPeriod; float _fPostTrainLevel; char sUnused007[12]; // GROUP #12 - Variable parameter user list ( 82 bytes) short _nParamToVary; char _sParamValueList[ABF_VARPARAMLISTLEN]; // GROUP #13 - Autopeak measurement (36 bytes) short _nAutopeakEnable; short _nAutopeakPolarity; short _nAutopeakADCNum; short _nAutopeakSearchMode; ABFLONG _lAutopeakStart; ABFLONG _lAutopeakEnd; short _nAutopeakSmoothing; short _nAutopeakBaseline; short _nAutopeakAverage; char sUnavailable1866[2]; // Was nAutopeakSaveStrategy, use nStatisticsSaveStrategy ABFLONG _lAutopeakBaselineStart; ABFLONG _lAutopeakBaselineEnd; ABFLONG _lAutopeakMeasurements; // GROUP #14 - Channel Arithmetic (52 bytes) short nArithmeticEnable; float fArithmeticUpperLimit; float fArithmeticLowerLimit; short nArithmeticADCNumA; short nArithmeticADCNumB; float fArithmeticK1; float fArithmeticK2; float fArithmeticK3; float fArithmeticK4; char sArithmeticOperator[ABF_ARITHMETICOPLEN]; char sArithmeticUnits[ABF_ARITHMETICUNITSLEN]; float fArithmeticK5; float fArithmeticK6; short nArithmeticExpression; char sUnused008[2]; // GROUP #15 - On-line subtraction (34 bytes) short _nPNEnable; short nPNPosition; short _nPNPolarity; short nPNNumPulses; short _nPNADCNum; float _fPNHoldingLevel; float fPNSettlingTime; float fPNInterpulse; char sUnused009[12]; // GROUP #16 - Miscellaneous variables (82 bytes) short _nListEnable; short nBellEnable[ABF_BELLCOUNT]; short nBellLocation[ABF_BELLCOUNT]; short nBellRepetitions[ABF_BELLCOUNT]; short nLevelHysteresis; ABFLONG lTimeHysteresis; short nAllowExternalTags; char nLowpassFilterType[ABF_ADCCOUNT]; char nHighpassFilterType[ABF_ADCCOUNT]; short nAverageAlgorithm; float fAverageWeighting; short nUndoPromptStrategy; short nTrialTriggerSource; short nStatisticsDisplayStrategy; short nExternalTagType; ABFLONG lHeaderSize; double dFileDuration; short nStatisticsClearStrategy; // Size of v1.5 header = 2048 // Extra parameters in v1.6 // EXTENDED GROUP #2 - File Structure (26 bytes) ABFLONG lDACFilePtr[ABF_WAVEFORMCOUNT]; ABFLONG lDACFileNumEpisodes[ABF_WAVEFORMCOUNT]; // EXTENDED GROUP #3 - Trial Hierarchy float fFirstRunDelay; char sUnused010[6]; // EXTENDED GROUP #7 - Multi-channel information (62 bytes) float fDACCalibrationFactor[ABF_DACCOUNT]; float fDACCalibrationOffset[ABF_DACCOUNT]; char sUnused011[30]; // GROUP #17 - Trains parameters (160 bytes) ABFLONG lEpochPulsePeriod[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; ABFLONG lEpochPulseWidth [ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; // EXTENDED GROUP #9 - Epoch Waveform and Pulses ( 412 bytes) short nWaveformEnable[ABF_WAVEFORMCOUNT]; short nWaveformSource[ABF_WAVEFORMCOUNT]; short nInterEpisodeLevel[ABF_WAVEFORMCOUNT]; short nEpochType[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; float fEpochInitLevel[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; float fEpochLevelInc[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; ABFLONG lEpochInitDuration[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; ABFLONG lEpochDurationInc[ABF_WAVEFORMCOUNT][ABF_EPOCHCOUNT]; short nDigitalTrainValue[ABF_EPOCHCOUNT]; // 2 * 10 = 20 bytes short nDigitalTrainActiveLogic; // 2 bytes char sUnused012[18]; // EXTENDED GROUP #10 - DAC Output File (552 bytes) float fDACFileScale[ABF_WAVEFORMCOUNT]; float fDACFileOffset[ABF_WAVEFORMCOUNT]; ABFLONG lDACFileEpisodeNum[ABF_WAVEFORMCOUNT]; short nDACFileADCNum[ABF_WAVEFORMCOUNT]; char sDACFilePath[ABF_WAVEFORMCOUNT][ABF_PATHLEN]; char sUnused013[12]; // EXTENDED GROUP #11 - Presweep (conditioning) pulse train (100 bytes) short nConditEnable[ABF_WAVEFORMCOUNT]; ABFLONG lConditNumPulses[ABF_WAVEFORMCOUNT]; float fBaselineDuration[ABF_WAVEFORMCOUNT]; float fBaselineLevel[ABF_WAVEFORMCOUNT]; float fStepDuration[ABF_WAVEFORMCOUNT]; float fStepLevel[ABF_WAVEFORMCOUNT]; float fPostTrainPeriod[ABF_WAVEFORMCOUNT]; float fPostTrainLevel[ABF_WAVEFORMCOUNT]; char sUnused014[40]; // EXTENDED GROUP #12 - Variable parameter user list (1096 bytes) short nULEnable[ABF_USERLISTCOUNT]; short nULParamToVary[ABF_USERLISTCOUNT]; char sULParamValueList[ABF_USERLISTCOUNT][ABF_USERLISTLEN]; short nULRepeat[ABF_USERLISTCOUNT]; char sUnused015[48]; // EXTENDED GROUP #15 - On-line subtraction (56 bytes) short nPNEnable[ABF_WAVEFORMCOUNT]; short nPNPolarity[ABF_WAVEFORMCOUNT]; short __nPNADCNum[ABF_WAVEFORMCOUNT]; float fPNHoldingLevel[ABF_WAVEFORMCOUNT]; short nPNNumADCChannels[ABF_WAVEFORMCOUNT]; char nPNADCSamplingSeq[ABF_WAVEFORMCOUNT][ABF_ADCCOUNT]; // EXTENDED GROUP #6 Environmental Information (898 bytes) short nTelegraphEnable[ABF_ADCCOUNT]; short nTelegraphInstrument[ABF_ADCCOUNT]; float fTelegraphAdditGain[ABF_ADCCOUNT]; float fTelegraphFilter[ABF_ADCCOUNT]; float fTelegraphMembraneCap[ABF_ADCCOUNT]; short nTelegraphMode[ABF_ADCCOUNT]; short nTelegraphDACScaleFactorEnable[ABF_DACCOUNT]; char sUnused016a[24]; short nAutoAnalyseEnable; char sAutoAnalysisMacroName[ABF_MACRONAMELEN]; char sProtocolPath[ABF_PATHLEN]; char sFileComment[ABF_FILECOMMENTLEN]; struct GUID FileGUID; float fInstrumentHoldingLevel[ABF_DACCOUNT]; uint32_t ulFileCRC; char sModifierInfo[ABF_CREATORINFOLEN]; char sUnused017[76]; // EXTENDED GROUP #13 - Statistics measurements (388 bytes) short nStatsEnable; unsigned short nStatsActiveChannels; // Active stats channel bit flag unsigned short nStatsSearchRegionFlags; // Active stats region bit flag short nStatsSelectedRegion; short _nStatsSearchMode; short nStatsSmoothing; short nStatsSmoothingEnable; short nStatsBaseline; ABFLONG lStatsBaselineStart; ABFLONG lStatsBaselineEnd; ABFLONG lStatsMeasurements[ABF_STATS_REGIONS]; // Measurement bit flag for each region ABFLONG lStatsStart[ABF_STATS_REGIONS]; ABFLONG lStatsEnd[ABF_STATS_REGIONS]; short nRiseBottomPercentile[ABF_STATS_REGIONS]; short nRiseTopPercentile[ABF_STATS_REGIONS]; short nDecayBottomPercentile[ABF_STATS_REGIONS]; short nDecayTopPercentile[ABF_STATS_REGIONS]; short nStatsChannelPolarity[ABF_ADCCOUNT]; short nStatsSearchMode[ABF_STATS_REGIONS]; // Stats mode per region: mode is cursor region, epoch etc char sUnused018[156]; // GROUP #18 - Application version data (16 bytes) short nCreatorMajorVersion; short nCreatorMinorVersion; short nCreatorBugfixVersion; short nCreatorBuildVersion; short nModifierMajorVersion; short nModifierMinorVersion; short nModifierBugfixVersion; short nModifierBuildVersion; // GROUP #19 - LTP protocol (14 bytes) short nLTPType; short nLTPUsageOfDAC[ABF_WAVEFORMCOUNT]; short nLTPPresynapticPulses[ABF_WAVEFORMCOUNT]; char sUnused020[4]; // GROUP #20 - Digidata 132x Trigger out flag. (8 bytes) short nDD132xTriggerOut; char sUnused021[6]; // GROUP #21 - Epoch resistance (40 bytes) char sEpochResistanceSignalName[ABF_WAVEFORMCOUNT][ABF_ADCNAMELEN]; short nEpochResistanceState[ABF_WAVEFORMCOUNT]; char sUnused022[16]; // GROUP #22 - Alternating episodic mode (58 bytes) short nAlternateDACOutputState; short nAlternateDigitalValue[ABF_EPOCHCOUNT]; short nAlternateDigitalTrainValue[ABF_EPOCHCOUNT]; short nAlternateDigitalOutputState; char sUnused023[14]; // GROUP #23 - Post-processing actions (210 bytes) float fPostProcessLowpassFilter[ABF_ADCCOUNT]; char nPostProcessLowpassFilterType[ABF_ADCCOUNT]; // 6014 header bytes allocated + 130 header bytes not allocated char sUnused2048[130]; }; // Size = 6144 // This structure is persisted, so the size MUST NOT CHANGE #if !defined(_WINDOWS) || defined(__MINGW32__) #define C_ASSERT(e) extern void __C_ASSERT__(int [(e)?1:-1]) #endif C_ASSERT(sizeof(struct ABFFileHeader) == 6144); /* inline ABFFileHeader::ABFFileHeader() { // Set everything to 0. memset( this, 0, sizeof(ABFFileHeader) ); // Set critical parameters so we can determine the version. lFileSignature = ABF_NATIVESIGNATURE; fFileVersionNumber = ABF_CURRENTVERSION; fHeaderVersionNumber = ABF_CURRENTVERSION; lHeaderSize = ABF_HEADERSIZE; } */ /* // // Scope descriptor format. // #define ABF_FACESIZE 32 struct ABFLogFont { short nHeight; // Height of the font in pixels. // short lWidth; // use 0 // short lEscapement; // use 0 // short lOrientation; // use 0 short nWeight; // MSWindows font weight value. // char bItalic; // use 0 // char bUnderline; // use 0 // char bStrikeOut; // use 0 // char cCharSet; // use ANSI_CHARSET (0) // char cOutPrecision; // use OUT_TT_PRECIS // char cClipPrecision; // use CLIP_DEFAULT_PRECIS // char cQuality; // use PROOF_QUALITY char cPitchAndFamily; // MSWindows pitch and family mask. char Unused[3]; // Unused space to maintain 4-byte packing. char szFaceName[ABF_FACESIZE];// Face name of the font. }; // Size = 40 struct ABFSignal { char szName[ABF_ADCNAMELEN+2]; // ABF name length + '\0' + 1 for alignment. short nMxOffset; // Offset of the signal in the sampling sequence. DWORD rgbColor; // Pen color used to draw trace. char nPenWidth; // Pen width in pixels. char bDrawPoints; // TRUE = Draw disconnected points char bHidden; // TRUE = Hide the trace. char bFloatData; // TRUE = Floating point pseudo channel float fVertProportion; // Relative proportion of client area to use float fDisplayGain; // Display gain of trace in UserUnits float fDisplayOffset; // Display offset of trace in UserUnits // float fUUTop; // Top of window in UserUnits // float fUUBottom; // Bottom of window in UserUnits }; // Size = 34 /////////////////////////////////////////////////////////////////////////////////// //// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ////// /////////////////////////////////////////////////////////////////////////////////// // The Following #defines appear to be largely unused in opur code base // However there does exist a second set of #defines in AxScope32.h // that REALLY defines what these bits in the header do. // In particular it important to note that all 32 bits are in fact used internally /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// // Bit flags used in dwFlags field of ABFScopeConfig. #define ABF_OVERLAPPED 0x00000001 #define ABF_DONTERASE 0x00000002 #define ABF_MONOCHROME 0x00000004 #define ABF_CLIPPING 0x00000008 #define ABF_HIDEHORZGRIDS 0x00000010 #define ABF_HIDEVERTGRIDS 0x00000020 #define ABF_FULLSCREEN 0x00000040 #define ABF_HIDEXAXIS 0x00000080 #define ABF_HIDEYAXIS 0x00000100 #define ABF_HIDEXSCROLL 0x00000200 #define ABF_HIDEYSCROLL 0x00000400 #define ABF_HIDESIGNALNAME 0x00000800 #define ABF_ENABLEZOOM 0x00001000 #define ABF_XSPINFROMCENTER 0x00002000 #define ABF_HIDEXSPINNER 0x00004000 #define ABF_LARGESPINNERS 0x00008000 #define ABF_PERSISTENCEMODE 0x00010000 #define ABF_CARDIACMODE 0x00020000 #define ABF_HIDETWIRLER 0x00040000 #define ABF_DISABLEUI 0x00080000 /////////////////////////////////////////////////////////////////////////////////// // #define ABF_INTERNALUSE 0xFFF00000 // Do not add extra bit flags ^^^ here they are used internally /////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////// //// DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER DANGER// /////////////////////////////////////////////////////////////////////////////////// // Values for the wScopeMode field in ABFScopeConfig. #define ABF_EPISODICMODE 0 #define ABF_CONTINUOUSMODE 1 //#define ABF_XYMODE 2 // Values for the nEraseStrategy field in ABFScopeConfig. #define ABF_ERASE_EACHSWEEP 0 #define ABF_ERASE_EACHRUN 1 #define ABF_ERASE_EACHTRIAL 2 #define ABF_ERASE_DONTERASE 3 // Indexes into the rgbColor field of ABFScopeConfig. #define ABF_BACKGROUNDCOLOR 0 #define ABF_GRIDCOLOR 1 #define ABF_THRESHOLDCOLOR 2 #define ABF_EVENTMARKERCOLOR 3 #define ABF_SEPARATORCOLOR 4 #define ABF_AVERAGECOLOR 5 #define ABF_OLDDATACOLOR 6 #define ABF_TEXTCOLOR 7 #define ABF_AXISCOLOR 8 #define ABF_ACTIVEAXISCOLOR 9 #define ABF_LASTCOLOR ABF_ACTIVEAXISCOLOR #define ABF_SCOPECOLORS (ABF_LASTCOLOR+1) // Extended colors for rgbColorEx field in ABFScopeConfig #define ABF_STATISTICS_REGION0 0 #define ABF_STATISTICS_REGION1 1 #define ABF_STATISTICS_REGION2 2 #define ABF_STATISTICS_REGION3 3 #define ABF_STATISTICS_REGION4 4 #define ABF_STATISTICS_REGION5 5 #define ABF_STATISTICS_REGION6 6 #define ABF_STATISTICS_REGION7 7 #define ABF_BASELINE_REGION 8 #define ABF_STOREDSWEEPCOLOR 9 #define ABF_LASTCOLOR_EX ABF_STOREDSWEEPCOLOR #define ABF_SCOPECOLORS_EX (ABF_LASTCOLOR+1) // Values for the nDockState field in ABFScopeConfig #define ABF_SCOPE_NOTDOCKED 0 #define ABF_SCOPE_DOCKED_TOP 1 #define ABF_SCOPE_DOCKED_LEFT 2 #define ABF_SCOPE_DOCKED_RIGHT 3 #define ABF_SCOPE_DOCKED_BOTTOM 4 struct ABFScopeConfig { // Section 1 scope configurations DWORD dwFlags; // Flags that are meaningful to the scope. DWORD rgbColor[ABF_SCOPECOLORS]; // Colors for the components of the scope. float fDisplayStart; // Start of the display area in ms. float fDisplayEnd; // End of the display area in ms. WORD wScopeMode; // Mode that the scope is in. char bMaximized; // TRUE = Scope parent is maximized. char bMinimized; // TRUE = Scope parent is minimized. short xLeft; // Coordinate of the left edge. short yTop; // Coordinate of the top edge. short xRight; // Coordinate of the right edge. short yBottom; // Coordinate of the bottom edge. ABFLogFont LogFont; // Description of current font. ABFSignal TraceList[ABF_ADCCOUNT]; // List of traces in current use. short nYAxisWidth; // Width of the YAxis region. short nTraceCount; // Number of traces described in TraceList. short nEraseStrategy; // Erase strategy. short nDockState; // Docked position. // Size 656 // * Do not insert any new members above this point! * // Section 2 scope configurations for file version 1.68. short nSizeofOldStructure; // Unused byte to determine the offset of the version 2 data. DWORD rgbColorEx[ ABF_SCOPECOLORS_EX ]; // New color settings for stored sweep and cursors. short nAutoZeroState; // Status of the autozero selection. DWORD dwCursorsVisibleState; // Flag for visible status of cursors. DWORD dwCursorsLockedState; // Flag for enabled status of cursors. char sUnasigned[61]; // Size 113 ABFScopeConfig(); }; // Size = 769 inline ABFScopeConfig::ABFScopeConfig() { // Set everything to 0. memset( this, 0, sizeof(ABFScopeConfig) ); // Set critical parameters so we can determine the version. nSizeofOldStructure = 656; } */ // // Definition of the ABF synch array structure // struct ABFSynch { ABFLONG lStart; // Start of the episode/event in fSynchTimeUnit units. ABFLONG lLength; // Length of the episode/event in multiplexed samples. }; // Size = 8 // // Constants for nTagType in the ABFTag structure. // #define ABF_TIMETAG 0 #define ABF_COMMENTTAG 1 #define ABF_EXTERNALTAG 2 #define ABF_VOICETAG 3 #define ABF_NEWFILETAG 4 #define ABF_ANNOTATIONTAG 5 // Same as a comment tag except that nAnnotationIndex holds // the index of the annotation that holds extra information. // // Definition of the ABF Tag structure // struct ABFTag { ABFLONG lTagTime; // Time at which the tag was entered in fSynchTimeUnit units. char sComment[ABF_TAGCOMMENTLEN]; // Optional tag comment. short nTagType; // Type of tag ABF_TIMETAG, ABF_COMMENTTAG, ABF_EXTERNALTAG, ABF_VOICETAG, ABF_NEWFILETAG or ABF_ANNOTATIONTAG union { short nVoiceTagNumber; // If nTagType=ABF_VOICETAG, this is the number of this voice tag. short nAnnotationIndex; // If nTagType=ABF_ANNOTATIONTAG, this is the index of the corresponding annotation. }; }; // Size = 64 // Comment inserted for externally acquired tags (expanded with spaces to ABF_TAGCOMMENTLEN). #define ABF_EXTERNALTAGCOMMENT "" #define ABF_VOICETAGCOMMENT "" // // Constants for nCompressionType in the ABFVoiceTagInfo structure. // #define ABF_COMPRESSION_NONE 0 #define ABF_COMPRESSION_PKWARE 1 //#define ABF_COMPRESSION_MPEG 2 // // Definition of the ABFVoiceTagInfo structure. // struct ABFVoiceTagInfo { ABFLONG lTagNumber; // The tag number that corresponds to this VoiceTag ABFLONG lFileOffset; // Offset to this tag within the VoiceTag block ABFLONG lUncompressedSize; // Size of the voice tag expanded. ABFLONG lCompressedSize; // Compressed size of the tag. short nCompressionType; // Compression method used. short nSampleSize; // Size of the samples acquired. ABFLONG lSamplesPerSecond; // Rate at which the sound was acquired. uint32_t dwCRC; // CRC used to check data integrity. uint16_t wChannels; // Number of channels in the tag (usually 1). uint16_t wUnused; // Unused space. }; // Size 32 // // Constants for lParameterID in the ABFDelta structure. // // NOTE: If any changes are made to this list, the code in ABF_UpdateHeader must // be updated to include the new items. #define ABF_DELTA_HOLDING0 0 #define ABF_DELTA_HOLDING1 1 #define ABF_DELTA_HOLDING2 2 #define ABF_DELTA_HOLDING3 3 #define ABF_DELTA_DIGITALOUTS 4 #define ABF_DELTA_THRESHOLD 5 #define ABF_DELTA_PRETRIGGER 6 // Because of lack of space, the Autosample Gain ID also contains the ADC number. #define ABF_DELTA_AUTOSAMPLE_GAIN 100 // +ADC channel. // Because of lack of space, the Signal Gain ID also contains the ADC number. #define ABF_DELTA_SIGNAL_GAIN 200 // +ADC channel. // // Definition of the ABF Delta structure. // struct ABFDelta { ABFLONG lDeltaTime; // Time at which the parameter was changed in fSynchTimeUnit units. ABFLONG lParameterID; // Identifier for the parameter changed union { ABFLONG lNewParamValue; // Depending on the value of lParameterID float fNewParamValue; // this entry may be either a float or a long. }; }; // Size = 12 #ifndef RC_INVOKED #pragma pack(pop) // return to default packing #endif /* // // The size of the buffers to be passed to ABFH_GetWaveformVertor // #define ABFH_MAXVECTORS 30 // // Function prototypes for functions in ABFHEADR.C // void WINAPI ABFH_Initialize( ABFFileHeader *pFH ); void WINAPI ABFH_InitializeScopeConfig(const ABFFileHeader *pFH, ABFScopeConfig *pCfg); BOOL WINAPI ABFH_CheckScopeConfig(ABFFileHeader *pFH, ABFScopeConfig *pCfg); void WINAPI ABFH_GetADCDisplayRange( const ABFFileHeader *pFH, int nChannel, float *pfUUTop, float *pfUUBottom); void WINAPI ABFH_GetADCtoUUFactors( const ABFFileHeader *pFH, int nChannel, float *pfADCToUUFactor, float *pfADCToUUShift ); void WINAPI ABFH_ClipADCUUValue(const ABFFileHeader *pFH, int nChannel, float *pfUUValue); void WINAPI ABFH_GetDACtoUUFactors( const ABFFileHeader *pFH, int nChannel, float *pfDACToUUFactor, float *pfDACToUUShift ); void WINAPI ABFH_ClipDACUUValue(const ABFFileHeader *pFH, int nChannel, float *pfUUValue); BOOL WINAPI ABFH_GetMathValue(const ABFFileHeader *pFH, float fA, float fB, float *pfRval); int WINAPI ABFH_GetMathChannelName(char *pszName, UINT uNameLen); BOOL WINAPI ABFH_ParamReader( FILEHANDLE hFile, ABFFileHeader *pFH, int *pnError ); BOOL WINAPI ABFH_ParamReaderEx( HANDLE hFile, ABFFileHeader *pFH, int *pnError ); BOOL WINAPI ABFH_ParamWriter( HANDLE hFile, ABFFileHeader *pFH, int *pnError ); BOOL WINAPI ABFH_GetErrorText( int nError, char *pszBuffer, UINT nBufferSize ); // ABFHWAVE.CPP // Constants for ABFH_GetEpochLimits #define ABFH_FIRSTHOLDING -1 #define ABFH_LASTHOLDING ABF_EPOCHCOUNT // Return the bounds of a given epoch in a given episode. Values returned are ZERO relative. BOOL WINAPI ABFH_GetEpochLimits(const ABFFileHeader *pFH, int nADCChannel, DWORD dwEpisode, int nEpoch, UINT *puEpochStart, UINT *puEpochEnd, int *pnError); BOOL WINAPI ABFH_GetEpochLimitsEx(const ABFFileHeader *pFH, int nADCChannel, UINT uDACChannel, DWORD dwEpisode, int nEpoch, UINT *puEpochStart, UINT *puEpochEnd, int *pnError); // Get the offset in the sampling sequence for the given physical channel. BOOL WINAPI ABFH_GetChannelOffset( const ABFFileHeader *pFH, int nChannel, UINT *puChannelOffset ); // This function forms the de-multiplexed DAC output waveform for the // particular channel in the pfBuffer, in DAC UserUnits. BOOL WINAPI ABFH_GetWaveform( const ABFFileHeader *pFH, int nADCChannel, DWORD dwEpisode, float *pfBuffer, int *pnError); BOOL WINAPI ABFH_GetWaveformEx( const ABFFileHeader *pFH, UINT uDACChannel, DWORD dwEpisode, float *pfBuffer, int *pnError); // This function forms the de-multiplexed Digital output waveform for the // particular channel in the pdwBuffer, as a bit mask. Digital OUT 0 is in bit 0. BOOL WINAPI ABFH_GetDigitalWaveform( const ABFFileHeader *pFH, int nChannel, DWORD dwEpisode, DWORD *pdwBuffer, int *pnError); // Returns vector pairs for displaying a waveform made up of epochs. BOOL WINAPI ABFH_GetWaveformVector(const ABFFileHeader *pFH, DWORD dwEpisode, UINT uStart, UINT uFinish, float *pfLevels, float *pfTimes, int *pnVectors, int *pnError); // Returns vector pairs for displaying the digital outs. BOOL WINAPI ABFH_GetDigitalWaveformVector(const ABFFileHeader *pFH, DWORD dwEpisode, UINT uStart, UINT uFinish, DWORD *pdwLevels, float *pfTimes, int *pnVectors, int *pnError); // Calculates the timebase array for the file. void WINAPI ABFH_GetTimebase(const ABFFileHeader *pFH, float fTimeOffset, float *pfBuffer, UINT uBufferSize); void WINAPI ABFH_GetTimebaseEx(const ABFFileHeader *pFH, double dTimeOffset, double *pdBuffer, UINT uBufferSize); // Constant for ABFH_GetHoldingDuration #define ABFH_HOLDINGFRACTION 64 // Get the duration of the first holding period. UINT WINAPI ABFH_GetHoldingDuration(const ABFFileHeader *pFH); // Checks whether the waveform varies from episode to episode. BOOL WINAPI ABFH_IsConstantWaveform(const ABFFileHeader *pFH); BOOL WINAPI ABFH_IsConstantWaveformEx(const ABFFileHeader *pFH, UINT uDACChannel); // Checks that the sample intervals in the header are valid. BOOL WINAPI ABFH_CheckSampleIntervals(const ABFFileHeader *pFH, float fClockResolution, int *pnError); // Gets the closest sample intervals higher and lower than the passed interval. void WINAPI ABFH_GetClosestSampleIntervals(float fSampleInterval, float fClockResolution, int nOperationMode, float fMinPeriod, float fMaxPeriod, float *pfHigher, float *pfLower); // Sets up the list for the spinner to drive the sampling interval through. UINT WINAPI ABFH_SetupSamplingList(UINT uNumChannels, float fMinPeriod, float fMaxPeriod, float *pfIntervalList, UINT uListEntries); // Get the full sweep length given the length available to epochs or vice-versa. int WINAPI ABFH_SweepLenFromUserLen(int nUserLength, int nNumChannels); int WINAPI ABFH_UserLenFromSweepLen(int nSweepLength, int nNumChannels); // Converts a display range to the equivalent gain and offset factors. void WINAPI ABFH_GainOffsetToDisplayRange( const ABFFileHeader *pFH, int nChannel, float fDisplayGain, float fDisplayOffset, float *pfUUTop, float *pfUUBottom); // Converts a display range to the equivalent gain and offset factors. void WINAPI ABFH_DisplayRangeToGainOffset( const ABFFileHeader *pFH, int nChannel, float fUUTop, float fUUBottom, float *pfDisplayGain, float *pfDisplayOffset); // Converts a time value to a synch time count or vice-versa. void WINAPI ABFH_SynchCountToMS(const ABFFileHeader *pFH, UINT uCount, double *pdTimeMS); UINT WINAPI ABFH_MSToSynchCount(const ABFFileHeader *pFH, double dTimeMS); // Gets the point at which the sampling interval changes if split clock. UINT WINAPI ABFH_GetClockChange(const ABFFileHeader *pFH); // Gets the duration of the Waveform Episode (in us), allowing for split clock etc. void WINAPI ABFH_GetEpisodeDuration(const ABFFileHeader *pFH, double *pdEpisodeDuration); // Gets the duration of a P/N sequence (in us), including settling times. void WINAPI ABFH_GetPNDuration(const ABFFileHeader *pFH, double *pdPNDuration); void WINAPI ABFH_GetPNDurationEx(const ABFFileHeader *pFH, UINT uDAC, double *pdPNDuration); // Gets the duration of a pre-sweep train in us. void WINAPI ABFH_GetTrainDuration(const ABFFileHeader *pFH, double *pdTrainDuration); void WINAPI ABFH_GetTrainDurationEx (const ABFFileHeader *pFH, UINT uDAC, double *pdTrainDuration); // Gets the duration of a whole meta-episode (in us). void WINAPI ABFH_GetMetaEpisodeDuration(const ABFFileHeader *pFH, double *pdMetaEpisodeDuration); // Gets the start to start period for the episode in us. void WINAPI ABFH_GetEpisodeStartToStart(const ABFFileHeader *pFH, double *pdEpisodeStartToStart); // Checks that the user list contains valid entries for the protocol. BOOL WINAPI ABFH_CheckUserList(const ABFFileHeader *pFH, int *pnError); BOOL WINAPI ABFH_CheckUserListEx(const ABFFileHeader *pFH, UINT uListNum, int *pnError); // Checks if the ABFFileHeader is a new (6k) or old (2k) header. //BOOL WINAPI ABFH_IsNewHeader(const ABFFileHeader *pFH); // Demotes a new ABF header to a 1.5 version ABF header. void WINAPI ABFH_DemoteHeader(ABFFileHeader *pOut, const ABFFileHeader *pIn ); // Promotes an old ABF header to a 1.8 version ABF header. void WINAPI ABFH_PromoteHeader(ABFFileHeader *pOut, const ABFFileHeader *pIn ); // Gets the first sample interval, expressed as a double. double WINAPI ABFH_GetFirstSampleInterval( const ABFFileHeader *pFH ); // Gets the second sample interval expressed as a double. double WINAPI ABFH_GetSecondSampleInterval( const ABFFileHeader *pFH ); // Counts the number of changing sweeps. UINT WINAPI ABFH_GetNumberOfChangingSweeps( const ABFFileHeader *pFH ); // // Checks whether the digital output varies from episode to episode. BOOL WINAPI ABFH_IsConstantDigitalOutput(const ABFFileHeader *pFH); BOOL WINAPI ABFH_IsConstantDigitalOutputEx(const ABFFileHeader *pFH, UINT uDACChannel); int WINAPI ABFH_GetEpochDuration(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch); float WINAPI ABFH_GetEpochLevel(const ABFFileHeader *pFH, UINT uDACChannel, UINT uEpisode, int nEpoch); BOOL WINAPI ABFH_GetEpochLevelRange(const ABFFileHeader *pFH, UINT uDACChannel, int nEpoch, float *pfMin, float *pfMax); UINT WINAPI ABFH_GetMaxPNSubsweeps(const ABFFileHeader *pFH, UINT uDACChannel); */ // // Error return values that may be returned by the ABFH_xxx functions. // #define ABFH_FIRSTERRORNUMBER 2001 #define ABFH_EHEADERREAD 2001 #define ABFH_EHEADERWRITE 2002 #define ABFH_EINVALIDFILE 2003 #define ABFH_EUNKNOWNFILETYPE 2004 #define ABFH_CHANNELNOTSAMPLED 2005 #define ABFH_EPOCHNOTPRESENT 2006 #define ABFH_ENOWAVEFORM 2007 #define ABFH_EDACFILEWAVEFORM 2008 #define ABFH_ENOMEMORY 2009 #define ABFH_BADSAMPLEINTERVAL 2010 #define ABFH_BADSECONDSAMPLEINTERVAL 2011 #define ABFH_BADSAMPLEINTERVALS 2012 #define ABFH_ENOCONDITTRAINS 2013 #define ABFH_EMETADURATION 2014 #define ABFH_ECONDITNUMPULSES 2015 #define ABFH_ECONDITBASEDUR 2016 #define ABFH_ECONDITBASELEVEL 2017 #define ABFH_ECONDITPOSTTRAINDUR 2018 #define ABFH_ECONDITPOSTTRAINLEVEL 2019 #define ABFH_ESTART2START 2020 #define ABFH_EINACTIVEHOLDING 2021 #define ABFH_EINVALIDCHARS 2022 #define ABFH_ENODIG 2023 #define ABFH_EDIGHOLDLEVEL 2024 #define ABFH_ENOPNPULSES 2025 #define ABFH_EPNNUMPULSES 2026 #define ABFH_ENOEPOCH 2027 #define ABFH_EEPOCHLEN 2028 #define ABFH_EEPOCHINITLEVEL 2029 #define ABFH_EDIGLEVEL 2030 #define ABFH_ECONDITSTEPDUR 2031 #define ABFH_ECONDITSTEPLEVEL 2032 #define ABFH_EINVALIDBINARYCHARS 2033 #define ABFH_EBADWAVEFORM 2034 #ifdef __cplusplus } #endif #endif /* INC_ABFHEADR_H */ stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_rhd2000_read.c0000664000175000017500000005450614752215315016772 /* Copyright (C) 2019,2020 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. */ /* References: [1] RHD2000 Application Note: Data File Formats, Intan TECHNOLOGIES, LLC Downloaded 2020-01-14 from http://www.intantech.com/files/Intan_RHD2000_data_file_formats.pdf [2] RHS2000 Data File Formats - Intan Tech http://www.intantech.com/files/Intan_RHS2000_data_file_formats.pdf */ #include #include #include #include #include #include #if !defined(__APPLE__) && defined (_LIBICONV_H) #define iconv libiconv #define iconv_open libiconv_open #define iconv_close libiconv_close #endif #include "../gdftime.h" #include "../biosig-dev.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) #ifdef __cplusplus extern "C" { #endif /* get_qstring has the following functions and side effects: *) check whether sufficient data of the header information has been read, reads more data if needed, *) advance position pointer pos to the end of the string; *) convert QString into UTF-8 String in outbuf */ void read_qstring(HDRTYPE* hdr, size_t *pos, char *outbuf, size_t outlen) { uint32_t len = leu32p(hdr->AS.Header + (*pos)); *pos += 4; if (len==(uint32_t)(-1)) return; // after each qstring at most 28 bytes are loaded before the next check for a qstring // This check is also needed when qstring is empty size_t SIZE = *pos+len+100; if (SIZE > hdr->HeadLen) { SIZE = max(SIZE, 2*hdr->HeadLen); // always double size of header void *ptr = realloc(hdr->AS.Header, SIZE); if (ptr==NULL) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Format Intan RH[DS]2000 - memory allocation failed"); return; } hdr->AS.Header = (uint8_t*)ptr; hdr->HeadLen += ifread(hdr->AS.Header+hdr->HeadLen, 1, SIZE-hdr->HeadLen, hdr); } if ((*pos + len ) > hdr->HeadLen) biosigERROR(hdr, B4C_INCOMPLETE_FILE, "Format Intan RHD2000 - incomplete file"); // convert qString into UTF-8 string if (outbuf != NULL) { iconv_t CD = iconv_open ("UTF-8", "UTF-16LE"); size_t inlen = len; char *inbuf = hdr->AS.Header+(*pos); size_t iconv_res = iconv (CD, &inbuf, &inlen, &outbuf, &outlen); *outbuf = '\0'; iconv_close (CD); } *pos += len; return; } int sopen_intan_clp_read(HDRTYPE* hdr) { uint16_t NumADCs=0, NumChips=0, NumChan=0; float minor = leu16p(hdr->AS.Header+6); minor *= (minor < 10) ? 0.1 : 0.01; hdr->VERSION = leu16p(hdr->AS.Header+4) + minor; uint16_t datatype=leu16p(hdr->AS.Header+8); switch (datatype) { case 1: NumADCs=leu16p(hdr->AS.Header+10); hdr->SampleRate = lef32p(hdr->AS.Header+24); case 0: break; default: // this should never ever occurs, because getfiletype checks this biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format Intan CLP - datatype unknown"); return -1; } size_t HeadLen=leu16p(hdr->AS.Header+10+(datatype*2)); // read header if (HeadLen > hdr->HeadLen) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, HeadLen+1); hdr->HeadLen += ifread(hdr->AS.Header+HeadLen, 1, HeadLen - hdr->HeadLen, hdr); } hdr->AS.Header[hdr->HeadLen]=0; if (HeadLen > hdr->HeadLen) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format Intan/CLP - file is too short"); return -1; } ifseek(hdr, HeadLen, SEEK_SET); // read recording date and time size_t pos=12+(datatype*2); { struct tm t0; t0.tm_year = leu16p(hdr->AS.Header+pos); t0.tm_mon = leu16p(hdr->AS.Header+pos+2); t0.tm_mday = leu16p(hdr->AS.Header+pos+4); t0.tm_hour = leu16p(hdr->AS.Header+pos+6); t0.tm_min = leu16p(hdr->AS.Header+pos+8); t0.tm_sec = leu16p(hdr->AS.Header+pos+10); hdr->T0 = tm_time2gdf_time(&t0); } switch (datatype) { case 0: // If this is the standard data file (including clamp and measured data), /* TODO: read chips read settings */ break; case 1: // If this is the aux data file (including Digital Ins/Outs and ADC data) default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format Intan CLP - datatype unknown"); return -1; } switch (datatype) { case 0: { // read chips pos = 24; NumChips=leu16p(hdr->AS.Header+pos); NumChan=leu16p(hdr->AS.Header+pos+2); for (uint16_t k1 = 0; k1 < NumChips; k1++) { for (uint16_t k2 = 0; k2 < NumChan; k2++) { // read one header per chip //14*2+4+4+16+20+4 } // read } pos += ((14*2+4+4+16+20+4) * NumChan + 8) * NumChips; // read settings hdr->NS = 4; hdr->SPR = 1; hdr->NRec = -1; hdr->AS.bpb= 16; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); // see below // strcpy(hdr->CHANNEL[0].Label,"Time"); strcpy(hdr->CHANNEL[1].Label,"Clamp"); strcpy(hdr->CHANNEL[2].Label,"TotalClamp"); strcpy(hdr->CHANNEL[3].Label,"Measured"); for (int k=0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Transducer[0]='\0'; hc->OnOff=1; hc->GDFTYP=16; hc->DigMax=+1e9; hc->DigMin=-1e9; hc->Cal=1; hc->Off=0; } break; } case 1: { hdr->NS = NumADCs; hdr->SPR = 1; hdr->NRec = -1; hdr->AS.bpb= 4 + 2 + 2 + 2 * NumADCs; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); for (int k=0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; sprintf(hdr->CHANNEL[3].Label, "ADC%d", k-2); hc->Transducer[0]='\0'; hc->OnOff=1; hc->GDFTYP=4; hc->DigMax=65535.0; hc->DigMin=0; hc->Cal = (k < 3) ? 1.0 : 0.0003125; hc->Off = (k < 3) ? 0.0 : -10.24; } // see below // strcpy(hdr->CHANNEL[0].Label, "Time"); strcpy(hdr->CHANNEL[1].Label,"DigitalIn"); strcpy(hdr->CHANNEL[2].Label,"DigitalOut"); break; } default: ; } hdr->CHANNEL[0].OnOff=2; //uint32 hdr->CHANNEL[0].GDFTYP=6; //uint32 hdr->CHANNEL[0].DigMax=ldexp(1l,32)-1; //uint32 hdr->CHANNEL[0].DigMin=0.0; //uint32 hdr->CHANNEL[0].Cal=1.0/hdr->SampleRate; //uint32 hdr->CHANNEL[0].PhysDimCode = 2176; //uint32 strcpy(hdr->CHANNEL[0].Label, "Time"); hdr->AS.bpb = 0; for (int k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->LeadIdCode = 0; hc->PhysDimCode = 0; hc->TOffset = 0; hc->LowPass = NAN; hc->HighPass = NAN; hc->Notch = NAN; hc->Impedance = NAN; hc->fZ = NAN; hc->SPR = 1; memset(hc->XYZ, 0, 12); hc->bi = hdr->AS.bpb; hdr->AS.bpb += (GDFTYP_BITS[hc->GDFTYP]*(size_t)hc->SPR) >> 3; } biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format Intan/CLP not supported"); return -1; } /* RHS2000 Data File Formats - Intan Tech http://www.intantech.com/files/Intan_RHS2000_data_file_formats.pdf */ int sopen_rhs2000_read(HDRTYPE* hdr) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %u); %s(...) [%u]\n",__FILE__,__LINE__,__func__,hdr->HeadLen); // 8 bytes int16_t major = leu16p(hdr->AS.Header+4); int16_t minor = leu16p(hdr->AS.Header+6); hdr->VERSION = major + minor * (minor < 10 ? 0.1 : 0.01); // +38 = 46 bytes hdr->NS = 1; hdr->SampleRate = lef32p(hdr->AS.Header+8); float HighPass = ( leu16p(hdr->AS.Header+12) ? lef32p(hdr->AS.Header+14) : 0.0 ); HighPass = max( HighPass, lef32p(hdr->AS.Header+18) ); float LowPass = lef32p(hdr->AS.Header+26); // +10 = 56 bytes const int ListNotch[] = {0,50,60}; uint16_t tmp = leu16p(hdr->AS.Header+46); if (tmp>2) tmp=0; float Notch = ListNotch[tmp]; float fZ_desired = lef32p(hdr->AS.Header+46); // desired impedance test frequency float fZ_actual = lef32p(hdr->AS.Header+50); // actual impedance test frequency // +4 = 60 bytes // +12 = 72 bytes float StimStepSize = lef32p(hdr->AS.Header+58); // Stim Step Size [A] float ChargeRecoveryCurrentLimit = lef32p(hdr->AS.Header+62); // [A] float ChargeRecoveryTargetVoltage = lef32p(hdr->AS.Header+66); // [V] size_t pos = 72; read_qstring(hdr, &pos, NULL, 0); // note1 read_qstring(hdr, &pos, NULL, 0); // note2 read_qstring(hdr, &pos, NULL, 0); // note3 uint16_t flag_DC_amplifier_data_saved = leu16p(hdr->AS.Header+pos) > 0; pos += 2; uint16_t BoardMode = leu16p(hdr->AS.Header+pos); pos += 2; char *ReferenceChannelName = NULL; read_qstring(hdr, &pos, ReferenceChannelName, 0); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %u); %s(...) %u %u\n", __FILE__, __LINE__, __func__, (unsigned)pos, hdr->HeadLen); uint16_t numberOfSignalGroups = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t NS = 0; hdr->SPR = (major == 1 ? 60 : 128); size_t bi = (0+4)*hdr->SPR; // read all signal groups for (int nsg=0; nsg < numberOfSignalGroups; nsg++) { char SignalGroupName[101], SignalGroupPrefix[101]; read_qstring(hdr, &pos, SignalGroupName, 100); read_qstring(hdr, &pos, SignalGroupPrefix, 100); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %u); %s(...) group=%u %u SGP<%s> SGP<%s>\n",__FILE__,__LINE__,__func__, nsg, (unsigned)pos, SignalGroupName,SignalGroupPrefix ); uint16_t flag_SignalGroupEnabled = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t NumberOfChannelsInSignalGroup = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t NumberOfAmplifierChannelsInSignalGroup = leu16p(hdr->AS.Header+pos); pos += 2; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %u); %s(...) group=%u %u+%u %d\n", __FILE__, __LINE__, __func__, nsg, NS, NumberOfChannelsInSignalGroup, (int)pos); if (flag_SignalGroupEnabled) { typeof(pos) tmppos = pos; int NumChans0 = 0; int NumChans1 = 0; // get number of enabled channels for (unsigned k = 0; k < NumberOfChannelsInSignalGroup; k++) { read_qstring(hdr, &tmppos, NULL, 0); read_qstring(hdr, &tmppos, NULL, 0); tmppos += 4; int16_t SignalType = lei16p(hdr->AS.Header+tmppos); tmppos += 2; int16_t ChannelEnabled = lei16p(hdr->AS.Header+tmppos); tmppos += 24; NumChans0 += (ChannelEnabled > 0); NumChans1 += (ChannelEnabled > 0) * (1 + (SignalType==0) * (flag_DC_amplifier_data_saved+1)); } hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, (1+NS+NumChans1) * sizeof(CHANNEL_TYPE)); for (unsigned k = 0; k < NumberOfChannelsInSignalGroup; k++) { char NativeChannelName[MAX_LENGTH_LABEL+1]; char CustomChannelName[MAX_LENGTH_LABEL+1]; read_qstring(hdr, &pos, NativeChannelName, MAX_LENGTH_LABEL); read_qstring(hdr, &pos, CustomChannelName, MAX_LENGTH_LABEL); pos += 4; int16_t SignalType = lei16p(hdr->AS.Header+pos); pos += 2; int16_t ChannelEnabled = leu16p(hdr->AS.Header+pos)>0; pos += 2; int16_t ChipChannel = lei16p(hdr->AS.Header+pos); pos += 2; int16_t CommandStream = lei16p(hdr->AS.Header+pos); pos += 2; int16_t BoardStream = lei16p(hdr->AS.Header+pos); pos += 2; int16_t SpikeScopeVoltageTriggerMode = lei16p(hdr->AS.Header+pos); pos += 2; int16_t SpikeScopeVoltageThreshold = lei16p(hdr->AS.Header+pos); pos += 2; int16_t SpikeScopeDigitalTriggerChannel = lei16p(hdr->AS.Header+pos); pos += 2; int16_t SpikeScopeDigitalTriggerEdgePolarity = lei16p(hdr->AS.Header+pos); pos += 2; float ElectrodeImpedanceMagnitude = lef32p(hdr->AS.Header+pos); pos += 4; float ElectrodeImpedancePhase = lef32p(hdr->AS.Header+pos); pos += 4; if (ChannelEnabled) { int nn = 1 + (SignalType==0) * (1 + flag_DC_amplifier_data_saved); char *ChannelName = NULL; NS++; // first channel is Time channel for (int k2=0; k2 < nn; k2++) { // k2>0 takes care of StimDatea and DCamp channels CHANNEL_TYPE *hc = hdr->CHANNEL + NS + NumChans0*k2; strcpy(hc->Label, NativeChannelName); strncat(hc->Label, ":", MAX_LENGTH_LABEL-strlen(hc->Label)); strncat(hc->Label, CustomChannelName, MAX_LENGTH_LABEL-strlen(hc->Label)); #ifdef MAX_LENGTH_PHYSDIM strcpy(hc->PhysDim,"?"); #endif hc->OnOff = 1; hc->GDFTYP = 4; // uint16 hc->bi = bi + hdr->SPR * NumChans0 * k2 * 2; hc->bi8 = bi << 3; hc->LeadIdCode = 0; hc->DigMin = 0.0; hc->DigMax = ldexp(1,16)-1; hc->PhysDimCode = 0; // [?] default hc->Cal = 1; // default hc->Off = 0; // default hc->SPR = hdr->SPR; // default switch (SignalType) { case 0: // RHS2000 amplifier channel if (k2==0) { ChannelName = hc->Label; hc->Cal = 0.195; hc->Off = -32768 * hc->Cal; hc->PhysDimCode = 4275; // [uV] } else if ((k2+1)==nn) { // Stimulation Data sprintf(hc->Label,"Stim %s",ChannelName); hc->PhysDimCode = 4160; // [A] hc->Cal = StimStepSize; hc->Off = 0; /* NOTE: reading StimData disabled - this is not supported yet. Issues are decoding and scaling of data (bit9-16) */ hc->OnOff = 0; } else { sprintf(hc->Label,"DC_AmpData %s",ChannelName); hc->Cal = 19.23; hc->Off = -512 * hc->Cal; hc->PhysDimCode = 4274; // [mV] } break; /* case 2: // supply voltage channel hc->SPR = 1; hc->Cal = 0.0000748; hc->Off = 0; hc->PhysDimCode = 4256; // [V] break */ case 3: // Analog input channel case 4: // Analog output channel hc->PhysDimCode = 4256; // [V] hc->Cal = 0.0003125; hc->Off = -32768 * hc->Cal; break; case 5: // Digital Input channel case 6: // Digital Output channel hc->PhysDimCode = 0; // [1] break; default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format Intan RHS2000 - not conformant to specification"); } hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->bufptr = NULL; hc->TOffset = 0; hc->LowPass = LowPass; hc->HighPass = HighPass; hc->Notch = Notch; hc->XYZ[0] = NAN; hc->XYZ[1] = NAN; hc->XYZ[2] = NAN; if ( (hc->PhysDimCode & 0xffe0) == 4256) // [V] hc->Impedance = ElectrodeImpedanceMagnitude; } bi += hdr->SPR * 2; } // if (ChannelEnabled) } // take care of StimData Channels and AmpDC channels bi += (NumChans1 - NumChans0) * hdr->SPR * 2; NS += NumChans1 - NumChans0; } } { // channel 0 - time channel CHANNEL_TYPE *hc = hdr->CHANNEL+0; hc->OnOff = 2; strcpy(hc->Label, "time"); strcpy(hc->Transducer, ""); #ifdef MAX_LENGTH_PHYSDIM strcpy(hc->PhysDim,"s"); #endif hc->bi = 0; hc->bufptr = NULL; hc->OnOff = 2; // time channel hc->SPR = hdr->SPR; hc->GDFTYP = 6; // uint32 hc->bi = 0; hc->bi8 = hc->bi << 3; hc->LeadIdCode = 0; hc->DigMin = 0.0; hc->DigMax = ldexp(1,32)-1; hc->Off = 0.0; hc->Cal = 1.0/hdr->SampleRate; hc->PhysDimCode = 2176; // [s] hc->PhysMin = 0; hc->PhysMax = hc->DigMax*hc->Cal; hc->bufptr = NULL; hc->TOffset = 0; hc->LowPass = 0; hc->HighPass = INFINITY; hc->Notch = 0; hc->XYZ[0] = NAN; hc->XYZ[1] = NAN; hc->XYZ[2] = NAN; hc->Impedance = NAN; } hdr->HeadLen = pos; hdr->NRec = -1; hdr->NS = NS+1; hdr->AS.bpb = bi; ifseek(hdr, hdr->HeadLen, SEEK_SET); struct stat FileBuf; if (stat(hdr->FileName,&FileBuf)==0) hdr->FILE.size = FileBuf.st_size; hdr->NRec = (hdr->FILE.size - hdr->HeadLen) / hdr->AS.bpb; return 0; } /* RHD2000 Data File Formats - Intan Tech http://www.intantech.com/files/Intan_RHD2000_data_file_formats.pdf */ int sopen_rhd2000_read(HDRTYPE* hdr) { uint16_t major = leu16p(hdr->AS.Header+4); float minor = leu16p(hdr->AS.Header+6); minor *= (minor < 10) ? 0.1 : 0.01; hdr->VERSION = major + minor; hdr->NS = 1; hdr->SampleRate = lef32p(hdr->AS.Header+8); float HighPass = ( leu16p(hdr->AS.Header+12) ? lef32p(hdr->AS.Header+14) : 0.0 ); HighPass = max( HighPass, lef32p(hdr->AS.Header+18) ); float LowPass = lef32p(hdr->AS.Header+22); const int ListNotch[] = {0,50,60}; uint16_t tmp = leu16p(hdr->AS.Header+38); if (tmp>2) tmp=0; float Notch = ListNotch[tmp]; float fZ_desired = lef32p(hdr->AS.Header+40); // desired impedance test frequency float fZ_actual = lef32p(hdr->AS.Header+44); // actual impedance test frequency size_t pos = 48; char tmpstr[101]; read_qstring(hdr, &pos, tmpstr, 100); // note1 read_qstring(hdr, &pos, tmpstr, 100); // note2 read_qstring(hdr, &pos, tmpstr, 100); // note3 uint16_t numberTemperatureSensors = 0; if (hdr->Version >= 1.1) { numberTemperatureSensors = leu16p(hdr->AS.Header+pos); pos += 2; } int BoardMode = 0; if (hdr->Version >= 1.3) { BoardMode = leu16p(hdr->AS.Header+pos); pos += 2; } char referenceChannelName[101]; referenceChannelName[0]=0; if (hdr->Version >= 2.0) { read_qstring(hdr, &pos, referenceChannelName, 100); } uint16_t numberOfSignalGroups = leu16p(hdr->AS.Header+pos); pos += 2; hdr->NS = 1+numberTemperatureSensors; // time channel + temparature channels hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); CHANNEL_TYPE *hc = hdr->CHANNEL; strcpy(hc->Label,"Time"); hc->Transducer[0] = 0; hc->OnOff = 2; hc->bi = 0; hc->GDFTYP = 5; //int32_t hc->DigMin = -ldexp(1,31); hc->DigMax = ldexp(1,31) - 1; hdr->SPR = (major==1) ? 60 : 128; hc->SPR = hdr->SPR; size_t bi = (0+4)*hdr->SPR; for (uint16_t k = 0; kAS.Header+pos); pos += 2; uint16_t numberChannelsInGroup = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t numberAmplifierChannels = leu16p(hdr->AS.Header+pos); pos += 2; if (enabledGroup && (numberChannelsInGroup > 0) ) { hdr->CHANNEL = realloc(hdr->CHANNEL, ((size_t)hdr->NS + (size_t)numberChannelsInGroup) * sizeof(CHANNEL_TYPE)); int ns = 0; uint32_t chan; for (chan=0; chan < numberChannelsInGroup; chan++) { char NativeChannelName[MAX_LENGTH_LABEL+1]; char CustomChannelName[MAX_LENGTH_LABEL+1]; read_qstring(hdr, &pos, NativeChannelName, MAX_LENGTH_LABEL); read_qstring(hdr, &pos, CustomChannelName, MAX_LENGTH_LABEL); uint16_t nativeOrder = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t customOrder = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t signalType = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t channelEnabled = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t chipChannel = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t boardStream = leu16p(hdr->AS.Header+pos); pos += 2; // Spike Scope uint16_t triggerMode = leu16p(hdr->AS.Header+pos); pos += 2; int16_t voltageThreshold = leu16p(hdr->AS.Header+pos); // uV pos += 2; uint16_t triggerChannel = leu16p(hdr->AS.Header+pos); pos += 2; uint16_t edgePolarity = leu16p(hdr->AS.Header+pos); pos += 2; float ImpedanceMagnitude = lef32p(hdr->AS.Header+pos); // Ohm pos += 4; float ImpedancePhase = lef32p(hdr->AS.Header+pos); // degree pos += 4; if (!(chipChannel<32) || !(signalType<6)) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format Intan RHD2000 - not conformant to specification"); return -1; } if (channelEnabled) { CHANNEL_TYPE *hc = hdr->CHANNEL + hdr->NS + ns; ns += channelEnabled > 0; // translate into biosig HDR channel structure hc->GDFTYP = 4; // uint16_t hc->PhysDimCode = 0; // [?] default hc->Cal = 1; // default hc->Off = 0; // default hc->SPR = hdr->SPR; // default strcpy(hc->Label, NativeChannelName); strncat(hc->Label, ":", MAX_LENGTH_LABEL - strlen(hc->Label)); strncat(hc->Label, CustomChannelName, MAX_LENGTH_LABEL - strlen(hc->Label)); hc->Transducer[0] = 0; #ifdef MAX_LENGTH_PHYSDIM strcpy(hc->PhysDim, "?"); #endif hc->OnOff = 1; hc->bi = bi; hc->bi8 = bi << 3; hc->LeadIdCode = 0; hc->DigMin = 0.0; hc->DigMax = ldexp(1,16)-1; switch (signalType) { case 0: // amplifier channel hc->Cal = 0.195; hc->Off = -32768*hc->Cal; hc->PhysDimCode = 4275; // [uV] break; case 1: // auxilary input channel hc->SPR = hc->SPR/4; hc->Cal = 0.0000374; hc->Off = -32768*hc->Cal; hc->PhysDimCode = 4256; // [V] break; case 2: // supply voltage channel hc->SPR = channelEnabled; hc->Cal = 0.0000748; hc->Off = 0; hc->PhysDimCode = 4256; // [V] break; case 0xffff: // Temperature Sensor channel hc->GDFTYP = 3; // int16 hc->SPR = 1; hc->Cal = 0.01; hc->Off = 0; hc->PhysDimCode = 6048; // [°C] break; case 3: // USB board ADC input channel hc->PhysDimCode = 4256; // [V] switch(BoardMode) { case 0: hc->Cal = 0.000050354; hc->Off = 0; break; case 1: hc->Cal = 0.00015259; hc->Off = -32768*hc->Cal; break; case 13: hc->Cal = 0.0003125; hc->Off = -32768*hc->Cal; break; } break; case 4: // USB board digital input channel ; case 5: // USB board digital output channel ; } bi += hc->SPR*2; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; if ( (hc->PhysDimCode & 0xffe0) == 4256) // [V] hc->Impedance = ImpedanceMagnitude; } // if (channelEnabled) } hdr->NS += ns; } } hdr->CHANNEL = realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); hdr->HeadLen = pos; hdr->NRec = -1; hdr->AS.bpb = bi; ifseek(hdr, hdr->HeadLen, SEEK_SET); struct stat FileBuf; if (stat(hdr->FileName,&FileBuf)==0) hdr->FILE.size = FileBuf.st_size; hdr->NRec = (hdr->FILE.size - hdr->HeadLen) / hdr->AS.bpb; return 0; } #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_matio.c0000664000175000017500000001114214752215315016016 /* Copyright (C) 2021 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #ifdef WITH_MATIO #include #endif #include "../biosig.h" int sopen_matlab(HDRTYPE* hdr) { #ifdef WITH_MATIO /* file hdr->FileName is already opened and hdr->HeadLen bytes are read These are available from hdr->AS.Header. ToDo: populate hdr sanity checks memory leaks */ ifclose(hdr); //size_t count = hdr->HeadLen; // TODO: identify which type/origin of MATLAB fprintf(stdout, "Trying to read Matlab data using MATIO v%i.%i.%i\n", MATIO_MAJOR_VERSION, MATIO_MINOR_VERSION, MATIO_RELEASE_LEVEL); mat_t *matfile = Mat_Open(hdr->FileName, MAT_ACC_RDONLY); matvar_t *EEG=NULL, *pnts=NULL, *nbchan=NULL, *trials=NULL, *srate=NULL, *data=NULL, *chanlocs=NULL, *event=NULL; if (matfile != NULL) { EEG = Mat_VarRead(matfile, "EEG" ); if (EEG != NULL) { Mat_VarReadDataAll(matfile, EEG ); pnts = Mat_VarGetStructField(EEG, "pnts", MAT_BY_NAME, 0); nbchan = Mat_VarGetStructField(EEG, "nbchan", MAT_BY_NAME, 0); trials = Mat_VarGetStructField(EEG, "trials", MAT_BY_NAME, 0); srate = Mat_VarGetStructField(EEG, "srate", MAT_BY_NAME, 0); data = Mat_VarGetStructField(EEG, "data", MAT_BY_NAME, 0); chanlocs = Mat_VarGetStructField(EEG, "chanlocs", MAT_BY_NAME, 0); event = Mat_VarGetStructField(EEG, "event", MAT_BY_NAME, 0); hdr->NS = *(double*)(nbchan->data); hdr->SPR = *(double*)(pnts->data); hdr->NRec= *(double*)(trials->data); hdr->SampleRate = *(double*)(srate->data); /* TODO CB hdr->NRec = ; hdr->SPR = ; hdr->T0 = 0; // Unknown; */ uint16_t gdftyp = 16; // 16: float; 17: double hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); size_t k; for (k=0; kNS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; sprintf(hc->Label,"#%2d",k+1); hc->SPR = hdr->SPR; /* TODO CB hc->GDFTYP = gdftyp; hc->Transducer[0] = '\0'; hc->LowPass = ; hc->HighPass = ; hc->Notch = ; // unknown hc->PhysMax = ; hc->DigMax = ; hc->PhysMin = ; hc->DigMin = ; hc->Cal = 1.0; hc->Off = 0.0; hc->OnOff = 1; hc->PhysDimCode = 4275; // uV hc->LeadIdCode = 0; hc->bi = k*GDFTYP_BITS[gdftyp]>>3; // TODO AS */ } size_t sz = hdr->NS*hdr->SPR*hdr->NRec*GDFTYP_BITS[gdftyp]>>3; hdr->AS.rawdata = realloc(hdr->AS.rawdata, sz); /* TODO CB memcpy(hdr->AS.rawdata,...,sz); */ hdr->EVENT.N = 0; // TODO CB hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, hdr->EVENT.N*sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, hdr->EVENT.N*sizeof(*hdr->EVENT.TYP)); hdr->EVENT.DUR = (uint32_t*) realloc(hdr->EVENT.DUR, hdr->EVENT.N*sizeof(*hdr->EVENT.DUR)); hdr->EVENT.CHN = (uint16_t*) realloc(hdr->EVENT.CHN, hdr->EVENT.N*sizeof(*hdr->EVENT.CHN)); for (k=0; kEVENT.N; k++) { /* TODO CB hdr->EVENT.TYP[k] = FreeTextEvent(hdr, k, annotation) hdr->EVENT.POS[k] = hdr->EVENT.CHN[k] = 0; hdr->EVENT.DUR[k] = 0; */ } hdr->AS.bpb = hdr->NS*2; hdr->FLAG.OVERFLOWDETECTION = 0; // BKR does not support automated overflow and saturation detection Mat_VarPrint(pnts, 1); Mat_VarPrint(nbchan, 1); Mat_VarPrint(trials, 1); Mat_VarPrint(srate, 1); //Mat_VarPrint(data, 1); //Mat_VarPrint(chanlocs, 1); //Mat_VarPrint(event, 1); Mat_VarFree(EEG); } Mat_Close(matfile); } biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error reading MATLAB file"); return(-1); #else // WITH_MATIO biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "SOPEN(MATIO): - matlab format not supported - libbiosig need to be recompiled with libmatio support."); ifclose(hdr); return(-1); #endif // WITH_MATIO } stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_abf_read.c0000664000175000017500000014310014752215315016430 /* Copyright (C) 2012-2019,2021 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "../biosig.h" #define ABFLONG int32_t #include "axon_structs.h" // ABF2 #include "abfheadr.h" // ABF1 #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) /****************************************************************************** read ATF file ******************************************************************************/ EXTERN_C void sopen_atf_read(HDRTYPE* hdr) { ifseek(hdr, 0, SEEK_SET); size_t ll = 0; char *line = NULL; ssize_t nc; typeof (hdr->NS) k; // first line - skip: contains "ATF\t1.0" or alike nc = getline(&line, &ll, hdr->FILE.FID); // 2nd line: number of rows and colums nc = getline(&line, &ll, hdr->FILE.FID); char *str = line; long numHdrLines = strtoul(str,&str,10); // number of additional header lines (?) - not used hdr->SPR = 1; hdr->NRec = 1; long numTraces = strtoul(str,&str,10); hdr->NS = 0; // 3rd line: trace labels, while (strncmp(line, "\"Time (", 7)) { // skip all (numHdrLines?) header lines nc = getline(&line, &ll, hdr->FILE.FID); if (VERBOSE_LEVEL>7) fprintf(stdout,"ATF line <%s>\n",line); } /* obtain hdr->NS from the number of equal labels. This will distinguish between ATF files with single channel and multiple sections and and ATF files with single section and multiple channels */ char**Label = malloc(numTraces*sizeof(void*)); size_t *traceList = (size_t*) malloc((numTraces-1)*sizeof(size_t)); size_t *chanList = (size_t*) malloc((numTraces-1)*sizeof(size_t)); char *str0 = strtok(line, "\t"); char *str1 = str0; size_t lenLabel = strcspn(str0,"("); char *tmpptr = NULL; char *timeunit = strchr(str0,'('); *timeunit=0; timeunit++; tmpptr=strchr(timeunit,')'); *tmpptr=0; hdr->SampleRate = 1.0 / PhysDimScale(PhysDimCode(timeunit)); k = 0; long K2 = 1; long k2 = 0; for (k2 = 0; k2 < numTraces-1; k2++) { k++; str0 = strtok(NULL, "\t"); Label[k2] = str0; char *p1 = NULL; long ll=0; if (!strncmp(str0, "\"Section", 8)) { p1 = strchr(str0,'['); ll = strtol(p1+1, &tmpptr, 10); } else if (!strncmp(str0, "\"Trace #", 8)) { p1 = strchr(str0,'#'); ll = strtol(p1+1, &tmpptr, 10)-1; } else { biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, " (ATF) invalid/unsupported label name"); } if (ll<0) biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, " (ATF) invalid trace number"); traceList[k2] = ll; if (!strncmp(str1, str0, lenLabel)) { if (k > hdr->NS) { K2 = k - hdr->NS + 1; hdr->NS = k; } } else { k = 0; str1 = str0; lenLabel = strcspn(str0,"("); } chanList[k2] = k; // zero-based indexing } hdr->NS = K2; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); hdr->AS.bpb = 0; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; //init_channel(hc); hc->GDFTYP = 17; // float64 hc->PhysMin = -1e9; hc->PhysMax = +1e9; hc->DigMin = -1e9; hc->DigMax = +1e9; hc->Cal = 1.0; hc->Off = 0.0; hc->OnOff = 1; hc->LeadIdCode = 0; hc->Transducer[0] = '\0'; hc->PhysDimCode = 0; #ifdef MAX_LENGTH_PHYSDIM hc->PhysDim[0] = '?'; #endif hc->TOffset = 0.0; hc->HighPass = NAN; hc->LowPass = NAN; hc->Notch = NAN; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; hc->Impedance = NAN; hc->bufptr = NULL; hc->SPR = 1; hc->bi8 = k * GDFTYP_BITS[hc->GDFTYP]; hc->bi = hc->bi8 / 8; hdr->AS.bpb += GDFTYP_BITS[hc->GDFTYP]/8; // split string into label and unit "label (unit)"; char *label = strtok(Label[K2+k], "(\""); char *unit = strtok(NULL, ")\""); if (label != NULL) strncpy(hc->Label, label, MAX_LENGTH_LABEL+1); if (unit != NULL) { hc->PhysDimCode = PhysDimCode(unit); #ifdef MAX_LENGTH_PHYSDIM strncpy(hc->PhysDim, unit, MAX_LENGTH_PHYSDIM+1); #endif } } hdr->HeadLen = iftell(hdr); /*********************************************************************** read data block into memory ***********************************************************************/ size_t ln = 0; size_t numLines=0; double t1; while (~ifeof(hdr)) { ssize_t nc = getline(&line, &ll, hdr->FILE.FID); if (nc < 0) break; if (numLines <= (ln+1) ) { numLines = max(1024, ln*2); hdr->AS.rawdata = realloc(hdr->AS.rawdata, numLines * (numTraces-1) * sizeof(double)); } char *str = NULL; double val = strtod(line, &str); if (ln==0) t1 = val; if (ln==1) hdr->SampleRate /= (val-t1); for (size_t nc = 0; nc < numTraces-1; nc++) { val = strtod(str, &str); *(double*)(hdr->AS.rawdata + sizeof(double) * (ln * (numTraces-1) + nc)) = val; } ln++; } free(line); ifclose(hdr); hdr->SPR = ln; hdr->NRec = (numTraces-1) / hdr->NS; /* set up event table */ if (hdr->NRec > 1) { reallocEventTable(hdr, hdr->NRec - 1); hdr->EVENT.N = hdr->NRec - 1; hdr->EVENT.SampleRate = hdr->SampleRate; for (size_t k=0; k < hdr->EVENT.N ; k++) { hdr->EVENT.TYP[k] = 0x7ffe; hdr->EVENT.POS[k] = (k+1)*hdr->SPR; } if (hdr->EVENT.DUR!=NULL && hdr->EVENT.CHN!=NULL) { for (size_t k=0; k < hdr->EVENT.N ; k++) { hdr->EVENT.DUR[k]=0; // duration hdr->EVENT.CHN[k]=0; // all channels } } } /* reshape data */ double *data = malloc(hdr->NS * hdr->NRec * hdr->SPR * sizeof(double)); for (size_t nr = 0; nr < hdr->SPR; nr++) for (size_t nc = 0; nc < (numTraces-1); nc++) { double val = *(double*)(hdr->AS.rawdata + sizeof(double) * (nr * (numTraces-1) + nc)); size_t idx = traceList[nc] * hdr->SPR + chanList[nc]*hdr->SPR*hdr->NRec + nr; data[idx] = val; } free(hdr->AS.rawdata); hdr->AS.rawdata = (void*)data; hdr->NRec *= hdr->SPR; hdr->SPR = 1; free(Label); free(traceList); free(chanList); hdr->FILE.POS = 0; hdr->AS.first = 0; hdr->AS.length = hdr->NRec; } EXTERN_C void sopen_abf_read(HDRTYPE* hdr) { /* this function will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ if (VERBOSE_LEVEL>7) fprintf(stdout,"sopen_abf_read 101\n"); if (VERBOSE_LEVEL>7) fprintf(stderr,"%s (line %i) %"PRIiPTR" %i %i %"PRIiPTR"\n",__FILE__,__LINE__, sizeof(struct ABFFileHeader),ABF_OLDHEADERSIZE, ABF_HEADERSIZE, offsetof(struct ABFFileHeader, lHeaderSize)); if (VERBOSE_LEVEL>7) fprintf(stderr,"%s (line %i) %i %"PRIiPTR" %i\n",__FILE__,__LINE__, ABF_BLOCKSIZE, offsetof(struct ABFFileHeader, lDataSectionPtr), ABF_BLOCKSIZE*lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDataSectionPtr)) ); size_t count = hdr->HeadLen; hdr->VERSION = lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fFileVersionNumber)); hdr->HeadLen = ABF_BLOCKSIZE * lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDataSectionPtr)); if (count < hdr->HeadLen) { hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, hdr->HeadLen); count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); } if ( count < (hdr->VERSION < 1.6 ? ABF_OLDHEADERSIZE : ABF_HEADERSIZE) || count < hdr->HeadLen ) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, "Reading ABF Header block failed"); return; } hdr->HeadLen = count; { struct tm t; uint32_t u = leu32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lFileStartDate)); t.tm_year = u / 10000 - 1900; t.tm_mon = (u % 10000)/100 - 1; t.tm_mday = (u % 100); u = leu32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lFileStartTime)); t.tm_hour = u / 3600; t.tm_min = (u % 3600)/60; t.tm_sec = (u % 60); //u = leu16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nFileStartMillisecs)); hdr->T0 = tm_time2gdf_time(&t); } uint16_t gdftyp = 3; switch (lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDataFormat))) { case 0: gdftyp = 3; break; case 1: gdftyp = 16; break; default: biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "ABF datatype/gdftyp unknown/unsupported (neither int16 nor float32)"); break; } if (VERBOSE_LEVEL>7) fprintf(stderr,"%s (line %i)\n",__FILE__,__LINE__); size_t slen; slen = min(MAX_LENGTH_MANUF, sizeof(((struct ABFFileHeader*)(hdr->AS.Header))->sCreatorInfo)); slen = min(MAX_LENGTH_MANUF, ABF_CREATORINFOLEN); strncpy(hdr->ID.Manufacturer._field, (char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sCreatorInfo), slen); hdr->ID.Manufacturer._field[slen] = 0; hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field; if (hdr->Version > 1.5) { slen = min(MAX_LENGTH_RID, sizeof(((struct ABFFileHeader*)(hdr->AS.Header))->sFileComment)); strncpy(hdr->ID.Recording,(char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sFileComment), slen); hdr->ID.Recording[slen] = 0; } if (VERBOSE_LEVEL>7) { fprintf(stdout,"sCreatorInfo:\t%s\n",hdr->AS.Header + offsetof(struct ABFFileHeader, sCreatorInfo)); fprintf(stdout,"_sFileComment:\t%s\n",hdr->AS.Header + offsetof(struct ABFFileHeader, _sFileComment)); if (hdr->Version > 1.5) fprintf(stdout,"sFileComment:\t%s\n",hdr->AS.Header + offsetof(struct ABFFileHeader, sFileComment)); fprintf(stdout,"\nlHeaderSize:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lHeaderSize))); fprintf(stdout,"lTagSectionPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lTagSectionPtr))); fprintf(stdout,"lNumTagEntries:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumTagEntries))); fprintf(stdout,"lVoiceTagPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lVoiceTagPtr))); fprintf(stdout,"lVoiceTagEntries:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lVoiceTagEntries))); fprintf(stdout,"lSynchArrayPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lSynchArrayPtr))); fprintf(stdout,"lSynchArraySize:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lSynchArraySize))); fprintf(stdout,"\nlDataSectionPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDataSectionPtr))); fprintf(stdout,"lScopeConfigPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lScopeConfigPtr))); fprintf(stdout,"lNumScopes:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumScopes))); fprintf(stdout,"_lDACFilePtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, _lDACFilePtr))); fprintf(stdout,"_lDACFileNumEpisodes:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, _lDACFileNumEpisodes))); fprintf(stdout,"lDeltaArrayPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDeltaArrayPtr))); fprintf(stdout,"lNumDeltas:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumDeltas))); fprintf(stdout,"nDataFormat:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDataFormat))); fprintf(stdout,"nSimultaneousScan:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nSimultaneousScan))); fprintf(stdout,"lStatisticsConfigPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lStatisticsConfigPtr))); fprintf(stdout,"lAnnotationSectionPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lAnnotationSectionPtr))); fprintf(stdout,"lNumAnnotations:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumAnnotations))); fprintf(stdout,"\nlNumSamplesPerEpisode:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumSamplesPerEpisode))); fprintf(stdout,"lPreTriggerSamples:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lPreTriggerSamples))); fprintf(stdout,"lEpisodesPerRun:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lEpisodesPerRun))); fprintf(stdout,"lActualAcqLength:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lActualAcqLength))); fprintf(stdout,"lActualEpisodes:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lActualEpisodes))); fprintf(stdout,"lRunsPerTrial:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lRunsPerTrial))); fprintf(stdout,"lNumberOfTrials:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumberOfTrials))); fprintf(stdout,"fADCRange:\t%g\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCRange))); fprintf(stdout,"fDACRange:\t%g\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fDACRange))); fprintf(stdout,"lADCResolution:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lADCResolution))); fprintf(stdout,"lDACResolution:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDACResolution))); fprintf(stdout,"\nchannel_count_acquired:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, channel_count_acquired))); fprintf(stdout,"nADCNumChannels:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCNumChannels))); fprintf(stdout,"fADCSampleInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSampleInterval))); fprintf(stdout,"nDigitalDACChannel:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalDACChannel))); fprintf(stdout,"nOperationMode:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nOperationMode))); fprintf(stdout,"nDigitalEnable:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalEnable))); fprintf(stdout,"\nfFileVersionNumber:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fFileVersionNumber))); fprintf(stdout,"fHeaderVersionNumber:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fHeaderVersionNumber))); fprintf(stdout,"fADCSampleInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSampleInterval))); fprintf(stdout,"fADCSecondSampleInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSecondSampleInterval))); fprintf(stdout,"fSynchTimeUnit:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSynchTimeUnit))); fprintf(stdout,"fSecondsPerRun:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSecondsPerRun))); fprintf(stdout,"fTriggerThreshold:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTriggerThreshold))); fprintf(stdout,"\nfScopeOutputInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fScopeOutputInterval))); fprintf(stdout,"fEpisodeStartToStart:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fEpisodeStartToStart))); fprintf(stdout,"fRunStartToStart:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fRunStartToStart))); fprintf(stdout,"fTrialStartToStart:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTrialStartToStart))); fprintf(stdout,"fStatisticsPeriod:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fStatisticsPeriod))); fprintf(stdout,"fADCRange:\t%g\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCRange))); fprintf(stdout,"fDACRange:\t%g\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTriggerThreshold))); fprintf(stdout,"fTriggerThreshold:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fDACRange))); fprintf(stdout,"dFileDuration:\t%g\n",lef64p(hdr->AS.Header + offsetof(struct ABFFileHeader, dFileDuration))); fprintf(stdout,"fTriggerThreshold:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTriggerThreshold))); fprintf(stdout,"nExperimentType:\t%f\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nExperimentType))); } if (VERBOSE_LEVEL>7) fprintf(stdout,"sopen_abf_read 201\n"); if (VERBOSE_LEVEL>7) fprintf(stderr,"%s (line %i)\n",__FILE__,__LINE__); hdr->NS = lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCNumChannels)); if (lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalEnable))) hdr->NS += lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalDACChannel)); hdr->SampleRate = 1e6 / (hdr->NS * lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSampleInterval))); hdr->NRec = lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lActualAcqLength)) / lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCNumChannels)); hdr->SPR = 1; hdr->AS.bpb = hdr->NS*GDFTYP_BITS[gdftyp]/8; hdr->CHANNEL = realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); uint32_t k1=0,k; // ABF is 32 bits only, no need for more for (k=0; k < ABF_ADCCOUNT + ABF_DACCOUNT; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k1; if ((k < ABF_ADCCOUNT) && (lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCSamplingSeq) + 2 * k) >= 0)) { hc->OnOff = 1; hc->bufptr = NULL; hc->LeadIdCode = 0; int ll = min(ABF_ADCNAMELEN, MAX_LENGTH_LABEL); strncpy(hc->Label, (char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sADCChannelName) + k*ABF_ADCNAMELEN, ll); while (ll > 0 && isspace(hc->Label[--ll])); hc->Label[ll+1] = 0; char units[ABF_ADCUNITLEN+1]; { memcpy(units, (char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sADCUnits) + k*ABF_ADCUNITLEN, ABF_ADCUNITLEN); units[ABF_ADCUNITLEN] = 0; int p=ABF_ADCUNITLEN; while ( (0PhysDimCode = PhysDimCode(units); } hc->Transducer[0] = '\0'; hc->LowPass = lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalLowpassFilter) + 4 * k); hc->HighPass = lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalHighpassFilter) + 4 * k); hc->Notch = NAN; hc->TOffset = NAN; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; hc->GDFTYP = gdftyp; hc->SPR = hdr->SPR; hc->bi = k1*GDFTYP_BITS[gdftyp]/8; hc->bi8 = k1*GDFTYP_BITS[gdftyp]; double PhysMax = lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCRange)); double DigMax = (double)lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lADCResolution)); double fTotalScaleFactor = lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fInstrumentScaleFactor) + 4 * k) * lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCProgrammableGain) + 4 * k); hc->Off = -lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fInstrumentOffset) + 4 * k); if (lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nSignalType) + 2 * k) != 0) { hc->Off -= lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fInstrumentOffset) + 4 * k); fTotalScaleFactor *= lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalGain) + 4 * k); } if (hdr->Version > 1.5 && lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nTelegraphEnable) + 2 * k) != 0) { fTotalScaleFactor *= lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTelegraphAdditGain) + 4 * k); } hc->Cal = PhysMax / (fTotalScaleFactor * DigMax); hc->DigMax = DigMax-1.0; hc->DigMin = -hc->DigMax; hc->PhysMax = hc->DigMax * hc->Cal; hc->PhysMin = hc->DigMin * hc->Cal; if (VERBOSE_LEVEL>7) { fprintf(stdout,"==== CHANNEL %i [%s] ====\n",k,units); fprintf(stdout,"nSignalType:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nSignalType) + 2 * k)); fprintf(stdout,"nADCPtoLChannelMap:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCPtoLChannelMap) + 2 * k)); fprintf(stdout,"nADCSamplingSeq:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCSamplingSeq) + 2 * k)); fprintf(stdout,"fADCProgrammableGain:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCProgrammableGain) + 4 * k)); fprintf(stdout,"fADCRange:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCRange) + 4 * k)); fprintf(stdout,"fADCDisplayAmplification:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCDisplayAmplification) + 4 * k)); fprintf(stdout,"fADCDisplayOffset:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCDisplayOffset) + 4 * k)); fprintf(stdout,"fInstrumentScaleFactor:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fInstrumentScaleFactor) + 4 * k)); fprintf(stdout,"fInstrumentOffset:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fInstrumentOffset) + 4 * k)); fprintf(stdout,"fSignalGain:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalGain) + 4 * k)); fprintf(stdout,"fSignalOffset:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalOffset) + 4 * k)); fprintf(stdout,"fSignalLowpassFilter:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalLowpassFilter) + 4 * k)); fprintf(stdout,"fSignalHighpassFilter:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalHighpassFilter) + 4 * k)); if (hdr->Version > 1.5) fprintf(stdout,"fTelegraphAdditGain:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTelegraphAdditGain) + 4 * k)); } k1++; } else if (k < ABF_ADCCOUNT) { // do not increase k1; if (VERBOSE_LEVEL>7) { fprintf(stdout,"==== CHANNEL %i ====\n",k); fprintf(stdout,"nADCPtoLChannelMap:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCPtoLChannelMap) + 2 * k)); fprintf(stdout,"nADCSamplingSeq:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCSamplingSeq) + 2 * k)); fprintf(stdout,"fADCProgrammableGain:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCProgrammableGain) + 4 * k)); fprintf(stdout,"fADCDisplayAmplification:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCDisplayAmplification) + 4 * k)); fprintf(stdout,"fADCDisplayOffset:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCDisplayOffset) + 4 * k)); fprintf(stdout,"fInstrumentScaleFactor:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fInstrumentScaleFactor) + 4 * k)); fprintf(stdout,"fInstrumentOffset:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fInstrumentOffset) + 4 * k)); fprintf(stdout,"fSignalGain:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalGain) + 4 * k)); fprintf(stdout,"fSignalOffset:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalOffset) + 4 * k)); fprintf(stdout,"fSignalLowpassFilter:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalLowpassFilter) + 4 * k)); fprintf(stdout,"fSignalHighpassFilter:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalHighpassFilter) + 4 * k)); } } else if ( (k1 < ABF_ADCCOUNT+ABF_DACCOUNT) && (k < hdr->NS) ) { hc->OnOff = 1; hc->bufptr = NULL; hc->LeadIdCode = 0; strncpy(hc->Label, (char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sDACChannelName) + (k-ABF_ADCCOUNT)*ABF_DACNAMELEN, min(ABF_DACNAMELEN,MAX_LENGTH_LABEL)); hc->Label[ABF_DACNAMELEN] = 0; char units[ABF_DACUNITLEN+1]; { memcpy(units, hdr->AS.Header + offsetof(struct ABFFileHeader, sDACChannelUnits) + (k-ABF_ADCCOUNT)*ABF_DACUNITLEN, ABF_DACUNITLEN); units[ABF_DACUNITLEN] = 0; int p=ABF_ADCUNITLEN; while ( (0PhysDimCode = PhysDimCode(units); } hc->Transducer[0] = '\0'; hc->HighPass = NAN; hc->LowPass = NAN; hc->Notch = NAN; hc->TOffset = NAN; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; hc->GDFTYP = gdftyp; hc->SPR = hdr->SPR; hc->bi = k1*GDFTYP_BITS[gdftyp]/8; hc->bi8 = k1*GDFTYP_BITS[gdftyp]; double PhysMax = lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fDACRange)); double DigMax = (double)lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDACResolution)); hc->Cal = PhysMax/DigMax; hc->Off = 0.0; hc->PhysMax = PhysMax * (DigMax-1.0) / DigMax; hc->PhysMin = -hc->PhysMax; hc->DigMax = DigMax-1; hc->DigMin = -hc->DigMax; if (VERBOSE_LEVEL>7) { fprintf(stdout,"==== CHANNEL %i [%s] ====\nfDACScaleFactor:\t%f\n",k,units, lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fDACScaleFactor) + 4 * (k-ABF_ADCCOUNT))); fprintf(stdout,"fDACHoldingLevel:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fDACHoldingLevel) + 4 * (k-ABF_ADCCOUNT))); } k1++; } } /* ===== EVENT TABLE ===== */ uint32_t n1,n2; n1 = lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lActualEpisodes)) - 1; n2 = lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumTagEntries)); hdr->EVENT.N = n1+n2; /* add breaks between sweeps */ size_t spr = lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumSamplesPerEpisode))/hdr->NS; hdr->EVENT.SampleRate = hdr->SampleRate; hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, hdr->EVENT.N * sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, hdr->EVENT.N * sizeof(*hdr->EVENT.TYP)); for (k=0; k < n1; k++) { hdr->EVENT.TYP[k] = 0x7ffe; hdr->EVENT.POS[k] = (k+1)*spr; } if (hdr->EVENT.DUR!=NULL && hdr->EVENT.CHN!=NULL) { for (k=0; k < n1; k++) { hdr->EVENT.DUR[k]=0; // duration hdr->EVENT.CHN[k]=0; // all channels } } /* add tags */ hdr->AS.auxBUF = realloc(hdr->AS.auxBUF, n2 * sizeof(struct ABFTag)); ifseek(hdr, lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lTagSectionPtr))*ABF_BLOCKSIZE, SEEK_SET); count = ifread(hdr->AS.auxBUF, sizeof(struct ABFTag), n2, hdr); if (count>255) { count = 255; fprintf(stderr,"Warning ABF: more than 255 tags cannot be read"); } hdr->EVENT.N = n1+count; for (k=0; k < count; k++) { uint8_t *abftag = hdr->AS.auxBUF + k * sizeof(struct ABFTag); hdr->EVENT.POS[k+n1] = leu32p(abftag)/hdr->NS; abftag[ABF_TAGCOMMENTLEN+4-1]=0; FreeTextEvent(hdr, k+n1, (char*)(abftag+4)); } // set HeadLen to begin of data block hdr->HeadLen = ABF_BLOCKSIZE * lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDataSectionPtr)); ifseek(hdr, hdr->HeadLen, SEEK_SET); } // end of sopen_abf_read size_t readABF2block(uint8_t *block, HDRTYPE *hdr, struct ABF_Section *S) { S->uBlockIndex = leu32p(block + offsetof(struct ABF_Section, uBlockIndex)); if (S->uBlockIndex==0) return 0; S->uBytes = leu32p(block + offsetof(struct ABF_Section, uBytes)); if (S->uBytes==0) return 0; S->llNumEntries = leu64p(block + offsetof(struct ABF_Section, llNumEntries)); hdr->AS.auxBUF = realloc(hdr->AS.auxBUF, S->llNumEntries*S->uBytes); ifseek(hdr, S->uBlockIndex*(size_t)512, SEEK_SET); return ifread(hdr->AS.auxBUF, 1, S->llNumEntries*S->uBytes, hdr); } EXTERN_C void sopen_abf2_read(HDRTYPE* hdr) { /* this function will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ if (VERBOSE_LEVEL>7) fprintf(stdout,"sopen_abf2_read 101\n"); if (hdr->HeadLen < 512) { hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, 512); hdr->HeadLen += ifread(hdr->AS.Header+hdr->HeadLen, 1, 512-hdr->HeadLen, hdr); } { struct tm t; uint32_t u = leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uFileStartDate)); t.tm_year = u / 10000 - 1900; t.tm_mon = (u % 10000)/100 - 1; t.tm_mday = (u % 100); u = leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uFileStartTimeMS))/1000; t.tm_hour = u / 3600; t.tm_min = (u % 3600)/60; t.tm_sec = (u % 60); //u = leu16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nFileStartMillisecs)); hdr->T0 = tm_time2gdf_time(&t); } hdr->SPR = 1; uint16_t gdftyp = 3; unsigned numSweeps = leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uActualEpisodes)); if (VERBOSE_LEVEL>7) { fprintf(stdout,"\nuFileInfoSize:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uFileInfoSize))); fprintf(stdout,"uActualEpisodes:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uActualEpisodes))); fprintf(stdout,"uFileStartDate:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uFileStartDate))); fprintf(stdout,"uFileStartTimeMS:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uFileStartTimeMS))); fprintf(stdout,"uStopwatchTime:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uStopwatchTime))); fprintf(stdout,"nFileType:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABF_FileInfo, nFileType))); fprintf(stdout,"nDataFormat:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABF_FileInfo, nDataFormat))); fprintf(stdout,"nSimultaneousScan:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABF_FileInfo, nSimultaneousScan))); fprintf(stdout,"nCRCEnable:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABF_FileInfo, nCRCEnable))); fprintf(stdout,"uFileCRC: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uFileCRC))); fprintf(stdout,"uCreatorVersion: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uCreatorVersion))); fprintf(stdout,"uCreatorNameIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uCreatorNameIndex))); fprintf(stdout,"uModifierVersion: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uModifierVersion))); fprintf(stdout,"uModifierNameIndex:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uModifierNameIndex))); fprintf(stdout,"uProtocolPathIndex:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, uProtocolPathIndex))); fprintf(stdout,"ProtocolSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ProtocolSection.uBlockIndex))); fprintf(stdout,"ProtocolSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ProtocolSection.uBytes))); fprintf(stdout,"ProtocolSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ProtocolSection.llNumEntries))); fprintf(stdout,"ADCSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCSection.uBlockIndex))); fprintf(stdout,"ADCSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCSection.uBytes))); fprintf(stdout,"ADCSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCSection.llNumEntries))); fprintf(stdout,"DACSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DACSection.uBlockIndex))); fprintf(stdout,"DACSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DACSection.uBytes))); fprintf(stdout,"DACSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DACSection.llNumEntries))); fprintf(stdout,"EpochSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochSection.uBlockIndex))); fprintf(stdout,"EpochSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochSection.uBytes))); fprintf(stdout,"EpochSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochSection.llNumEntries))); fprintf(stdout,"ADCPerDACSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCPerDACSection.uBlockIndex))); fprintf(stdout,"ADCPerDACSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCPerDACSection.uBytes))); fprintf(stdout,"ADCPerDACSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCPerDACSection.llNumEntries))); fprintf(stdout,"EpochPerDACSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochPerDACSection.uBlockIndex))); fprintf(stdout,"EpochPerDACSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochPerDACSection.uBytes))); fprintf(stdout,"EpochPerDACSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochPerDACSection.llNumEntries))); fprintf(stdout,"UserListSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, UserListSection.uBlockIndex))); fprintf(stdout,"UserListSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, UserListSection.uBytes))); fprintf(stdout,"UserListSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, UserListSection.llNumEntries))); fprintf(stdout,"StatsRegionSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsRegionSection.uBlockIndex))); fprintf(stdout,"StatsRegionSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsRegionSection.uBytes))); fprintf(stdout,"StatsRegionSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsRegionSection.llNumEntries))); fprintf(stdout,"MathSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, MathSection.uBlockIndex))); fprintf(stdout,"MathSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, MathSection.uBytes))); fprintf(stdout,"MathSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, MathSection.llNumEntries))); fprintf(stdout,"StringsSection.uBlockIndex:\t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StringsSection.uBlockIndex))); fprintf(stdout,"StringsSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StringsSection.uBytes))); fprintf(stdout,"StringsSection.llNumEntries:\t%i\n",(int)lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StringsSection.llNumEntries))); fprintf(stdout,"DataSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DataSection.uBlockIndex))); fprintf(stdout,"DataSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DataSection.uBytes))); fprintf(stdout,"DataSection.llNumEntries:\t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DataSection.llNumEntries))); fprintf(stdout,"TagSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, TagSection.uBlockIndex))); fprintf(stdout,"TagSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, TagSection.uBytes))); fprintf(stdout,"TagSection.llNumEntries: \t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, TagSection.llNumEntries))); fprintf(stdout,"ScopeSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ScopeSection.uBlockIndex))); fprintf(stdout,"ScopeSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ScopeSection.uBytes))); fprintf(stdout,"ScopeSection.llNumEntries:\t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, ScopeSection.llNumEntries))); fprintf(stdout,"DeltaSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DeltaSection.uBlockIndex))); fprintf(stdout,"DeltaSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DeltaSection.uBytes))); fprintf(stdout,"DeltaSection.llNumEntries:\t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DeltaSection.llNumEntries))); fprintf(stdout,"VoiceTagSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, VoiceTagSection.uBlockIndex))); fprintf(stdout,"VoiceTagSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, VoiceTagSection.uBytes))); fprintf(stdout,"VoiceTagSection.llNumEntries:\t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, VoiceTagSection.llNumEntries))); fprintf(stdout,"SynchArraySection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, SynchArraySection.uBlockIndex))); fprintf(stdout,"SynchArraySection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, SynchArraySection.uBytes))); fprintf(stdout,"SynchArraySection.llNumEntries:\t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, SynchArraySection.llNumEntries))); fprintf(stdout,"AnnotationSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, AnnotationSection.uBlockIndex))); fprintf(stdout,"AnnotationSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, AnnotationSection.uBytes))); fprintf(stdout,"AnnotationSection.llNumEntries:\t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, AnnotationSection.llNumEntries))); fprintf(stdout,"StatsSection.uBlockIndex: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsSection.uBlockIndex))); fprintf(stdout,"StatsSection.uBytes: \t%i\n",leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsSection.uBytes))); fprintf(stdout,"StatsSection.llNumEntries:\t%"PRIi64"\n",lei64p(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsSection.llNumEntries))); } switch(leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DataSection.uBytes))) { case 2: gdftyp=3; break; case 4: gdftyp=16; break; default: biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "ABF2 datatype/gdftyp unknown/unsupported (neither int16 nor float32)"); break; } struct ABF_Section S; readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, ProtocolSection), hdr, &S); // TODO: checking why it requires big-endian here float fADCRange = bef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fADCRange)); float fDACRange = bef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fDACRange)); int32_t lADCResolution = lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lADCResolution)); int32_t lDACResolution = lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lDACResolution)); hdr->SampleRate = 1e6 / lef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fADCSequenceInterval)); int16_t nOperationMode = lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nOperationMode)); switch (nOperationMode) { case 3: // Gap free break; case 1: // Variable-Length Event-Driven case 2: // Fixed-Length Event-Driven case 4: // High-Speed Oscilloscope Mode case 5: // Episodic Stimulation Mode fprintf(stdout,"Warning ABF2 v%4.2f: nOperationMode=%d is very experimental - double check the data you get.\n", hdr->VERSION, nOperationMode); break; default: biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "ABF2 nOperationMode unknown and unsupported"); break; } if (VERBOSE_LEVEL>7) { fprintf(stdout,"nOperationMode:\t%i\n", nOperationMode); fprintf(stdout,"fADCSequenceInterval:\t%g\n", lef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fADCSequenceInterval))); fprintf(stdout,"fSecondsPerRun:\t%g\n", lef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fSecondsPerRun))); fprintf(stdout,"fSecondsPerRun:\t%g\n", bef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fSecondsPerRun))); fprintf(stdout,"lNumSamplesPerEpisode:\t%i\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lNumSamplesPerEpisode))); fprintf(stdout,"lPreTriggerSamples:\t%i\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lPreTriggerSamples))); fprintf(stdout,"lEpisodesPerRun:\t%i\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lEpisodesPerRun))); fprintf(stdout,"lRunsPerTrial:\t%i\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lRunsPerTrial))); fprintf(stdout,"lNumberOfTrials:\t%i\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lNumberOfTrials))); fprintf(stdout,"nDigitalEnable:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitalEnable))); fprintf(stdout,"nActiveDACChannel:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nActiveDACChannel))); fprintf(stdout,"nDigitalHolding:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitalHolding))); fprintf(stdout,"nDigitalInterEpisode:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitalInterEpisode))); fprintf(stdout,"nDigitalDACChannel:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitalDACChannel))); fprintf(stdout,"nDigitizerADCs:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitizerADCs))); fprintf(stdout,"nDigitizerDACs:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitizerDACs))); fprintf(stdout,"nDigitizerTotalDigitalOuts:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitizerTotalDigitalOuts))); fprintf(stdout,"nDigitizerSynchDigitalOuts:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitizerSynchDigitalOuts))); fprintf(stdout,"nDigitizerType:\t%i\n", lei16p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, nDigitizerType))); fprintf(stdout,"fADCRange:\t(l)%g\n", lef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fADCRange))); fprintf(stdout,"fDACRange:\t(l)%g\n", lef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fDACRange))); fprintf(stdout,"fADCRange:\t(b)%g\n", bef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fADCRange))); fprintf(stdout,"fDACRange:\t(b)%g\n", bef32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, fDACRange))); fprintf(stdout,"lADCResolution:\t0x%08x\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lADCResolution))); fprintf(stdout,"lDACResolution:\t0x%08x\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lDACResolution))); fprintf(stdout,"lADCResolution:\t(l)%d\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lADCResolution))); fprintf(stdout,"lDACResolution:\t(l)%d\n", lei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lDACResolution))); fprintf(stdout,"lADCResolution:\t(b)%d\n", bei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lADCResolution))); fprintf(stdout,"lDACResolution:\t(b)%d\n", bei32p(hdr->AS.auxBUF + offsetof(struct ABF_ProtocolInfo, lDACResolution))); } readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCSection), hdr, &S); hdr->NS = S.llNumEntries; hdr->CHANNEL = realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); int k; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->bufptr = NULL; hc->LeadIdCode = 0; hc->OnOff = 1; hc->Transducer[0] = 0; hc->Label[0] = 0; hc->LowPass = lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fSignalLowpassFilter)); hc->HighPass = lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fSignalHighpassFilter)); hc->GDFTYP = gdftyp; hc->SPR = hdr->SPR; hc->bi = k*GDFTYP_BITS[gdftyp] / 8; strncpy(hc->Label, (char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sADCChannelName) + k*ABF_ADCNAMELEN, min(ABF_ADCNAMELEN,MAX_LENGTH_LABEL)); hc->Label[ABF_ADCNAMELEN] = 0; /* // TODO: where to find information about PhysDim and Label in ABF2 file ? Currently, this is hardcoded below char units[ABF_ADCUNITLEN+1]; { memcpy(units, (char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sADCUnits) + k*ABF_ADCUNITLEN, ABF_ADCUNITLEN); units[ABF_ADCUNITLEN] = 0; int p=ABF_ADCUNITLEN; while ( (0PhysDimCode = PhysDimCode(units); } */ hc->PhysDimCode = PhysDimCode("V"); hc->Cal = 0.001; hc->Off = 0.0; double PhysMax = fADCRange; double DigMax = lADCResolution; // https://swharden.com/pyabf/abf2-file-format/#reading-multi-byte-integers-from-bytestrings // https://support.moleculardevices.com/s/article/Convert-data-file-from-another-program-to-an-ABF-file-so-that-it-can-be-read-by-pCLAMP // https://github.com/yamad/libabf/blob/master/src/AxAbfFio32/abfheader.cpp -> GetADCtoUUFactors if (gdftyp==3) { double iCal = lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fInstrumentScaleFactor)); iCal *= lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fADCProgrammableGain)); if (lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nSignalType) + 2 * k) != 0) iCal *= lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSignalGain) + 4 * k); if (!lei16p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, nTelegraphEnable))) iCal *= lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fTelegraphAdditGain)); if (hc->Cal == 0.0) hc->Cal = 1.0; hc->Cal = fADCRange / (iCal * lADCResolution); hc->Off = lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fInstrumentOffset)); } // hc->Off = lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fInstrumentOffset)); hc->DigMax = lADCResolution - 1.0; hc->DigMin = -hc->DigMax; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; if (VERBOSE_LEVEL>7) { fprintf(stdout,"nADCNum:\t%i\n", lei16p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, nADCNum))); fprintf(stdout,"nADCSamplingSeq:\t%i\n", lei16p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, nADCSamplingSeq))); fprintf(stdout,"nADCPtoLChannelMap:\t%i\n", lei16p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, nADCPtoLChannelMap))); fprintf(stdout,"fADCProgrammableGain:\t%g\n", lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fADCProgrammableGain))); fprintf(stdout,"fInstrumentScaleFactor:\t%g\n", lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fInstrumentScaleFactor))); fprintf(stdout,"fInstrumentOffset:\t%g\n", lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fInstrumentOffset))); fprintf(stdout,"fSignalGain:\t%g\n", lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fSignalGain))); fprintf(stdout,"fSignalOffset:\t%g\n", lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fSignalOffset))); fprintf(stdout,"fSignalLowpassFilter:\t%g\n", lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fSignalLowpassFilter))); fprintf(stdout,"fSignalHighpassFilter:\t%g\n", lef32p(hdr->AS.auxBUF + S.uBytes*k + offsetof(struct ABF_ADCInfo, fSignalHighpassFilter))); } } readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, DACSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, ADCPerDACSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, EpochPerDACSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, UserListSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsRegionSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, MathSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, StringsSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, DataSection), hdr, &S); hdr->AS.rawdata = hdr->AS.auxBUF; hdr->AS.auxBUF = NULL; hdr->AS.first = 0; hdr->AS.length = S.llNumEntries; hdr->NRec = S.llNumEntries; hdr->AS.bpb = S.uBytes; readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, TagSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, ScopeSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, DeltaSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, VoiceTagSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, SynchArraySection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, AnnotationSection), hdr, &S); readABF2block(hdr->AS.Header + offsetof(struct ABF_FileInfo, StatsSection), hdr, &S); /* hdr->NS = lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCNumChannels)); if (lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalEnable))) hdr->NS += lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalDACChannel)); hdr->SampleRate = 1e6 / (hdr->NS * lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSampleInterval))); hdr->NRec = lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lActualAcqLength)) / lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCNumChannels)); hdr->SPR = 1; hdr->AS.bpb = hdr->NS*GDFTYP_BITS[gdftyp]/8; hdr->CHANNEL = realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); */ // beginning of data block hdr->HeadLen = leu32p(hdr->AS.Header + offsetof(struct ABF_FileInfo, DataSection.uBlockIndex)) * 512; /* set up event table */ if (numSweeps > 1) { reallocEventTable(hdr, numSweeps - 1); hdr->EVENT.N = numSweeps - 1; hdr->EVENT.SampleRate = hdr->SampleRate; for (size_t k=0; k < hdr->EVENT.N ; k++) { hdr->EVENT.TYP[k] = 0x7ffe; hdr->EVENT.POS[k] = (k+1)*((uint64_t)hdr->SPR * hdr->NRec) / numSweeps; } if (hdr->EVENT.DUR!=NULL && hdr->EVENT.CHN!=NULL) { for (size_t k=0; k < hdr->EVENT.N ; k++) { hdr->EVENT.DUR[k] = 0; // duration hdr->EVENT.CHN[k] = 0; // all channels } } } } stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_alpha_read.c0000664000175000017500000004040214752215315016766 /* $Id: sopen_alpha_read.c,v 1.2 2009-02-12 16:15:17 schloegl Exp $ Copyright (C) 2005,2006,2007,2008,2009 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "../biosig.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) EXTERN_C void sopen_alpha_read(HDRTYPE* hdr) { /* this function will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ size_t count; unsigned int k; const char *FileName = hdr->FileName; fprintf(stdout,"Warning: support for alpha format is just experimental.\n"); char* fn = (char*)malloc(strlen(hdr->FileName)+15); strcpy(fn,hdr->FileName); // Flawfinder: ignore const size_t bufsiz = 4096; char buf[bufsiz]; // alpha.alp cal_res digin digvidtc eog marker measure mkdef montage rawdata rawhead report.txt r_info sleep const char *f2 = "alpha.alp"; char *tmpstr = strrchr(fn,FILESEP); if (tmpstr) strcpy(tmpstr+1,f2); // Flawfinder: ignore else strcpy(fn,f2); // Flawfinder: ignore FILE *fid = fopen(fn,"r"); count = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0; // terminating 0 character char *t = strtok(buf,"\xA\xD"); while (t) { if (VERBOSE_LEVEL>7) fprintf(stdout,"0: %s \n",t); if (!strncmp(t,"Version = ",9)) hdr->VERSION = atof(t+9); else if (!strncmp(t,"Id = ",4)) { strncpy(hdr->ID.Manufacturer._field,t+5,MAX_LENGTH_MANUF); hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field; } t = strtok(NULL,"\xA\xD"); } f2 = "rawhead"; if (tmpstr) strcpy(tmpstr+1,f2); // Flawfinder: ignore else strcpy(fn,f2); // Flawfinder: ignore int Notch = 0; int Bits = 0; double DigMax=0, DigMin=0; uint16_t gdftyp = 0; int ns = 0; fid = fopen(fn,"r"); count = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0; // terminating 0 character t = strtok(buf,"\xA\xD"); char STATUS = 1; uint32_t *ChanOrder=NULL; char **ChanType = NULL; while ((t!=NULL) && (STATUS<9)) { char *t1 = strchr(t,'='); if (VERBOSE_LEVEL>7) fprintf(stdout,"<%6.2f> %i- %s | %s\n",hdr->VERSION, STATUS,t,t1); if (t1) { t1[-1] = 0; t1++; if (STATUS == 1) { if (!strcmp(t,"Version")) hdr->VERSION = atof(t1); else if (!strcmp(t,"BitsPerValue")) { Bits = atoi(t1); switch (Bits) { case 12: gdftyp = 255+12; // hdr->FILE.LittleEndian = 0; DigMax = (1<<(Bits-1))-1; DigMin = -(1<<(Bits-1)); break; case 16: gdftyp = 3; DigMax = 32752.0; //!!! that's the maximum value found in alpha-trace files DigMin = -32736.0; //!!! that's the minimum value found in alpha-trace files break; case 32: gdftyp = 5; break; DigMax = (1<<(Bits-1))-1; DigMin = -(1<<(Bits-1)); } } else if (!strcmp(t,"ChanCount")) { hdr->NS = atoi(t1); hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE)); ChanOrder = (uint32_t*)calloc(hdr->NS,sizeof(uint32_t)*2); ChanType = (char**)calloc(hdr->NS,sizeof(char*)); } else if (!strcmp(t,"SampleFreq")) hdr->SampleRate = atof(t1); else if (!strcmp(t,"SampleCount")) { hdr->NRec = atoi(t1); hdr->SPR = 1; } else if (!strcmp(t,"NotchFreq")) Notch = atof(t1); else if (!strcmp(t,"DispFlags") && (hdr->VERSION < 411.89)) STATUS = 2; else if (!strcmp(t,"Sec2Marker") && (hdr->VERSION > 411.89)) STATUS = 2; } else if (STATUS == 2) { if (ns>=hdr->NS) { ns = 0; STATUS = 3; } else { CHANNEL_TYPE *hc = hdr->CHANNEL+ns; hc->GDFTYP = gdftyp; hc->Notch = Notch; hc->LeadIdCode = 0; hc->SPR = hdr->SPR; //hc->bi8 = GDFTYP_BITS[gdftyp]*ns; hc->DigMax = DigMax; hc->DigMin = DigMin; hc->OnOff = 1; hc->Cal = 1.0; hc->Off = 0.0; hc->PhysMax = hc->DigMax; hc->PhysMin = hc->DigMin; hc->Transducer[0] = 0; strncpy(hc->Label, t, MAX_LENGTH_LABEL+1); char* t2= strchr(t1,','); t2[0] = 0; while (isspace((++t2)[0])); char* t3= strchr(t2,','); t3[0] = 0; while (isspace((++t3)[0])); char* t4= strchr(t3,','); t4[0] = 0; while (isspace((++t4)[0])); ChanOrder[ns*2] = atoi(t2); ChanOrder[ns*2+1] = ns; ChanType[ns] = t3; ns++; } } else if (STATUS == 3) { // decode information (filters, PhysDim, etc.) and assign to corresponding channels. char *pd = NULL; float tmp1, tmp2, HighPass, LowPass; #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L sscanf(t1, "%f, %f, %f, %f, %as", &HighPass,&LowPass, &tmp1,&tmp2, &pd); #else sscanf(t1, "%f, %f, %f, %f, %ms", &HighPass,&LowPass, &tmp1,&tmp2, &pd); #endif strrchr(pd,',')[0]=0; if (!strcmp(pd,"%%")) pd[1]=0; uint16_t pdc = PhysDimCode(pd); if (pd) free(pd); char flag = 0; for (k=0; k < hdr->NS; k++) { if ((ChanType[k]!=NULL) && !strcmp(t,ChanType[k])) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->PhysDimCode = pdc; //strcpy(hc->PhysDim,pd); hc->LowPass = LowPass; hc->HighPass = HighPass; ChanType[k] = NULL; } if (ChanType[k] != NULL) flag = 1; // not done yet } if (!flag) STATUS = 99; // done with channel definition } } t = strtok(NULL,"\xA\xD"); } hdr->AS.bpb8 = (GDFTYP_BITS[gdftyp]*hdr->NS); // hdr->AS.bpb = (GDFTYP_BITS[gdftyp]*hdr->NS)>>3; // do not rely on this, because some bits can get lost // sort channels qsort(ChanOrder,hdr->NS,2*sizeof(uint32_t),&u32cmp); for (k=0; kNS; k++) { hdr->CHANNEL[ChanOrder[2*k+1]].bi8 = GDFTYP_BITS[gdftyp]*k; hdr->CHANNEL[ChanOrder[2*k+1]].bi = (GDFTYP_BITS[gdftyp]*k)>>3; } free(ChanOrder); free(ChanType); f2 = "cal_res"; if (tmpstr) strcpy(tmpstr+1,f2); // Flawfinder: ignore else strcpy(fn,f2); // Flawfinder: ignore fid = fopen(fn,"r"); if (fid!=NULL) { if (VERBOSE_LEVEL>7) fprintf(stdout,"cal_res: \n"); count = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0; // terminating 0 character t = strtok(buf,"\xA\xD"); t = strtok(NULL,"\xA\xD"); // skip lines 1 and 2 /* char label[MAX_LENGTH_LABEL+1]; char flag[MAX_LENGTH_LABEL+1]; double cal,off; */ char *t0,*t1,*t2,*t3; unsigned n=0; // for (k=0; max(k,n)NS; k++) { t = strtok(NULL,"\xA\xD"); if (t==NULL) { fprintf(stderr,"Warning SOPEN(alpha): scaling coefficients not defined for all channels\n"); break; } // strncpy(hc->Label,t,min(strcspn(t," =,"),MAX_LENGTH_LABEL)); t0 = strchr(t,'=');t0[0]=0;t0++; int ix = strlen(t)-1; while ((ix>0) && isspace(t[ix])) t[ix--] = 0; // remove trailing spaces t1 = strchr(t0,',');t1[0]=0;t1++; t2 = strchr(t1,',');t2[0]=0;t2++; t3 = strchr(t2,',');t3[0]=0;t3++; n = atoi(t); // n==0 if label is provided, n>0 if channel number is provided /* does not work because ambiguous labels are used in rawhead and cal_res (e.g. T3 and T7) if (!n) for (n=0; nNS; n++) { if (!strcmp(hdr->CHANNEL[n].Label,t)) { n++; break; } } */ if (VERBOSE_LEVEL>7) fprintf(stdout,"cal_res: %i %i <%s> %s %s %s\n",k,n,t,t1,t2,t3); CHANNEL_TYPE *hc = hdr->CHANNEL + (n>0 ? n-1 : k); // channel can be denoted by label or number hc->Cal = atof(t1); hc->Off = 0; if (VERBOSE_LEVEL>7) fprintf(stdout," <%s> %s = ###, %f, %f\n", t1,hc->Label,hc->Cal,hc->Off); hc->PhysMax = (hc->DigMax - hc->Off) * hc->Cal; hc->PhysMin = (hc->DigMin - hc->Off) * hc->Cal; hc->XYZ[0]=0; hc->XYZ[1]=0; hc->XYZ[2]=0; } } f2 = "r_info"; if (tmpstr) strcpy(tmpstr+1,f2); // Flawfinder: ignore else strcpy(fn,f2); // Flawfinder: ignore fid = fopen(fn,"r"); if (fid!=NULL) { if (VERBOSE_LEVEL>7) fprintf(stdout,"r_info: \n"); count = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0; // terminating 0 character struct tm T; t = strtok(buf,"\xA\xD"); t = strtok(NULL,"\xA\xD"); // skip line 1 while (t!=NULL) { char *t1 = strchr(t,'='); t1[0] = 0; while (isspace((++t1)[0])); for (k=strlen(t); (k>0) && isspace(t[--k]); t[k]=0); for (k=strlen(t1); (k>0) && isspace(t1[--k]); t1[k]=0); if (VERBOSE_LEVEL>7) fprintf(stdout,"r_info: %s = %s\n",t,t1); if (0) {} else if (!strcmp(t,"RecId")) strncpy(hdr->ID.Recording,t1,MAX_LENGTH_RID); else if (!strcmp(t,"RecDate")) { sscanf(t1,"%02d.%02d.%04d",&T.tm_mday,&T.tm_mon,&T.tm_year); T.tm_year -=1900; T.tm_mon -=1; } else if (!strcmp(t,"RecTime")) sscanf(t1,"%02d.%02d.%02d",&T.tm_hour,&T.tm_min,&T.tm_sec); else if (!strcmp(t,"TechSal")) { if (hdr->ID.Technician) free(hdr->ID.Technician); hdr->ID.Technician = strdup(t1); } else if (!strcmp(t,"TechTitle") || !strcmp(t,"TechLast") || !strcmp(t,"TechFirst")) { size_t l0 = strlen(hdr->ID.Technician); size_t l1 = strlen(t1); hdr->ID.Technician = (char*)realloc(hdr->ID.Technician,l0+l1+2); hdr->ID.Technician[l0] = ' '; strcpy(hdr->ID.Technician+l0+1, t1); // Flawfinder: ignore } t = strtok(NULL,"\xA\xD"); } hdr->T0 = tm_time2gdf_time(&T); } f2 = "marker"; if (tmpstr) strcpy(tmpstr+1,f2); // Flawfinder: ignore else strcpy(fn,f2); // Flawfinder: ignore fid = fopen(fn,"r"); if (fid != NULL) { size_t n,N; N=0; n=0; while (!feof(fid)) { hdr->AS.auxBUF = (uint8_t*) realloc(hdr->AS.auxBUF,N+bufsiz+1); N += fread(hdr->AS.auxBUF+N, 1, bufsiz, fid); } fclose(fid); hdr->AS.auxBUF[N] = 0; // terminating 0 character N = 0; t = (char*)hdr->AS.auxBUF+strcspn((char*)hdr->AS.auxBUF,"\xA\xD"); t = t+strspn(t,"\xA\xD"); // skip lines 1 and 2 while (t[0]) { char* t1 = t; size_t l1 = strcspn(t1,"="); size_t p2 = strspn(t1+l1,"= ")+l1; char* t2 = t+p2; size_t l2 = strcspn(t2," ,"); size_t p3 = strspn(t2+l2," ,")+l2; char* t3 = t2+p3; size_t l3 = strcspn(t3," ,"); size_t p4 = strspn(t3+l3," ,")+l3; char* t4 = t3+p4; size_t l4 = strcspn(t4,"\xA\xD"); size_t p5 = strspn(t4+l4,"\xA\xD")+l4; t1[l1] = 0; while (isspace(t1[--l1])) t1[l1]=0; t2[l2] = 0; t3[l3] = 0; t4[l4] = 0; t = t4 + p5; if (n+1 >= N) { const size_t sz = 100; hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP,(N+sz)*sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS,(N+sz)*sizeof(*hdr->EVENT.POS)); N += sz; } hdr->EVENT.POS[n] = atol(t3); if (!strcmp(t1,"REC")) hdr->EVENT.TYP[n] = 0x7ffe; else if (!strcmp(t1,"MON")) hdr->EVENT.TYP[n] = 0; else if (!strcmp(t1,"TXT")) FreeTextEvent(hdr, n, t4); else FreeTextEvent(hdr, n, t1); if (!strcmp(t2,"off")) hdr->EVENT.TYP[n] |= 0x8000; //fprintf(stdout,"#%u, 0x%04x,%u | t1=<%s> = t2=<%s>, t3=<%s>, t4=<%s>\n",n,hdr->EVENT.TYP[n],hdr->EVENT.POS[n],t1,t2,t3,t4); n++; // t = strtok(NULL,"\xA\xD"); //fprintf(stdout," <%s>\n",t1); } hdr->EVENT.N = n; hdr->EVENT.SampleRate = hdr->SampleRate; // convert2to4_eventtable(hdr); } tmpstr = strrchr(fn,FILESEP); tmpstr[0] = 0; tmpstr = strrchr(fn,FILESEP); f2 = "s_info"; if (tmpstr) strcpy(tmpstr+1,f2); // Flawfinder: ignore else strcpy(fn,f2); // Flawfinder: ignore fid = fopen(fn,"r"); if (fid!=NULL) { count = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0; // terminating 0 character char *Lastname = NULL; char *Firstname = NULL; struct tm T; t = strtok(buf,"\xA\xD"); t = strtok(NULL,"\xA\xD"); // skip line 1 while (t!=NULL) { char *t1 = strchr(t,'='); t1[0] = 0; while (isspace((++t1)[0])); for (k=strlen(t); (k>0) && isspace(t[--k]); t[k]=0); for (k=strlen(t1); (k>0) && isspace(t1[--k]); t1[k]=0); if (VERBOSE_LEVEL>7) fprintf(stdout,"s_info: <%s> = <%s>\n",t,t1); if (0) {} else if (!strcmp(t,"SubjId")) strncpy(hdr->Patient.Id,t1,MAX_LENGTH_PID); else if (!strcmp(t,"Gender")) switch (t1[0]) { case 'm': case 'M': hdr->Patient.Sex = 1; break; case 'w': case 'W': case 'f': case 'F': hdr->Patient.Sex = 2; break; default: hdr->Patient.Sex = 0; break; } else if (!strcmp(t,"Handedness")) switch (t1[0]) { case 'r': case 'R': hdr->Patient.Handedness = 1; break; case 'l': case 'L': hdr->Patient.Handedness = 2; break; default: hdr->Patient.Handedness = 0; break; } else if (!strcmp(t,"Size")) hdr->Patient.Height = atof(t1); else if (!strcmp(t,"Weight")) hdr->Patient.Weight = atof(t1); else if (!strcmp(t,"FirstName")) { Firstname = t1; } else if (!strcmp(t,"LastName")) { Lastname = t1; } else if (!strcmp(t,"BirthDay")) { int c = sscanf(t1,"%02d.%02d.%04d",&T.tm_mday,&T.tm_mon,&T.tm_year); T.tm_year -=1900; T.tm_mon -=1; T.tm_hour =12; T.tm_min =0; T.tm_sec =0; if (c > 2) hdr->Patient.Birthday = tm_time2gdf_time(&T); } t = strtok(NULL,"\xA\xD"); } size_t l0 = strlen(Firstname); size_t l1 = strlen(Lastname); if (l0+l1+1 <= MAX_LENGTH_NAME) { strcpy(hdr->Patient.Name, Firstname); // Flawfinder: ignore hdr->Patient.Name[l0] = ' '; strcpy(hdr->Patient.Name + l0 + 1, Lastname); // Flawfinder: ignore } else strncpy(hdr->Patient.Name, Lastname, MAX_LENGTH_NAME+1); // Flawfinder: ignore } strcpy(fn,hdr->FileName); // Flawfinder: ignore tmpstr = strrchr(fn,FILESEP); f2 = "rawdata"; if (tmpstr) strcpy(tmpstr+1,f2); // Flawfinder: ignore else strcpy(fn,f2); // Flawfinder: ignore if (VERBOSE_LEVEL>7) fprintf(stdout,"rawdata11: %s \n",f2); hdr->FileName = fn; ifopen(hdr,"r"); if (VERBOSE_LEVEL>7) fprintf(stdout,"rawdata22: %s open=%i\n",f2,hdr->FILE.OPEN); if (hdr->FILE.OPEN) { int16_t a[3]; ifread(a, 2, 3, hdr); hdr->VERSION = a[0]; hdr->HeadLen = 6; switch (a[2]) { case 12: gdftyp = 255+12; break; case 16: gdftyp = 3; break; case 32: gdftyp = 5; break; } for (k=a[1]; kNS; k++) hdr->CHANNEL[k].OnOff = 0; for (k=0; kNS; k++) { hdr->CHANNEL[k].GDFTYP = gdftyp; } hdr->AS.bpb = (GDFTYP_BITS[gdftyp]*a[1])>>3; hdr->FILE.POS = 0; size_t len = (GDFTYP_BITS[gdftyp]*a[1]*hdr->NRec*hdr->SPR)>>3; if ((GDFTYP_BITS[gdftyp]*a[1]) & 0x07) { /* hack: if SPR*NS*bits are not a multiple of bytes, hdr->AS.bpb would be non-integer causing some problems in SREAD reading the correct number of bytes. This hack makes sure that all data is loaded. */ len++; } hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata, len); size_t count = ifread(hdr->AS.rawdata,1,len,hdr); hdr->AS.first = 0; hdr->AS.length = (count<<3)/(GDFTYP_BITS[gdftyp]*a[1]); } if (VERBOSE_LEVEL>7) fprintf(stdout,"rawdata55: %s c=%i [%i, %i] sizeof(CHAN)=%i\n",fn,(int)count,(int)hdr->AS.first,(int)hdr->AS.length,(int)sizeof(hdr->CHANNEL[0])); free(fn); hdr->FileName = FileName; } stimfit-0.16.7/src/biosig/biosig4c++/t210/codes.h0000664000175000017500000003364514752215315014617 /* --------------------------------------------------------------------------- Copyright (C) 2003 Eugenio Cervesato & Giorgio De Odorico. Developed at the Associazione per la Ricerca in Cardiologia - Pordenone - Italy. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------------- */ // codes.h consts included in the protocol #ifndef __CODES_H__ #define __CODES_H__ static const char STR_END[]={(char)-1,'\0'}; static char STR_NULL[]=" unspecified/unknown "; static alfabetic _special[]={ { 29999 , "measurements not computed" }, { 29998 , "measurements not found due to rejection of the lead" }, { 19999 , "measurements not found because wave not present" }, { 999 , "undefined" } }; static alfabetic _age[]={ { 0 , " unspecified/unknown " } , { 1 , " years " } , { 2 , " months " } , { 3 , " weeks " } , { 4 , " days " } , { 5 , " hours " } }; static alfabetic _height[]={ { 0 , " unspecified/unknown " } , { 1 , " cm " } , { 2 , " inch " } , { 3 , " mm " } }; static alfabetic _weight[]={ { 0 , " unspecified/unknown " } , { 1 , " Kg " } , { 2 , " g " } , { 3 , " lb " } , { 4 , " oz " } }; static alfabetic _sex[]={ { 0 , " ? " } , { 1 , " M " } , { 2 , " F " } , { 3 , " unspecified/unknown " } }; static alfabetic _race[]={ { 0 , " unspecified/unknown " } , { 1 , " caucasian " } , { 2 , " black " } , { 3 , " oriental " } }; static alfabetic class_drug[]={ { 0 , " unspecified/unknown " } , { 1 , " digitalis preparation " } , { 2 , " antiarrhythmic " } , { 3 , " diuretics " } , { 4 , " antihypertensive " } , { 5 , " antianginal " } , { 6 , " antithrombotic agents " } , { 7 , " beta blockers " } , { 8 , " psychotropic " } , { 9 , " calcium blockers " } , { 10 , " antihypotensive " } , { 11 , " anticholesterol " } , { 12 , " ACE-inhibitors " } , { 100 , " not taking drugs " } , { 101 , " drugs, but unknown type " } , { 102 , " other medication " }, { 256 , " unspecified/unknown " } , { 257 , " digoxin-lanoxin " } , { 258 , " digitoxin-digitalis " } , { 265 , " other " }, { 512 , " unspecified/unknown " } , { 513 , " dysopyramide " } , { 514 , " quinidine " } , { 515 , " procainamide " } , { 516 , " lidocaine " } , { 517 , " phenytoin " } , { 518 , " dilantin " } , { 519 , " amiodarone " } , { 520 , " tocainide " } , { 521 , " other " } , { 522 , " encainide " } , { 523 , " mexitil/mexilitine " } , { 524 , " flecainide " } , { 525 , " lorcainide " } , { 768 , " unspecified/unknown " } , { 769 , " thiazide " } , { 770 , " furosemide (lasix) " } , { 771 , " potassium cloride " } , { 777 , " other " } , { 1024 , " unspecified/unknown " } , { 1025 , " clonidine " } , { 1026 , " prasozin " } , { 1027 , " hydralazine " } , { 1033 , " other " }, { 1280 , " unspecified/unknown " } , { 1281 , " isosorbide " } , { 1282 , " calcium blockers " } , { 1283 , " diuretics " } , { 1284 , " nitrates " } , { 1289 , " other " }, { 1536 , " unspecified/unknown " } , { 1537 , " aspirin " } , { 1538 , " coumarin " } , { 1539 , " heparin " } , { 1540 , " warfarin " } , { 1541 , " streptokinase " } , { 1542 , " t-PA " } , { 1545 , " other " }, { 1792 , " unspecified/unknown " } , { 1793 , " propanolol " } , { 1794 , " corgard " } , { 1795 , " atenolol " } , { 1796 , " metoprolol " } , { 1797 , " pindolol " } , { 1798 , " acebutolol " } , { 1801 , " other " }, { 2048 , " unspecified/unknown " } , { 2049 , " tricyclic antidepressant " } , { 2050 , " phenothiazide " } , { 2051 , " barbiturate " } , { 2057 , " other " }, { 2304 , " unspecified/unknown " } , { 2305 , " nifedipine " } , { 2306 , " verapamil " } , { 2313 , " other " }, { 2560 , " unspecified/unknown " } , { 2561 , " asthmatic drug " } , { 2562 , " aminophyline " } , { 2563 , " isuprel " } , { 2569 , " other " }, { 2816 , " unspecified/unknown " } , { 2817 , " colestid " } , { 2818 , " lovastatin " } , { 2819 , " simvastatin " } , { 2820 , " fibrates " } , { 2825 , " other " }, { 3071 , " unspecified/unknown " } , { 3072 , " captopril " } , { 3081 , " other " } }; static alfabetic device_type[]={ { 0 , " Cart " }, { 1 , " host " }, { 2 , " unspecified/unknown "} }; static alfabetic legacy_device[]={ { 0 , " unspecified/unknown " } , { 1 , " Burdick " } , { 2 , " Cambridge " } , { 3 , " Comprumed " } , { 4 , " Datamed " } , { 5 , " Fukuda " } , { 6 , " Hewlett-Packard " } , { 7 , " Marquette Electronics " } , { 8 , " Moratara Instruments " } , { 9 , " Nihon Kohden " } , { 10 , " Okin " } , { 11 , " Quinton " } , { 12 , " Siemens " } , { 13 , " Spacelabs " } , { 14 , " Telemed " } , { 15 , " Hellige " } , { 16 , " ESA-OTE " } , { 17 , " Schiller " } , { 18 , " Picker-Schwarzer " } , { 19 , " Elettronica-Trentina " } , { 20 , " Zwonitz " } }; static alfabetic compatibility[]={ { 72 , " I " } , { 160 , " II " } , { 176 , " III " } , { 192 , " IV " }, { 255 , " unspecified/unknown " } }; static alfabetic language_code[]={ { 0 , " 8 bit ASCII only " } , { 1 , " ISO-8859-1 latin-1 " } , { 192 , " ISO-8859-2 latin-2 (central and estern european) " } , { 208 , " ISO-8859-4 latin-4 (Baltic) " } , { 200 , " ISO-8859-5 (Cyrillic) " } , { 216 , " ISO-8859-6 (Arabic) " } , { 196 , " ISO-8859-7 (Greek) " } , { 212 , " ISO-8859-8 (Hebrew) " } , { 204 , " ISO-8859-11 (Thai) " } , { 220 , " ISO-8859-15 latin-9 (latin-0) " } , { 224 , " Unicode (ISO-60646) " } , { 240 , " JIS X0201-1976 (Japanese) " } , { 232 , " JIS X0208-1977 (Japanese) " } , { 248 , " JIS X0212-1990 (Japanese) " } , { 228 , " GB 2312-80 (Chinese) " } , { 244 , " KS C5601-1987 (Korean) " } , { 255 , " unspecified/unknown " } }; static alfabetic capability_device[]={ { 1 , " No printing " } , { 2 , " No analysis " } , { 3 , " No storage " } , { 4 , " No acquisition " } , { 5 , " can print ECG reports " } , { 6 , " can interpret ECG " } , { 7 , " can store ECG records " } , { 8 , " can acquire ECG data " } }; static alfabetic frequency_AC[]={ { 0 , " unspecified/unknown " } , { 1 , " 50 Hz " } , { 2 , " 60 Hz " } }; static alfabetic filter_bitmap[]={ { 0 , " unspecified/unknown " }, { 1 , " 60 Hz notch filter " } , { 2 , " 50 Hz notch filter " } , { 3 , " artifact filter " } , { 4 , " baseline filter " } }; static alfabetic _hystory[]={ { 0 , " diagnoses or clinical problems " } , { 1 , " apparently healty " } , { 10 , " acute myocardial infarction " } , { 11 , " myocardial infarction " } , { 12 , " previous myocardial infarction " } , { 15 , " ischemic heart disease " } , { 18 , " peripheral vascular disease " } , { 20 , " cyanotic congenital heart disease " } , { 21 , " acyanotic congenital heart disease " } , { 22 , " valvular heart disease " } , { 25 , " hypertension " } , { 27 , " cerebrovascular accident " } , { 30 , " cardiomyopathy " } , { 35 , " pericardits " } , { 36 , " myocardits " } , { 40 , " post-operative cardiac surgery " } , { 42 , " implanted cardiac pacemaker " } , { 45 , " pulmonary embolism " } , { 50 , " respiratory disease " } , { 55 , " endocrine disease " } , { 60 , " neurological disease " } , { 65 , " alimentary disease " } , { 70 , " renal disease " } , { 80 , " pre-operative general surgery " } , { 81 , " post-operative general surgery " } , { 90 , " general medical " } , { 100 , " unspecified/unknown " } }; static alfabetic electrode_configuration_standard[]={ { 0 , " unspecified/unknown " } , { 1 , " 12-lead positions: RA, RL, LA, and LL at limb extremities. V1 to V6 at standard positions on the chest. Individually " } , { 2 , " RA, RL, LA, and LL are placed on the torso. V1 to V6 are placed at standard positions on the chest. Individually " } , { 3 , " RA, RL, LA, and LL are individually placed on the torso. V1 to V6 on the chest as part of a single electrode pad " } , { 4 , " RA, RL, LA, LL, and V1 to V6 (all electrodes) are on the chest in a single electrode pad " } , { 5 , " 12-lead ECG is derived from Frank XYZ leads " } , { 6 , " 12-lead ECG is derived from non-standard leads " } }; static alfabetic electrode_configuration_XYZ[]={ { 0 , " unspecified/unknown " } , { 1 , " Frank " } , { 2 , " McFee-Parungao " } , { 3 , " Cube " } , { 4 , " XYZ bipolar uncorrected " } , { 5 , " pseudo-orthogonal XYZ (as used in Holter) " } , { 6 , " XYZ derived from standard 12 leads " } }; static alfabetic lead_identification[]={ { 0 , " unspecified/unknown " } , { 1 , " I " } , { 2 , " II " } , { 3 , " V1 " } , { 4 , " V2 " } , { 5 , " V3 " } , { 6 , " V4 " } , { 7 , " V5 " } , { 8 , " V6 " } , { 9 , " V7 " } , { 10 , " V2R " } , { 11 , " V3R " } , { 12 , " V4R " } , { 13 , " V5R " } , { 14 , " V6R " } , { 15 , " V7R " } , { 16 , " X " } , { 17 , " Y " } , { 18 , " Z " } , { 19 , " CC5 " } , { 20 , " CM5 " } , { 21 , " left arm " } , { 22 , " right arm " } , { 23 , " left leg " } , { 24 , " I " } , { 25 , " R " } , { 26 , " C " } , { 27 , " A " } , { 28 , " M " } , { 29 , " F " } , { 30 , " H " } , { 31 , " I-cal " } , { 32 , " II-cal " } , { 33 , " V1-cal " } , { 34 , " V2-cal " } , { 35 , " V3-cal " } , { 36 , " V4-cal " } , { 37 , " V5-cal " } , { 38 , " V6-cal " } , { 39 , " V7-cal " } , { 40 , " V2R-cal " } , { 41 , " V3R-cal " } , { 42 , " V4R-cal " } , { 43 , " V5R-cal " } , { 44 , " V6R-cal " } , { 45 , " V7R-cal " } , { 46 , " X-cal " } , { 47 , " Y-cal " } , { 48 , " Z-cal " } , { 49 , " CC5-cal " } , { 50 , " CM5-cal " } , { 51 , " left arm-cal " } , { 52 , " right arm-cal " } , { 53 , " left leg-cal " } , { 54 , " I-cal " } , { 55 , " R-cal " } , { 56 , " C-cal " } , { 57 , " A-cal " } , { 58 , " M-cal " } , { 59 , " F-cal " } , { 60 , " H-cal " } , { 61 , " III " } , { 62 , " aVR " } , { 63 , " aVL " } , { 64 , " aVF " } , { 65 , " -aVR " } , { 66 , " V8 " } , { 67 , " V9 " } , { 68 , " V8R " } , { 69 , " V9R " } , { 70 , " D (Nehb-dorsal) " } , { 71 , " A (Nehb-anterior) " } , { 72 , " J (Nehb-inferior) " } , { 73 , " defibrillator anterior-lateral " } , { 74 , " external pacing anterior-posterior " } , { 75 , " A1 (auxiliary unipolar lead 1) " } , { 76 , " A2 (auxiliary unipolar lead 2) " } , { 77 , " A3 (auxiliary unipolar lead 3) " } , { 78 , " A4 (auxiliary unipolar lead 4) " } , { 79 , " V8-cal " } , { 80 , " V9-cal " } , { 81 , " V8R-cal " } , { 82 , " V9R-cal " } , { 83 , " D-cal (Nehb-dorsal) " } , { 84 , " A-cal (Nehb-anterior) " } , { 85 , " J-cal (Nehb-inferior) " } }; static alfabetic _encode[]={ { 0 , " real " } , { 1 , " first difference " } , { 2 , " second difference " } }; static alfabetic _compression[]={ { 0 , " bimodal compression not used " } , { 1 , " bimodal compression used " } }; static alfabetic spike_type[]={ { 0 , " unspecified/unknown " } , { 1 , " spike triggers neither P-wave nor QRS " } , { 2 , " spike triggers a QRS " } , { 3 , " spike triggers a P-wave " } }; static alfabetic source_pacemaker[]={ { 0 , " unspecified/unknown " } , { 1 , " internal " } , { 2 , " external " } }; static alfabetic triggered_spike[]={ { 0 , " spike does not trigger a QRS " } , { 1 , " spike triggers a QRS " } }; static alfabetic _formula_type[]={ { 0 , " unspecified/unknown " } , { 1 , " Bazett " } , { 2 , " Hodges " } }; static alfabetic ID_tag[]={ { 0 , " QTend all-lead dispersion " } , { 1 , " QTpeak all-lead dispersion " } , { 2 , " QTend precordial dispersion " } , { 3 , " QTpeak precordial dispersion " } , { 4 , " unspecified/unknown " } }; static alfabetic value_tag[]={ { 0 , " Dispersion = maximum QT interval ? minimum QT interval " } , { 1 , " Heart rate corrected Dispersion: Max?Min " } , { 2 , " Dispersion = standard deviation of the QT intervals " } , { 3 , " Heart rate corrected Dispersion: standard deviation " } , { 4 , " Heart rate correction formula. (See definition of byte 7 for valid values) " } }; static alfabetic type_confirm[]={ { 0 , " original report (not overread) " } , { 1 , " confirmed report " } , { 2 , " overread report, but not confirmed " } , { 3 , " unspecified/unknown " } }; static alfabetic morphology_description[]={ { 0 , " unspecified/unknown " } , { 1 , " positive " } , { 2 , " negative " } , { 3 , " positive/negative " } , { 4 , " negative/positive " } , { 5 , " positive/negative/positive " } , { 6 , " negative/positive/negative " } , { 7 , " notched M-shaped " } , { 8 , " notched W-shaped " } }; static alfabetic quality_code[]={ { 0 , " AC (mains) noise " } , { 1 , " overrange " } , { 2 , " wander " } , { 3 , " tremor or muscle artifact " } , { 4 , " spike or sudden jumps " } , { 5 , " electrode loose or off " } , { 6 , " pacemaker " } , { 7 , " interchanged lead " } }; static alfabetic noise_level[]={ { 0 , " none/no " } , { 1 , " moderate/yes " } , { 2 , " severe " } , { 3 , " unknown " } }; static alfabetic type_statement[]={ { 1 , " coded statement type " } , { 2 , " full text type " } , { 3 , " statement logic type " } }; #endif /*__CODES_H__*/ stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_sqlite.c0000664000175000017500000001725514752215315016221 /* Copyright (C) 2021 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #ifdef WITH_SQLITE3 #include #endif #include "../biosig.h" #ifdef WITH_SQLITE3 static int callback(void *NotUsed, int argc, char **argv, char **azColName) { for(int i=0; i6) fprintf(stdout,"%s (line %d): %s(...) libsqlite v%s is used\n", __FILE__,__LINE__,__func__,sqlite3_libversion()); //sqlite3_initialize(); rc = sqlite3_open(hdr->FileName, &db); if (rc) { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "can not open (sqlite) file."); sqlite3_close(db); return; } if (VERBOSE_LEVEL>6) fprintf(stdout,"%s (line %d): %s(...)rc=%d\n", __FILE__,__LINE__,__func__,rc); /* Identify whether it is an Cadwell EZDATA file or not Cadwell has these tables: */ char zSql[SIZE_zSql]; strcpy(zSql, "SELECT COUNT(*) AS x FROM FrameInfo;" "SELECT COUNT(*) AS a FROM MiscInfo;" "SELECT COUNT(*) AS b FROM TrackInfoSyncRowData;" "SELECT COUNT(*) AS c FROM MaxUpdateTick;" "SELECT COUNT(*) AS d FROM MiscInfoSyncRowData;" "SELECT COUNT(*) AS e FROM syncrowdata;" "SELECT COUNT(*) AS f FROM MediaHeader;" "SELECT COUNT(*) AS g FROM SchemaUpdateLog;" "SELECT COUNT(*) AS h FROM synctable;" "SELECT COUNT(*) AS i FROM MediaHeaderSyncRowData;" "SELECT COUNT(*) AS j FROM TrackInfo;"); rc = sqlite3_exec(db, zSql, callback, 0, zErrMsg); if( rc != SQLITE_OK ) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format SQLite: not supported yet - not an ARC(Cadwell) file."); fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } if (VERBOSE_LEVEL>6) fprintf(stdout,"%s (line %d) %s(...) most likely a Cadwell file, because all tables are available.\n",__FILE__,__LINE__,__func__); const char *ARC_TableList[]={"FrameInfo", "MiscInfo", "TrackInfoSyncRowData", "MaxUpdateTick", "MiscInfoSyncRowData", "syncrowdata", "MediaHeader", "SchemaUpdateLog", "synctable", "MediaHeaderSyncRowData", "TrackInfo", NULL}; // https://www.sqlite.org/c3ref/prepare.html /* SQL statement, UTF-8 encoded */ unsigned int prepFlags = 0; sqlite3_stmt *pStmt = NULL; /* OUT: Statement handle */ const char *zTail = NULL; /* OUT: Pointer to unused portion of zSql */ if (VERBOSE_LEVEL>6) fprintf(stdout,"%s (line %d): %s(...)rc=%d\n", __FILE__, __LINE__, __func__, rc); for (int k=0; ARC_TableList[k]!=NULL; k++) { snprintf(zSql, SIZE_zSql, "SELECT * FROM %s", ARC_TableList[k]); rc = sqlite3_prepare_v2(db, zSql, sizeof(zSql), &pStmt, &zTail); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...)rc=%d <-prepare(db,\"%s\",...)\n", __FILE__,__LINE__,__func__, rc, zSql); int M = 0; while (SQLITE_ROW==sqlite3_step(pStmt)) { M++; if (M==1) for (int col = 0; ; col++) { int typ = sqlite3_column_type(pStmt, col); if (typ==SQLITE_NULL) break; char *DatabaseName = sqlite3_column_database_name(pStmt,col); char *TableName = sqlite3_column_table_name(pStmt,col); char *ColumnName = sqlite3_column_origin_name(pStmt,col); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...) col%d: %s.%s.%s\n", \ __FILE__,__LINE__,__func__, col+1, DatabaseName, TableName, ColumnName); } for (int col = 0; ; col++) { int T,I; int64_t I64; char *S; if (M > 10) break; // this breaks only the inner loop and stopping the output/fprintf, only up to M rows are displayed size_t sz = sqlite3_column_bytes(pStmt, col); int typ = sqlite3_column_type(pStmt, col); if (typ==SQLITE_NULL) break; switch (typ) { case SQLITE_INTEGER: { // 1 double V = sqlite3_column_int64(pStmt, col); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...) r%d,c%d sz%d I<%ld>\n", \ __FILE__,__LINE__,__func__, M, col+1, sz, V); break; } case SQLITE_FLOAT: { // 2 double V = sqlite3_column_double(pStmt, col); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...) r%d,c%d sz%d F<%g>\n", \ __FILE__,__LINE__,__func__, M, col+1, sz, V); break; } case SQLITE_TEXT: { // 3 char* V = sqlite3_column_text(pStmt, col); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...) r%d,c%d sz%d T<%s>\n", \ __FILE__,__LINE__,__func__, M, col+1, sz, V); break; } case SQLITE_BLOB: { // 4 void* V = sqlite3_column_blob(pStmt, col); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %d): %s(...) r%d,c%d sz%d 0x%016x\n", \ __FILE__,__LINE__,__func__, M, col+1, sz, leu64p(V)); if (VERBOSE_LEVEL>8) { char A[33]; A[32]=0; for (int k=0; k7) fprintf(stdout,"%s (line %d): %s(...) rows=%d T%d %d %ld %s\n", __FILE__,__LINE__,__func__, M,T,I,I64,S); } // for } // while if (VERBOSE_LEVEL>6) fprintf(stdout,"%s (line %d): %s(...) rows=%d\n", __FILE__,__LINE__,__func__, M); // https://www.sqlite.org/c3ref/finalize.html rc = sqlite3_finalize(pStmt); if (VERBOSE_LEVEL>6) fprintf(stdout,"%s (line %d): %s(...)rc=%d <-finalize(...) \n", __FILE__,__LINE__,__func__, rc); } if (VERBOSE_LEVEL > 6) fprintf(stdout,"%s (line %d) %s(...) rc=%d\n", __FILE__,__LINE__,__func__,rc); sqlite3_close(db); sqlite3_shutdown(); /* TODO: - check whether it is a recognized and supported data set (i.e. Cadwell/ARC format) - fill in HDRstruct* hdr - extract data samples and fill hdr->data - fill event table if applicable Once these steps are completed, the following line can be removed */ biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format SQLite: not supported yet."); #else // WITH_SQLITE3 biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "SOPEN(SQLite): - sqlite format not supported - libbiosig need to be recompiled with libsqlite3 support."); #endif // WITH_SQLITE3 } stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_biosigdump_read.c0000664000175000017500000000311514752215315020043 /* Copyright (C) 2022 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "../biosig.h" /****************************************************************************** read BiosigDump file ******************************************************************************/ void sopen_biosigdump_read(HDRTYPE* hdr) { if (VERBOSE_LEVEL > 8) fprintf(stdout,"%s (line %d) %s(hdr)\n", __FILE__, __LINE__, __func__); if (hdr->TYPE==BiosigDump) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Format BiosigDump: not supported yet"); } /* between 512 and 4096 bytes are already read into hdr->AS.Header, the exact number of bytes read, is available in "hdr->HeadLen" Currently this is 4096, but it might change in future. */ } stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_scp_read.c0000664000175000017500000016652414752215315016504 /* Copyright (C) 2005-2018 Alois Schloegl Copyright (C) 2011 Stoyan Mihaylov This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. */ // #define WITHOUT_SCP_DECODE // use SCP-DECODE if needed, Bimodal, reference beat /* the experimental version needs a few more thinks: - Bimodal and RefBeat decoding do not work yet - validation and testing */ #include #include #include #include #include #if !defined(__APPLE__) && defined (_LIBICONV_H) #define iconv libiconv #define iconv_open libiconv_open #define iconv_close libiconv_close #endif #include "../biosig-dev.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) #include "structures.h" static const uint8_t _NUM_SECTION = 20; //consider first 19 sections of SCP static bool add_filter = true; // additional filtering gives better shape, but use with care #ifdef __cplusplus extern "C" { #endif #ifndef WITHOUT_SCP_DECODE int scp_decode(HDRTYPE* hdr, struct pointer_section *section, struct DATA_DECODE*, struct DATA_RECORD*, struct DATA_INFO*, bool ); void sopen_SCP_clean(struct DATA_DECODE*, struct DATA_RECORD*, struct DATA_INFO*); #endif // Huffman Tables uint16_t NHT; /* number of Huffman tables */ typedef struct table_t { uint8_t PrefixLength; uint8_t CodeLength; uint8_t TableModeSwitch; int16_t BaseValue; uint32_t BaseCode; } table_t; typedef struct huffman_t { uint16_t NCT; /* number of Code structures in Table #1 */ table_t *Table; } huffman_t; huffman_t *Huffman; typedef struct htree_t { struct htree_t* child0; struct htree_t* child1; uint16_t idxTable; } htree_t; htree_t **HTrees; table_t DefaultTable[19] = { { 1, 1, 1, 0, 0 }, { 3, 3, 1, 1, 1 }, { 3, 3, 1,-1, 5 }, { 4, 4, 1, 2, 3 }, { 4, 4, 1,-2, 11}, { 5, 5, 1, 3, 7 }, { 5, 5, 1,-3, 23}, { 6, 6, 1, 4, 15}, { 6, 6, 1,-4, 47}, { 7, 7, 1, 5, 31}, { 7, 7, 1,-5, 95}, { 8, 8, 1, 6, 63}, { 8, 8, 1,-6, 191}, { 9, 9, 1, 7, 127}, { 9, 9, 1,-7, 383}, {10, 10, 1, 8, 255}, {10, 10, 1,-8, 767}, {18, 10, 1, 0, 511}, {26, 10, 1, 0, 1023} }; /* This structure defines the fields used for "Annotated ECG" */ typedef struct en1064_t { char* test; /* test field for annotated ECG */ float diastolicBloodPressure; float systolicBloodPressure; char* MedicationDrugs; char* ReferringPhysician; char* LatestConfirmingPhysician; char* Diagnosis; uint8_t EmergencyLevel; /* 0: routine 1-10: increased emergency level */ float HeartRate; float P_wave[2]; /* start and end */ float QRS_wave[2]; /* start and end */ float T_wave[2]; /* start and end */ float P_QRS_T_axes[3]; /***** SCP only fields *****/ struct { uint8_t HUFFMAN; uint8_t REF_BEAT; uint8_t DIFF;// OBSOLETE uint8_t BIMODAL;// OBSOLETE } FLAG; struct { //uint8_t tag14[41],tag15[41]; struct { uint16_t INST_NUMBER; /* tag 14, byte 1-2 */ uint16_t DEPT_NUMBER; /* tag 14, byte 3-4 */ uint16_t DEVICE_ID; /* tag 14, byte 5-6 */ uint8_t DeviceType; /* tag 14, byte 7: 0: Cart, 1: System (or Host) */ uint8_t MANUF_CODE; /* tag 14, byte 8 (MANUF_CODE has to be 255) */ char* MOD_DESC; /* tag 14, byte 9 (MOD_DESC has to be "Cart1") */ uint8_t VERSION; /* tag 14, byte 15 (VERSION has to be 20) */ uint8_t PROT_COMP_LEVEL; /* tag 14, byte 16 (PROT_COMP_LEVEL has to be 0xA0 => level II) */ uint8_t LANG_SUPP_CODE; /* tag 14, byte 17 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) */ uint8_t ECG_CAP_DEV; /* tag 14, byte 18 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) */ uint8_t MAINS_FREQ; /* tag 14, byte 19 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) */ char reserved[22]; /* char[35-19] reserved; */ char* ANAL_PROG_REV_NUM; char* SERIAL_NUMBER_ACQ_DEV; char* ACQ_DEV_SYS_SW_ID; char* ACQ_DEV_SCP_SW; /* tag 14, byte 38 (SCP_IMPL_SW has to be "OpenECG XML-SCP 1.00") */ char* ACQ_DEV_MANUF; /* tag 14, byte 38 (ACQ_DEV_MANUF has to be "Manufacturer") */ } Tag14, Tag15; } Section1; struct { } Section2; struct { uint8_t NS, flags; struct { uint32_t start; uint32_t end; // uint8_t id; } *lead; } Section3; struct { uint16_t len_ms, fiducial_sample, N; uint32_t SPR; struct { uint16_t btyp; uint32_t SB; uint32_t fcM; uint32_t SE; uint32_t QB; uint32_t QE; } *beat; } Section4; struct { size_t StartPtr; size_t Length; uint16_t AVM, dT_us; uint8_t DIFF; //diff: see FLAG uint16_t *inlen; int32_t *datablock; } Section5; struct { size_t StartPtr; size_t Length; uint16_t AVM, dT_us; uint8_t DIFF, BIMODAL; //diff, bimodal: see FLAG int32_t *datablock; } Section6; } en1064_t; en1064_t en1064; /* new node in Huffman tree */ htree_t* newNode(void) { htree_t* T = (htree_t*) malloc(sizeof(htree_t)); T->child0 = NULL; T->child1 = NULL; T->idxTable = 0; return(T); } /* check Huffman tree */ int checkTree(htree_t *T) { int v,v1,v2,v3; v1 = (T->child0 == NULL) && (T->child0 == NULL) && (T->idxTable > 0); v2 = (T->idxTable == 0) && (T->child0 != NULL) && checkTree(T->child0); v3 = (T->idxTable == 0) && (T->child1 != NULL) && checkTree(T->child1); v = v1 || v2 || v3; #ifndef ANDROID if (!v) fprintf(stderr,"Warning: Invalid Node in Huffman Tree: %i %p %p\n",T->idxTable,T->child0,T->child1); #endif return(v); } /* convert Huffman Table into a Huffman tree */ htree_t* makeTree(huffman_t HT) { uint16_t k1,k2; htree_t* T = newNode(); htree_t* node; for (k1=0; k1>=1) { if (bc & 0x00000001) { if (node->child1==NULL) node->child1 = newNode(); node = node->child1; } else { if (node->child0==NULL) node->child0 = newNode(); node = node->child0; } } node->idxTable = k1+1; } return(T); } /* get rid of Huffman tree */ void freeTree(htree_t* T) { if (T->child0 != NULL) freeTree(T->child0); if (T->child1 != NULL) freeTree(T->child1); free(T); } int DecodeHuffman(htree_t *HTrees[], huffman_t *HuffmanTables, uint8_t* indata, size_t inlen, int32_t* outdata, size_t outlen) { uint16_t ActualTable = 0; htree_t *node; size_t k1, k2, i; uint32_t acc; int8_t dlen,k3,r; k1=0, k2=0; node = HTrees[ActualTable]; r = 0; i = 0; while ((k1 < inlen*8) && (k2 < outlen)) { r = k1 % 8; i = k1 / 8; if (!node->idxTable) { if (indata[i] & (1<<(7-r))) { if (node->child1 != NULL) node = node->child1; else { return(-1); } } else { if (node->child0 != NULL) node = node->child0; else { return(-1); } } ++k1; } r = k1 % 8; i = k1 / 8; if (node->idxTable) { // leaf of tree reached table_t TableEntry = HuffmanTables[ActualTable].Table[node->idxTable - 1]; dlen = TableEntry.PrefixLength - TableEntry.CodeLength; if (!TableEntry.TableModeSwitch) // switch Huffman Code ActualTable = TableEntry.BaseValue; else if (dlen) { // no compression acc = 0; //(uint32_t)(indata[i]%(1<> (k3*8 - r - dlen)) & ((1L << dlen) - 1L) ; if (outdata[k2] >= (1 << (dlen-1))) outdata[k2] -= 1 << dlen; k1 += dlen; ++k2; } else { // lookup Huffman Table outdata[k2++] = TableEntry.BaseValue; } // reset node to root node = HTrees[ActualTable]; } } return(0); }; void deallocEN1064(en1064_t en1064) { /* free allocated memory */ if (en1064.FLAG.HUFFMAN) { size_t k1=0; for (; k1aECG)).Section1.Tag14.LANG_SUPP_CODE; iconv_t cd; if ((LanguageSupportCode & 0x01) == 0) cd = iconv_open ("UTF-8", "ASCII"); else if ((LanguageSupportCode & 0x03) == 1) cd = iconv_open ("UTF-8", "ISO8859-1"); else if (LanguageSupportCode == 0x03) cd = iconv_open ("UTF-8", "ISO8859-2"); else if (LanguageSupportCode == 0x0b) cd = iconv_open ("UTF-8", "ISO8859-4"); else if (LanguageSupportCode == 0x13) cd = iconv_open ("UTF-8", "ISO8859-5"); else if (LanguageSupportCode == 0x1b) cd = iconv_open ("UTF-8", "ISO8859-6"); else if (LanguageSupportCode == 0x23) cd = iconv_open ("UTF-8", "ISO8859-7"); else if (LanguageSupportCode == 0x2b) cd = iconv_open ("UTF-8", "ISO8859-8"); else if (LanguageSupportCode == 0x33) cd = iconv_open ("UTF-8", "ISO8859-11"); else if (LanguageSupportCode == 0x3b) cd = iconv_open ("UTF-8", "ISO8859-15"); else if (LanguageSupportCode == 0x07) cd = iconv_open ("UTF-8", "ISO-10646"); else if (LanguageSupportCode == 0x0f) // JIS X 0201-1976 (Japanese) - does not match exactly cd = iconv_open ("UTF-8", "EUC-JISX0213"); else if (LanguageSupportCode == 0x17) // JIS X 0208-1997 (Japanese) - does not match exactly cd = iconv_open ("UTF-8", "EUC-JISX0213"); else if (LanguageSupportCode == 0x1f) // JIS X 0212-1990 (Japanese) - does not match exactly cd = iconv_open ("UTF-8", "EUC-JISX0213"); else if (LanguageSupportCode == 0x27) cd = iconv_open ("UTF-8", "GB2312"); else if (LanguageSupportCode == 0x37) cd = iconv_open ("UTF-8", "UTF-8"); else if (LanguageSupportCode == 0x2F) // KS C5601-1987 (Korean) - does not match exactly cd = iconv_open ("UTF-8", "EUC-KR"); else { biosigERROR(hdr, B4C_CHAR_ENCODING_UNSUPPORTED, "SCP character encoding not supported"); return -1; } errno = 0; // reset error status int errsv; if (input[inbytesleft-1]==0) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(%i) decode_scp_text: input=<%s>%i,%i\n", __FILE__, __LINE__, input,(int)inbytesleft,(int)outbytesleft); // input string is 0-terminated iconv(cd, &input, &inbytesleft, &output, &outbytesleft); errsv = errno; } else if (inbytesleft < 64) { /* In case the string is not 0-terminated, * the string is copied to make it 0-terminated */ char buf[64]; char *tmpstr=buf; memcpy(buf,input,inbytesleft); tmpstr[inbytesleft++]=0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(%i) decode_scp_text: input=<%s>%i,%i\n", __FILE__, __LINE__, input,(int)inbytesleft,(int)outbytesleft); iconv(cd, &tmpstr, &inbytesleft, &output, &outbytesleft); errsv = errno; } else { /* In case the string is not 0-terminated, * the string is copied to make it 0-terminated */ char *tmpstr=malloc(inbytesleft+1); char *bakstr=tmpstr; strncpy(tmpstr,(char*)input,inbytesleft); tmpstr[inbytesleft]=0; inbytesleft++; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(%i) decode_scp_text: input=<%s>%i,%i\n", __FILE__, __LINE__, tmpstr,(int)inbytesleft,(int)outbytesleft); iconv(cd, &tmpstr, &inbytesleft, &output, &outbytesleft); errsv = errno; free(bakstr); } if (errsv) biosigERROR(hdr, B4C_CHAR_ENCODING_UNSUPPORTED, "conversion of SCP text failed"); #ifdef DEBUG if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(%i) decode_scp_text: [e%i ] output=<%s>%i,%i\n", __FILE__, __LINE__, errsv,start,inbytesleft,outbytesleft); #endif return (iconv_close(cd) || errsv); #else // if neither _ICONV_H nor _LIBCONV_H are defined if ((LanguageSupportCode & 0xFE) != 0) { biosigERROR(hdr, B4C_CHAR_ENCODING_UNSUPPORTED, "SCP character encoding not supported"); } else // ASCII encoding is UTF-8 compatible - no convesion needed strncpy(output, input, min(inbytesleft, outbytesleft+1)); return(LanguageSupportCode & 0xFE); #endif } int sopen_SCP_read(HDRTYPE* hdr) { /* this function is a stub or placeholder and need to be defined in order to be useful. It will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ uint8_t* ptr; // pointer to memory mapping of the file layout uint8_t* PtrCurSect; // point to current section uint8_t* Ptr2datablock=NULL; // pointer to data block int32_t* data=NULL; // point to rawdata uint16_t curSect=0; // current section uint32_t len; uint16_t crc; uint32_t i,k1,k2; size_t curSectPos; size_t sectionStart; int NSections = 12; uint8_t tag; float HighPass=0, LowPass=INFINITY, Notch=-1; // filter settings uint16_t Cal5=0, Cal6=0, Cal0=0; // scaling coefficients uint16_t dT_us = 1000; // sampling interval in microseconds /* Try direct conversion SCP->HDR to internal data structure + whole data is loaded once, then no further File I/O is needed. - currently Huffman and Bimodal compression is not supported. */ struct aecg* aECG; en1064.Section5.inlen = NULL; en1064.Section5.datablock = NULL; en1064.Section3.lead = NULL; en1064.Section4.beat = NULL; if (hdr->aECG == NULL) { hdr->aECG = malloc(sizeof(struct aecg)); aECG = (struct aecg*)hdr->aECG; aECG->diastolicBloodPressure=0.0; aECG->systolicBloodPressure=0.0; aECG->MedicationDrugs = NULL; aECG->ReferringPhysician= NULL; aECG->LatestConfirmingPhysician=NULL; aECG->Diagnosis=NULL; aECG->EmergencyLevel=0; } else aECG = (struct aecg*)hdr->aECG; aECG->Section1.Tag14.VERSION = 0; // acquiring.protocol_revision_number aECG->Section1.Tag15.VERSION = 0; // analyzing.protocol_revision_number aECG->Section1.Tag14.LANG_SUPP_CODE = 0; aECG->FLAG.HUFFMAN = 0; aECG->FLAG.DIFF = 0; aECG->FLAG.REF_BEAT = 0; aECG->FLAG.BIMODAL = 0; #if (BIOSIG_VERSION < 10500) aECG->Section8.NumberOfStatements = 0; aECG->Section8.Statements = NULL; aECG->Section11.NumberOfStatements = 0; aECG->Section11.Statements = NULL; #endif en1064.FLAG.HUFFMAN = 0; en1064.FLAG.DIFF = 0; en1064.FLAG.REF_BEAT = 0; en1064.FLAG.BIMODAL = 0; en1064.Section4.len_ms = 0; struct pointer_section section[_NUM_SECTION]; #ifndef WITHOUT_SCP_DECODE struct DATA_DECODE decode; struct DATA_RECORD record; struct DATA_INFO textual; bool AS_DECODE = 0; decode.length_BdR0 = NULL; decode.samples_BdR0= NULL; decode.length_Res = NULL; decode.samples_Res = NULL; decode.t_Huffman=NULL; decode.flag_Huffman=NULL; decode.data_lead=NULL; decode.data_protected=NULL; decode.data_subtraction=NULL; decode.length_BdR0=NULL; decode.samples_BdR0=NULL; decode.Median=NULL; decode.length_Res=NULL; decode.samples_Res=NULL; decode.Residual=NULL; decode.Reconstructed=NULL; //variables inizialization decode.flag_lead.number=0; decode.flag_lead.subtraction=0; decode.flag_lead.all_simultaneously=0; decode.flag_lead.number_simultaneously=0; decode.flag_BdR0.length=0; decode.flag_BdR0.fcM=0; decode.flag_BdR0.AVM=0; decode.flag_BdR0.STM=0; decode.flag_BdR0.number_samples=0; decode.flag_BdR0.encoding=0; decode.flag_Res.AVM=0; decode.flag_Res.STM=0; decode.flag_Res.number=0; decode.flag_Res.number_samples=0; decode.flag_Res.encoding=0; decode.flag_Res.bimodal=0; decode.flag_Res.decimation_factor=0; #endif ptr = hdr->AS.Header; hdr->NRec = 0; sectionStart = 6; PtrCurSect = ptr+sectionStart; /**** SECTION 0 ****/ len = leu32p(PtrCurSect+4); NSections = (len-16)/10; if (memcmp(ptr+16, "SCPECG\0\0", 8)) { fprintf(stderr,"Warning SOPEN (SCP): Bytes 11-16 of Section 0 do not contain SCPECG - this violates ISO/DIS 11073-91064 Section 5.3.2.\n" ); } section[0].ID = 0; section[0].length = len; section[0].index = 6+16; int K; for (K=1; K<_NUM_SECTION; K++) { section[K].ID = -1; section[K].length = 0; section[K].index = 0; } for (K = 1; K < NSections; K++) { // this is needed because fields are not always sorted curSect = leu32p(ptr+6+16+K*10); len = leu32p(ptr+6+16+K*10+2); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): #%d section %d/%d %d %d\n",__FILE__,__LINE__,K,curSect,NSections,leu32p(ptr+6+16+K*10+2),leu32p(ptr+6+16+K*10+6)-1); if (curSect < _NUM_SECTION) { if (section[curSect].ID >= 0) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "SCP Section must not be defined twice"); return -1; } section[curSect].ID = curSect; section[curSect].length = len; section[curSect].index = leu32p(ptr+6+16+K*10+6)-1; } else if (len > 0) fprintf(stderr,"Warning SOPEN (SCP) : vendor specific section %d is not supported\n",curSect); } if (section[1].length) { /**** identify language support code - scan through section 1 for tag 14, byte 17 ****/ K = 1; curSect = section[K].ID; len = section[K].length; sectionStart = section[K].index; PtrCurSect = ptr+sectionStart; crc = leu16p(PtrCurSect); /* uint16_t tmpcrc = CRCEvaluate((uint8_t*)(PtrCurSect+2),len-2); uint8_t versionSection = *(ptr+sectionStart+8); uint8_t versionProtocol = *(ptr+sectionStart+9); */ // future versions might not need to do this, because language encoding is fixed (i.e. known). uint32_t len1; curSectPos = 16; while (curSectPos<=len) { tag = *(PtrCurSect+curSectPos); len1 = leu16p(PtrCurSect+curSectPos+1); curSectPos += 3; if (curSectPos+len1 > len) break; if (tag==14) { aECG->Section1.Tag14.LANG_SUPP_CODE = *(PtrCurSect+curSectPos+16); // tag 14, byte 16 (LANG_SUPP_CODE has to be 0x00 => Ascii only, if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) Language Support Code is 0x%02x\n",__FILE__,__LINE__,aECG->Section1.Tag14.LANG_SUPP_CODE); break; } curSectPos += len1; } } for (K=1; K<_NUM_SECTION; K++) { curSect = section[K].ID; len = section[K].length; sectionStart = section[K].index; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): SCP Section %i %i len=%i secStart=%i HeaderLength=%i\n",__FILE__,__LINE__,K,curSect,len,(int)sectionStart,hdr->HeadLen); if (len==0) continue; /***** empty section *****/ if (sectionStart + len > hdr->HeadLen) { biosigERROR(hdr, B4C_INCOMPLETE_FILE, "%s (line %i): SOPEN(SCP-READ): File incomplete - Section length + start of section is more then total length of header"); break; } PtrCurSect = ptr+sectionStart; crc = leu16p(PtrCurSect); uint16_t tmpcrc = CRCEvaluate((uint8_t*)(PtrCurSect+2),len-2); uint8_t versionSection = *(ptr+sectionStart+8); uint8_t versionProtocol = *(ptr+sectionStart+9); #ifndef ANDROID if ((crc != 0xffff) && (crc != tmpcrc)) fprintf(stderr,"Warning SOPEN(SCP-READ): faulty CRC in section %i: crc=%x, %x\n" ,curSect,crc,tmpcrc); if (curSect != leu16p(PtrCurSect+2)) fprintf(stderr,"Warning SOPEN(SCP-READ): Current Section No does not match field in sections (%i %i)\n",curSect,leu16p(PtrCurSect+2)); if (len != leu32p(PtrCurSect+4)) fprintf(stderr,"Warning SOPEN(SCP-READ): length field in pointer section (%i) does not match length field in sections (%i %i)\n",K,len,leu32p(PtrCurSect+4)); if ((versionSection != 13) && (versionSection != 20) && (versionSection != (uint8_t)(hdr->Version*10))) fprintf(stderr,"Warning SOPEN(SCP-READ): Version of section %i is not 13 or 20 but %i. This is not tested.\n", curSect, versionSection); if ((versionProtocol != 13) && (versionProtocol != 20) && (versionProtocol != (uint8_t)(hdr->Version*10))) fprintf(stderr,"Warning SOPEN(SCP-READ): Version of Protocol is not 13 or 20 but %i. This is not tested.\n", versionProtocol); #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): SCP Section %i %i len=%i secStart=%i version=%i %i \n",__FILE__,__LINE__, K, curSect, len, (int)sectionStart,(int)versionSection, (int)versionProtocol); curSectPos = 16; /**** SECTION 0: POINTERS TO DATA AREAS IN THE RECORD ****/ if (curSect==0) { } /**** SECTION 1: HEADER INFORMATION - PATIENT DATA/ECG ACQUISITION DATA ****/ else if (curSect==1) { struct tm t0,t1; t0.tm_year = 0; t0.tm_mon = 0; t0.tm_mday = 0; t0.tm_hour = 0; t0.tm_min = 0; t0.tm_sec = 0; t0.tm_isdst= -1; // daylight savings time - unknown hdr->T0 = 0; hdr->Patient.Birthday = 0; uint32_t len1; while ((curSectPos<=len) && (*(PtrCurSect+curSectPos) < 255)) { tag = *(PtrCurSect+curSectPos); len1 = leu16p(PtrCurSect+curSectPos+1); if (VERBOSE_LEVEL > 7) fprintf(stdout,"SCP(r): Section 1 Tag %i Len %i <%s>\n",tag,len1, (char*)PtrCurSect+curSectPos); curSectPos += 3; if (curSectPos+len1 > len) { #ifndef ANDROID fprintf(stdout,"Warning SCP(read): section 1 corrupted (exceeds file length)\n"); #endif break; } if (tag==0) { // convert to UTF8 if (!hdr->FLAG.ANONYMOUS) { // Last name or entire name if no first name is provided decode_scp_text(hdr, len1, (char*)PtrCurSect+curSectPos, MAX_LENGTH_NAME, hdr->Patient.Name, versionSection); } } else if (tag==1) { if (!hdr->FLAG.ANONYMOUS) { // First name size_t len = strlen(hdr->Patient.Name); if (len+3 < MAX_LENGTH_NAME) { // unit separator ascii(31), 0x1f is used for separating name componentes strcat(hdr->Patient.Name,"\x1f"); len+=1; decode_scp_text(hdr, len1, (char*)PtrCurSect+curSectPos, MAX_LENGTH_NAME-len+1, hdr->Patient.Name+len, versionSection); } } } else if (tag==2) { #ifndef ANDROID if (len1 > MAX_LENGTH_PID) { fprintf(stdout,"Warning SCP(read): length of Patient Id (section1 tag2) exceeds %i>%i\n",len1,MAX_LENGTH_PID); } #endif // convert to UTF8 decode_scp_text(hdr, len1, (char*)PtrCurSect+curSectPos, MAX_LENGTH_PID, hdr->Patient.Id, versionSection); hdr->Patient.Id[MAX_LENGTH_PID] = 0; if (!strcmp(hdr->Patient.Id,"UNKNOWN")) hdr->Patient.Id[0] = 0; } else if (tag==3) { if (!hdr->FLAG.ANONYMOUS) { // Second last name size_t len = strlen(hdr->Patient.Name); if (len+2 < MAX_LENGTH_NAME) { // unit separator ascii(31), 0x1f is used for separating name componentes strcat(hdr->Patient.Name,"\x1f"); len+=1; decode_scp_text(hdr, len1, (char*)PtrCurSect+curSectPos, MAX_LENGTH_NAME-len+1, hdr->Patient.Name+len, versionSection); } } } else if (tag==4) { } else if (tag==5) { t1.tm_year = leu16p(PtrCurSect+curSectPos)-1900; t1.tm_mon = *(PtrCurSect+curSectPos+2)-1; t1.tm_mday = *(PtrCurSect+curSectPos+3); t1.tm_hour = 12; t1.tm_min = 0; t1.tm_sec = 0; t1.tm_isdst= -1; // daylight saving time: unknown // t1.tm_gmtoff = 0; hdr->Patient.Birthday = tm_time2gdf_time(&t1); } else if (tag==6) { hdr->Patient.Height = leu16p(PtrCurSect+curSectPos); } else if (tag==7) { hdr->Patient.Weight = leu16p(PtrCurSect+curSectPos); } else if (tag==8) { hdr->Patient.Sex = *(PtrCurSect+curSectPos); if (hdr->Patient.Sex>2) hdr->Patient.Sex = 0; } else if (tag==9) { } else if (tag==10) { // TODO: convert to UTF8 } else if (tag==11) { aECG->systolicBloodPressure = leu16p(PtrCurSect+curSectPos); } else if (tag==12) { aECG->diastolicBloodPressure = leu16p(PtrCurSect+curSectPos); } else if (tag==13) { // TODO: convert to UTF8 aECG->Diagnosis = (char*)(PtrCurSect+curSectPos); } else if (tag==14) { /* Acquiring Device ID Number */ // TODO: convert to UTF8 #ifndef ANDROID if (len1>85) fprintf(stderr,"Warning SCP(r): length of tag14 %i>40\n",len1); #endif memcpy(hdr->ID.Manufacturer._field,(char*)PtrCurSect+curSectPos,min(len1,MAX_LENGTH_MANUF)); hdr->ID.Manufacturer._field[min(len1,MAX_LENGTH_MANUF)] = 0; hdr->ID.Manufacturer.Model = hdr->ID.Manufacturer._field+8; hdr->ID.Manufacturer.Version = hdr->ID.Manufacturer._field+36; int tmp = strlen(hdr->ID.Manufacturer.Version)+1; hdr->ID.Manufacturer.SerialNumber = hdr->ID.Manufacturer.Version+tmp; tmp += strlen(hdr->ID.Manufacturer.Version+tmp)+1; // skip SW ID tmp += strlen(hdr->ID.Manufacturer.Version+tmp)+1; // skip SW tmp += strlen(hdr->ID.Manufacturer.Version+tmp)+1; // skip SW hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer.Version+tmp; /* might become obsolete */ //memcpy(hdr->aECG->Section1.tag14,PtrCurSect+curSectPos,40); //hdr->VERSION = *(PtrCurSect+curSectPos+14)/10.0; // tag 14, byte 15 aECG->Section1.Tag14.INST_NUMBER = leu16p(PtrCurSect+curSectPos); aECG->Section1.Tag14.DEPT_NUMBER = leu16p(PtrCurSect+curSectPos+2); aECG->Section1.Tag14.DEVICE_ID = leu16p(PtrCurSect+curSectPos+4); aECG->Section1.Tag14.DeviceType = *(PtrCurSect+curSectPos+ 6); aECG->Section1.Tag14.MANUF_CODE = *(PtrCurSect+curSectPos+ 7); // tag 14, byte 7 (MANUF_CODE has to be 255) const char *MANUFACTURER[] = { "unknown","Burdick","Cambridge", "Compumed","Datamed","Fukuda","Hewlett-Packard", "Marquette Electronics","Mortara Instruments", "Nihon Kohden","Okin","Quinton","Siemens","Spacelabs", "Telemed","Hellige","ESA-OTE","Schiller", "Picker-Schwarzer","et medical devices", "Zwönitz",NULL}; if (!strlen(hdr->ID.Manufacturer.Name)) { if (aECG->Section1.Tag14.MANUF_CODE < 21) hdr->ID.Manufacturer.Name = MANUFACTURER[aECG->Section1.Tag14.MANUF_CODE]; else fprintf(stderr,"Warning SOPEN(SCP): unknown manufacturer code\n"); } aECG->Section1.Tag14.MOD_DESC = (char*)(PtrCurSect+curSectPos+8); aECG->Section1.Tag14.VERSION = *(PtrCurSect+curSectPos+14); aECG->Section1.Tag14.PROT_COMP_LEVEL = *(PtrCurSect+curSectPos+15); // tag 14, byte 15 (PROT_COMP_LEVEL has to be 0xA0 => level II) aECG->Section1.Tag14.LANG_SUPP_CODE = *(PtrCurSect+curSectPos+16); // tag 14, byte 16 (LANG_SUPP_CODE has to be 0x00 => Ascii only, latin and 1-byte code) aECG->Section1.Tag14.ECG_CAP_DEV = *(PtrCurSect+curSectPos+17); // tag 14, byte 17 (ECG_CAP_DEV has to be 0xD0 => Acquire, (No Analysis), Print and Store) aECG->Section1.Tag14.MAINS_FREQ = *(PtrCurSect+curSectPos+18); // tag 14, byte 18 (MAINS_FREQ has to be 0: unspecified, 1: 50 Hz, 2: 60Hz) aECG->Section1.Tag14.ANAL_PROG_REV_NUM = (char*)(PtrCurSect+curSectPos+36); tmp = strlen((char*)(PtrCurSect+curSectPos+36)); aECG->Section1.Tag14.SERIAL_NUMBER_ACQ_DEV = (char*)(PtrCurSect+curSectPos+36+tmp+1); tmp += strlen((char*)(PtrCurSect+curSectPos+36+tmp+1)); aECG->Section1.Tag14.ACQ_DEV_SYS_SW_ID = (char*)(PtrCurSect+curSectPos+36+tmp+1); tmp += strlen((char*)(PtrCurSect+curSectPos+36+tmp+1)); aECG->Section1.Tag14.ACQ_DEV_SCP_SW = (char*)(PtrCurSect+curSectPos+36+tmp+1); // tag 14, byte 38 (SCP_IMPL_SW has to be "OpenECG XML-SCP 1.00") tmp += strlen((char*)(PtrCurSect+curSectPos+36+tmp+1)); aECG->Section1.Tag14.ACQ_DEV_MANUF = (char*)(PtrCurSect+curSectPos+36+tmp+1); // tag 14, byte 38 (ACQ_DEV_MANUF has to be "Manufacturer") if (aECG->Section1.Tag14.LANG_SUPP_CODE & 0xFE) { #if _ICONV_H fprintf(stdout, "Warning SCP-ECG: decoding of text strings not ready yet"); #else biosigERROR(hdr, B4C_CHAR_ENCODING_UNSUPPORTED, "SCP-SCP: Non-ASCII text string language - conversion not supported"); #endif } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): Version %i\n",__FILE__,__LINE__,aECG->Section1.Tag14.VERSION); } else if (tag==15) { /* Analyzing Device ID Number */ // TODO: convert to UTF8 //memcpy(hdr->aECG->Section1.tag15,PtrCurSect+curSectPos,40); aECG->Section1.Tag15.VERSION = *(PtrCurSect+curSectPos+14); } else if (tag==16) { /* Acquiring Institution Description */ size_t outlen = len1*2+1; hdr->ID.Hospital = malloc(outlen); if (hdr->ID.Hospital) { // convert to UTF8 decode_scp_text(hdr, len1, (char*)PtrCurSect+curSectPos, outlen, hdr->ID.Hospital, versionSection); hdr->ID.Hospital[outlen] = 0; } } else if (tag==17) { /* Analyzing Institution Description */ // TODO: convert to UTF8 } else if (tag==18) { /* Acquiring Institution Description */ // TODO: convert to UTF8 } else if (tag==19) { /* Analyzing Institution Description */ // TODO: convert to UTF8 } else if (tag==20) { // TODO: convert to UTF8 aECG->ReferringPhysician = (char*)(PtrCurSect+curSectPos); } else if (tag==21) { // TODO: convert to UTF8 aECG->MedicationDrugs = (char*)(PtrCurSect+curSectPos); } else if (tag==22) { size_t outlen = len1*2+1; hdr->ID.Technician = malloc(outlen); if (hdr->ID.Technician) { // convert to UTF8 decode_scp_text(hdr, len1, (char*)PtrCurSect+curSectPos, outlen, hdr->ID.Technician, versionSection); hdr->ID.Technician[outlen] = 0; } } else if (tag==23) { /* Room Description */ // TODO: convert to UTF8 } else if (tag==24) { aECG->EmergencyLevel = *(PtrCurSect+curSectPos); } else if (tag==25) { t0.tm_year = leu16p(PtrCurSect+curSectPos)-1900; t0.tm_mon = (*(PtrCurSect+curSectPos+2)) - 1; t0.tm_mday = *(PtrCurSect+curSectPos+3); } else if (tag==26) { t0.tm_hour = *(PtrCurSect+curSectPos); t0.tm_min = *(PtrCurSect+curSectPos+1); t0.tm_sec = *(PtrCurSect+curSectPos+2); } else if (tag==27) { HighPass = leu16p(PtrCurSect+curSectPos)/100.0; } else if (tag==28) { LowPass = leu16p(PtrCurSect+curSectPos); } else if (tag==29) { uint8_t bitmap = *(PtrCurSect+curSectPos); if (bitmap==0) Notch = NAN; // undefined else if ((bitmap & 0x03)==0) Notch = -1; // notch off else if (bitmap & 0x01) Notch = 60.0; // notch 60Hz else if (bitmap & 0x02) Notch = 50.0; // notch 50Hz } else if (tag==30) { /* Free Text Field */ // TODO: convert to UTF8 } else if (tag==31) { /* ECG Sequence Number */ // TODO: convert to UTF8 } else if (tag==32) { /* History Diagnostic Codes */ // TODO: convert to UTF8 if (PtrCurSect[curSectPos]==0) { unsigned k=1; for (; k < len1; k++) { if ((PtrCurSect[curSectPos+k] > 9) && (PtrCurSect[curSectPos+k] < 40)) hdr->Patient.Impairment.Heart = 2; else if (PtrCurSect[curSectPos+k]==1) hdr->Patient.Impairment.Heart = 1; else if (PtrCurSect[curSectPos+k]==42) { hdr->Patient.Impairment.Heart = 3; break; } } } } else if (tag==33) { /* Electrode Configuration Code */ // TODO: convert to UTF8 } else if (tag==34) { /* DateTimeZone */ // TODO: convert to UTF8 int16_t tzmin = lei16p(PtrCurSect+curSectPos); if (tzmin != 0x7fff) { if (abs(tzmin)<=780) hdr->tzmin = tzmin; else fprintf(stderr,"Warning SOPEN(SCP-READ): invalid time zone (Section 1, Tag34)\n"); } //fprintf(stdout,"SOPEN(SCP-READ): tzmin = %i %x \n",tzmin,tzmin); } else if (tag==35) { /* Free Text Medical History */ // TODO: convert to UTF8 } else { } curSectPos += len1; } hdr->T0 = tm_time2gdf_time(&t0); } /**** SECTION 2: HUFFMAN TABLES USED IN ENCODING OF ECG DATA (IF USED) ****/ else if (curSect==2) { aECG->FLAG.HUFFMAN = 1; en1064.FLAG.HUFFMAN = 1; NHT = leu16p(PtrCurSect+curSectPos); curSectPos += 2; if (VERBOSE_LEVEL > 7) fprintf(stdout,"SCP(r): Section 2 NHT=%d\n", NHT); if (NHT==19999) { en1064.FLAG.HUFFMAN = 1; Huffman = (huffman_t*)malloc(sizeof(huffman_t)); HTrees = (htree_t**)malloc(sizeof(htree_t*)); Huffman[0].NCT = 19; Huffman[0].Table = DefaultTable; HTrees [0] = makeTree(Huffman[0]); k2 = 0; #ifndef ANDROID if (VERBOSE_LEVEL==9) for (k1=0; k1NS = *(PtrCurSect+curSectPos); aECG->FLAG.REF_BEAT = (*(PtrCurSect+curSectPos+1) & 0x01); en1064.Section3.flags = *(PtrCurSect+curSectPos+1); if (aECG->FLAG.REF_BEAT && (aECG->Section1.Tag14.VERSION > 25)) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "REF-BEAT compression is invalid in SCP v3"); } if (aECG->FLAG.REF_BEAT && !section[4].length) { #ifndef ANDROID fprintf(stderr,"Warning (SCP): Reference Beat but no Section 4\n"); #endif aECG->FLAG.REF_BEAT = 0; } #ifndef ANDROID if (!(en1064.Section3.flags & 0x04) || ((en1064.Section3.flags>>3) != hdr->NS)) fprintf(stderr,"Warning (SCP): channels are not simultaneously recorded! %x %i\n",en1064.Section3.flags,hdr->NS); #endif curSectPos += 2; hdr->CHANNEL = (CHANNEL_TYPE *) realloc(hdr->CHANNEL,hdr->NS* sizeof(CHANNEL_TYPE)); en1064.Section3.lead = (typeof(en1064.Section3.lead))malloc(hdr->NS*sizeof(*en1064.Section3.lead)); uint32_t startindex0; startindex0 = leu32p(PtrCurSect+curSectPos); for (i = 0, hdr->SPR=1; i < hdr->NS; i++) { en1064.Section3.lead[i].start = leu32p(PtrCurSect+curSectPos); en1064.Section3.lead[i].end = leu32p(PtrCurSect+curSectPos+4); uint8_t LeadIdCode = *(PtrCurSect+curSectPos+8); if (LeadIdCode > 184) { // consider this as undefined LeadId LeadIdCode = 0; fprintf(stderr,"Warning (SCP): LeadId of channel %i is %i - which is unspecified\n",i+1, LeadIdCode); } hdr->CHANNEL[i].SPR = en1064.Section3.lead[i].end - en1064.Section3.lead[i].start + 1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): SCP Section %i #%i SPR=%d/%d [%d..%d]\n",__FILE__,__LINE__,curSect, i, hdr->CHANNEL[i].SPR, hdr->SPR, en1064.Section3.lead[i].end, en1064.Section3.lead[i].start ); hdr->SPR = lcm(hdr->SPR,hdr->CHANNEL[i].SPR); hdr->CHANNEL[i].LeadIdCode = LeadIdCode; hdr->CHANNEL[i].Label[0]= 0; hdr->CHANNEL[i].Transducer[0]= 0; hdr->CHANNEL[i].LowPass = LowPass; hdr->CHANNEL[i].HighPass= HighPass; hdr->CHANNEL[i].Notch = Notch; curSectPos += 9; #ifndef ANDROID if (en1064.Section3.lead[i].start != startindex0) fprintf(stderr,"Warning SCP(read): starting sample %i of #%i differ to %x in #1\n",en1064.Section3.lead[i].start,*(PtrCurSect+curSectPos+8),startindex0); #endif } } /**** SECTION 4: QRS LOCATIONS (IF REFERENCE BEATS ARE ENCODED) ****/ else if (curSect==4) { if (aECG->Section1.Tag14.VERSION > 25) biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Section 4 must not be used in SCP v3"); en1064.Section4.len_ms = leu16p(PtrCurSect+curSectPos); // ### TODO: SCPECGv3 ### en1064.Section4.fiducial_sample = leu16p(PtrCurSect+curSectPos+2); // ### TODO: SCPECGv3 ### en1064.Section4.N = leu16p(PtrCurSect+curSectPos+4); // ### TODO: SCPECGv3 ### en1064.Section4.SPR = hdr->SPR/4; en1064.Section4.beat = (typeof(en1064.Section4.beat))malloc(en1064.Section4.N*sizeof(*en1064.Section4.beat)); curSectPos += 6; for (i=0; i < en1064.Section4.N; i++) { en1064.Section4.beat[i].btyp = leu16p(PtrCurSect+curSectPos); en1064.Section4.beat[i].SB = leu32p(PtrCurSect+curSectPos+2); en1064.Section4.beat[i].fcM = leu32p(PtrCurSect+curSectPos+6); en1064.Section4.beat[i].SE = leu32p(PtrCurSect+curSectPos+10); curSectPos += 14; } for (i=0; i < en1064.Section4.N; i++) { en1064.Section4.beat[i].QB = leu32p(PtrCurSect+curSectPos); en1064.Section4.beat[i].QE = leu32p(PtrCurSect+curSectPos+4); curSectPos += 8; en1064.Section4.SPR += en1064.Section4.beat[i].QE-en1064.Section4.beat[i].QB-1; } if (en1064.Section4.len_ms==0) { aECG->FLAG.REF_BEAT = 0; } } /**** SECTION 5: ENCODED REFERENCE BEAT DATA IF REFERENCE BEATS ARE STORED ****/ else if (curSect==5) { Cal5 = leu16p(PtrCurSect+curSectPos); en1064.Section5.AVM = leu16p(PtrCurSect+curSectPos); en1064.Section5.dT_us = leu16p(PtrCurSect+curSectPos+2); en1064.Section5.DIFF = *(PtrCurSect+curSectPos+4); en1064.Section5.Length = (1000L * en1064.Section4.len_ms) / en1064.Section5.dT_us; // hdr->SPR; en1064.Section5.inlen = (typeof(en1064.Section5.inlen))malloc(hdr->NS*2); for (i=0; i < hdr->NS; i++) { en1064.Section5.inlen[i] = leu16p(PtrCurSect+curSectPos+6+2*i); // ### TODO: SCPECGv3 ### if (!section[4].length && (en1064.Section5.Length < en1064.Section5.inlen[i])) en1064.Section5.Length = en1064.Section5.inlen[i]; } if (!section[4].length && en1064.FLAG.HUFFMAN) { en1064.Section5.Length *= 5; // decompressed data might need more space #ifndef ANDROID fprintf(stderr,"Warning SCPOPEN: Section 4 not defined - size of Sec5 can be only guessed (%i allocated)\n",(int)en1064.Section5.Length); #endif } en1064.Section5.datablock = NULL; if (aECG->FLAG.REF_BEAT) { en1064.Section5.datablock = (int32_t*)malloc(4 * hdr->NS * en1064.Section5.Length); Ptr2datablock = (PtrCurSect+curSectPos+6+2*hdr->NS); for (i=0; i < hdr->NS; i++) { en1064.Section5.inlen[i] = leu16p(PtrCurSect+curSectPos+6+2*i); // ### TODO: SCPECGv3 ### if (en1064.FLAG.HUFFMAN) { if (DecodeHuffman(HTrees, Huffman, Ptr2datablock, en1064.Section5.inlen[i], en1064.Section5.datablock + en1064.Section5.Length*i, en1064.Section5.Length)) { biosigERROR(hdr, B4C_DECOMPRESSION_FAILED, "Empty node in Huffman table! Do not know what to do !"); } if (hdr->AS.B4C_ERRNUM) { deallocEN1064(en1064); return(-1); } } else { for (k1=0; k1NS; k1++) for (ix = k1*en1064.Section5.Length+1; ix < (k1+1)*en1064.Section5.Length; ix++) data[ix] += data[ix-1]; else if (en1064.Section5.DIFF==2) for (k1 = 0; k1 < hdr->NS; k1++) for (ix = k1*en1064.Section5.Length+2; ix < (k1+1)*en1064.Section5.Length; ix++) data[ix] += 2*data[ix-1] - data[ix-2]; } } /**** SECTION 6 ****/ else if ((curSect==6) && (section[12].length==0)) { // Read Section6 only if no Section 12 is available hdr->NRec = 1; uint8_t FLAG_HUFFMAN = 0; uint16_t gdftyp = 5; // int32: internal raw data type hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata,4 * hdr->NS * hdr->SPR * hdr->NRec); data = (int32_t*)hdr->AS.rawdata; en1064.Section6.AVM = leu16p(PtrCurSect+curSectPos); en1064.Section6.dT_us = leu16p(PtrCurSect+curSectPos+2); hdr->SampleRate = 1e6/en1064.Section6.dT_us; en1064.Section6.DIFF = *(PtrCurSect+curSectPos+4); en1064.FLAG.DIFF = *(PtrCurSect+curSectPos+4); if (hdr->VERSION < 3.0) { en1064.Section6.BIMODAL = *(PtrCurSect+curSectPos+5); en1064.FLAG.BIMODAL = *(PtrCurSect+curSectPos+5); aECG->FLAG.BIMODAL = *(PtrCurSect+curSectPos+5); } else { en1064.Section6.BIMODAL = 0; en1064.FLAG.BIMODAL = 0; aECG->FLAG.BIMODAL = 0; FLAG_HUFFMAN = *(PtrCurSect+curSectPos+5); } Cal6 = leu16p(PtrCurSect+curSectPos); en1064.Section6.dT_us = leu16p(PtrCurSect+curSectPos+2); aECG->FLAG.DIFF = *(PtrCurSect+curSectPos+4); if (VERBOSE_LEVEL>7) fprintf(stdout, "%s (line %i) Compression(Diff=%i Huffman=%i RefBeat=%i Bimodal=%i)\n", __func__, __LINE__, aECG->FLAG.DIFF, aECG->FLAG.HUFFMAN, aECG->FLAG.REF_BEAT, aECG->FLAG.BIMODAL); if ((section[5].length>4) && en1064.Section5.dT_us) dT_us = en1064.Section5.dT_us; else dT_us = en1064.Section6.dT_us; hdr->SampleRate = 1e6/dT_us; typeof(hdr->SPR) SPR = ( en1064.FLAG.BIMODAL ? en1064.Section4.SPR : hdr->SPR); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i\n", __func__ ,__LINE__, dT_us, Cal5, Cal6); if ((Cal5==0) && (Cal6 >0)) Cal0 = Cal6; else if ((Cal5 >0) && (Cal6==0)) Cal0 = Cal5; else if ((Cal5 >0) && (Cal6 >0)) Cal0 = gcd(Cal5,Cal6); else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "SCP with invalid AVM data !"); return(-1); } uint16_t cal5 = Cal5/Cal0; uint16_t cal6 = Cal6/Cal0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i %i %i\n",__func__,__LINE__,dT_us,Cal5,Cal6); Ptr2datablock = (PtrCurSect+curSectPos + 6 + hdr->NS*2); // pointer for huffman decoder len = 0; size_t ix; hdr->AS.bpb = hdr->NS * hdr->SPR*GDFTYP_BITS[gdftyp]>>3; for (i=0; i < hdr->NS; i++) { if (VERBOSE_LEVEL>7) fprintf(stdout,"sec6-%i\n",i); CHANNEL_TYPE *hc = hdr->CHANNEL+i; hc->SPR = hdr->SPR; hc->PhysDimCode = 4275; // PhysDimCode("uV") physical unit "uV" hc->Cal = Cal0 * 1e-3; hc->Off = 0; hc->OnOff = 1; // 1: ON 0:OFF hc->GDFTYP = gdftyp; #ifndef NO_BI hc->bi = i*hdr->SPR*GDFTYP_BITS[gdftyp]>>3; #endif // ### TODO: these values should represent the true saturation values ### // hc->DigMax = ldexp(1.0,20)-1; hc->DigMin = ldexp(-1.0,20); hc->PhysMax = hc->DigMax * hc->Cal; hc->PhysMin = hc->DigMin * hc->Cal; uint16_t inlen = leu16p(PtrCurSect+curSectPos+6+2*i); // ### TODO: SCPECGv3 ### if (en1064.FLAG.HUFFMAN) { if (DecodeHuffman(HTrees, Huffman, Ptr2datablock, inlen, data + i*hdr->SPR, hdr->SPR)) { biosigERROR(hdr, B4C_DECOMPRESSION_FAILED, "Empty node in Huffman table! Do not know what to do !"); } if (hdr->AS.B4C_ERRNUM) { deallocEN1064(en1064); return(-1); } } else { for (k1=0, ix = i*hdr->SPR; k1 < SPR; k1++) data[ix+k1] = lei16p(Ptr2datablock + 2*k1); } len += inlen; Ptr2datablock += inlen; if (aECG->FLAG.DIFF==1) { for (ix = i*hdr->SPR+1; ix < i*hdr->SPR + SPR; ix++) data[ix] += data[ix-1]; } else if (aECG->FLAG.DIFF==2) { for (ix = i*hdr->SPR+2; ix < i*hdr->SPR + SPR; ix++) data[ix] += 2*data[ix-1] - data[ix-2]; } #ifndef WITHOUT_SCP_DECODE if (aECG->FLAG.BIMODAL || aECG->FLAG.REF_BEAT) { // if (aECG->FLAG.BIMODAL) { // if (aECG->FLAG.REF_BEAT { /* this is experimental work Bimodal and RefBeat decompression are under development. "continue" ignores code below AS_DECODE=1 will call later SCP-DECODE instead */ AS_DECODE = 1; continue; } #endif if (aECG->FLAG.BIMODAL) { // ### FIXME ### ix = i*hdr->SPR; // memory offset k1 = en1064.Section4.SPR; // SPR of decimated data k2 = hdr->SPR; // SPR of sample data uint32_t k3 = en1064.Section4.N-1; // # of protected zones uint8_t k4 = 4; // decimation factor do { --k2; data[ix + k2] = data[ix + k1 - 1]; if (k2 > en1064.Section4.beat[k3].QE) { // outside protected zone if (--k4==0) {k4=4; --k1; }; } else { // inside protected zone --k1; if (k20)); } if (aECG->FLAG.REF_BEAT) { /* Add reference beats */ // ### FIXME ### for (k1 = 0; k1 < en1064.Section4.N; k1++) { if (en1064.Section4.beat[k1].btyp == 0) for (ix = 0; ix < en1064.Section5.Length; ix++) { uint32_t ix1 = en1064.Section4.beat[k1].SB - en1064.Section4.beat[k1].fcM + ix; uint32_t ix2 = i*hdr->SPR + ix1; if ((en1064.Section4.beat[k1].btyp==0) && (ix1 < hdr->SPR)) data[ix2] = data[ix2] * cal6 + en1064.Section5.datablock[i*en1064.Section5.Length+ix] * cal5; } } } } en1064.Section6.datablock = data; curSectPos += 6 + 2*hdr->NS + len; if (VERBOSE_LEVEL>8) fprintf(stdout,"end sec6\n"); } /**** SECTION 7 ****/ else if (curSect==7) { #if (BIOSIG_VERSION >= 10500) hdr->SCP.Section7Length = leu32p(PtrCurSect+4)-curSectPos; hdr->SCP.Section7 = PtrCurSect+curSectPos; #endif uint16_t N_QRS = *(uint8_t*)(PtrCurSect+curSectPos)-1; uint8_t N_PaceMaker = *(uint8_t*)(PtrCurSect+curSectPos+1); // uint16_t RRI = leu16p(PtrCurSect+curSectPos+2); // uint16_t PPI = leu16p(PtrCurSect+curSectPos+4); curSectPos += 6; //size_t curSectPos0 = curSectPos; // backup of pointer // skip data on QRS measurements /* // ### FIXME ### It seems that the P,QRS, and T wave events can not be reconstructed because they refer to the reference beat and not to the overall signal data. Maybe Section 4 information need to be used. However, EN1064 does not mention this. hdr->EVENT.POS = (uint32_t*)realloc(hdr->EVENT.POS, (hdr->EVENT.N+5*N_QRS+N_PaceMaker)*sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*)realloc(hdr->EVENT.TYP, (hdr->EVENT.N+5*N_QRS+N_PaceMaker)*sizeof(*hdr->EVENT.TYP)); hdr->EVENT.DUR = (uint32_t*)realloc(hdr->EVENT.DUR, (hdr->EVENT.N+5*N_QRS+N_PaceMaker)*sizeof(*hdr->EVENT.DUR)); hdr->EVENT.CHN = (uint16_t*)realloc(hdr->EVENT.CHN, (hdr->EVENT.N+5*N_QRS+N_PaceMaker)*sizeof(*hdr->EVENT.CHN)); for (i=0; i < 5*N_QRS; i++) { hdr->EVENT.DUR[hdr->EVENT.N+i] = 0; hdr->EVENT.CHN[hdr->EVENT.N+i] = 0; } for (i=0; i < 5*N_QRS; i+=5) { uint8_t typ = *(PtrCurSect+curSectPos+i); hdr->EVENT.TYP[hdr->EVENT.N] = 0x0502; hdr->EVENT.TYP[hdr->EVENT.N+1] = 0x8502; hdr->EVENT.TYP[hdr->EVENT.N+2] = 0x0503; hdr->EVENT.TYP[hdr->EVENT.N+3] = 0x8503; hdr->EVENT.TYP[hdr->EVENT.N+4] = 0x8506; hdr->EVENT.POS[hdr->EVENT.N] = leu16p(PtrCurSect+curSectPos0); hdr->EVENT.POS[hdr->EVENT.N+1] = leu16p(PtrCurSect+curSectPos0+2); hdr->EVENT.POS[hdr->EVENT.N+2] = leu16p(PtrCurSect+curSectPos0+4); hdr->EVENT.POS[hdr->EVENT.N+3] = leu16p(PtrCurSect+curSectPos0+6); hdr->EVENT.POS[hdr->EVENT.N+4] = leu16p(PtrCurSect+curSectPos0+8); hdr->EVENT.N+= 5; curSectPos0 += 16; } */ curSectPos += N_QRS*16; // pace maker information is stored in sparse sampling channel if (N_PaceMaker>0) { hdr->EVENT.POS = (uint32_t*)realloc(hdr->EVENT.POS, (hdr->EVENT.N+N_PaceMaker)*sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*)realloc(hdr->EVENT.TYP, (hdr->EVENT.N+N_PaceMaker)*sizeof(*hdr->EVENT.TYP)); hdr->EVENT.DUR = (uint32_t*)realloc(hdr->EVENT.DUR, (hdr->EVENT.N+N_PaceMaker)*sizeof(*hdr->EVENT.DUR)); hdr->EVENT.CHN = (uint16_t*)realloc(hdr->EVENT.CHN, (hdr->EVENT.N+N_PaceMaker)*sizeof(*hdr->EVENT.CHN)); /* add pacemaker channel */ hdr->CHANNEL = (CHANNEL_TYPE *) realloc(hdr->CHANNEL,(++hdr->NS)*sizeof(CHANNEL_TYPE)); i = hdr->NS; CHANNEL_TYPE *hc = hdr->CHANNEL+i; hc->SPR = 0; // sparse event channel hc->PhysDimCode = 4275; // PhysDimCode("uV") physical unit "uV" hc->Cal = 1; hc->Off = 0; hc->OnOff = 1; // 1: ON 0:OFF strcpy(hc->Transducer,"Pacemaker"); hc->GDFTYP = 3; // ### these values should represent the true saturation values ###// hc->DigMax = ldexp(1.0,15)-1; hc->DigMin = ldexp(-1.0,15); hc->PhysMax = hc->DigMax * hc->Cal; hc->PhysMin = hc->DigMin * hc->Cal; } // skip pacemaker spike measurements for (i=0; i < N_PaceMaker; i++) { ++hdr->EVENT.N; hdr->EVENT.TYP[hdr->EVENT.N] = 0x7fff; hdr->EVENT.CHN[hdr->EVENT.N] = hdr->NS; hdr->EVENT.POS[hdr->EVENT.N] = (uint32_t)(leu16p(PtrCurSect+curSectPos)*hdr->SampleRate*1e-3); hdr->EVENT.DUR[hdr->EVENT.N] = leu16p(PtrCurSect+curSectPos+2); curSectPos += 4; } // skip pacemaker spike information section curSectPos += N_PaceMaker*6; // QRS type information N_QRS = leu16p(PtrCurSect+curSectPos); curSectPos += 2; } /**** SECTION 8 ****/ else if (curSect==8) { // TODO: convert to UTF8 #if (BIOSIG_VERSION >= 10500) hdr->SCP.Section8Length = leu32p(PtrCurSect+4)-curSectPos; hdr->SCP.Section8 = PtrCurSect+curSectPos; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %p %d %d %d\n", __func__, __LINE__, hdr->AS.Header, hdr->SCP.Section8Length, (int)curSectPos, (int)(hdr->SCP.Section8-hdr->AS.Header)); #else aECG->Section8.Confirmed = *(char*)(PtrCurSect+curSectPos); aECG->Section8.t.tm_year = leu16p(PtrCurSect+curSectPos+1)-1900; aECG->Section8.t.tm_mon = *(uint8_t*)(PtrCurSect+curSectPos+3)-1; aECG->Section8.t.tm_mday = *(uint8_t*)(PtrCurSect+curSectPos+4); aECG->Section8.t.tm_hour = *(uint8_t*)(PtrCurSect+curSectPos+5); aECG->Section8.t.tm_min = *(uint8_t*)(PtrCurSect+curSectPos+6); aECG->Section8.t.tm_sec = *(uint8_t*)(PtrCurSect+curSectPos+7); aECG->Section8.NumberOfStatements = *(uint8_t*)(PtrCurSect+curSectPos+8); aECG->Section8.Statements= (char**)malloc(aECG->Section8.NumberOfStatements*sizeof(char*)); curSectPos += 9; uint8_t k=0; for (; kSection8.NumberOfStatements;k++) { if (curSectPos+3 > len) break; aECG->Section8.Statements[k] = (char*)(PtrCurSect+curSectPos+3); curSectPos += 3+leu16p(PtrCurSect+curSectPos+1); } #endif } /**** SECTION 9 ****/ else if (curSect==9) { // TODO: convert to UTF8 #if (BIOSIG_VERSION >= 10500) // hdr->SCP.Section9Length = leu32p(PtrCurSect+4)-curSectPos; // hdr->SCP.Section9 = PtrCurSect+curSectPos; #else aECG->Section9.StartPtr = (char*)(PtrCurSect+curSectPos); aECG->Section9.Length = len; #endif } /**** SECTION 10 ****/ else if (curSect==10) { #if (BIOSIG_VERSION >= 10500) hdr->SCP.Section10Length = leu32p(PtrCurSect+4)-curSectPos; hdr->SCP.Section10 = PtrCurSect+curSectPos; #endif } /**** SECTION 11 ****/ else if (curSect==11) { // TODO: convert to UTF8 if(len= 10500) /* hdr->SCP.Section11 = realloc(hdr->SCP.Section11, len); memcpy(hdr->SCP.Section11, PtrCurSect+curSectPos, len); */ hdr->SCP.Section11Length = leu32p(PtrCurSect+4)-curSectPos; hdr->SCP.Section11 = PtrCurSect+curSectPos; #else aECG->Section11.Confirmed = *(char*)(PtrCurSect+curSectPos); aECG->Section11.t.tm_year = leu16p(PtrCurSect+curSectPos+1)-1900; aECG->Section11.t.tm_mon = *(uint8_t*)(PtrCurSect+curSectPos+3)-1; aECG->Section11.t.tm_mday = *(uint8_t*)(PtrCurSect+curSectPos+4); aECG->Section11.t.tm_hour = *(uint8_t*)(PtrCurSect+curSectPos+5); aECG->Section11.t.tm_min = *(uint8_t*)(PtrCurSect+curSectPos+6); aECG->Section11.t.tm_sec = *(uint8_t*)(PtrCurSect+curSectPos+7); aECG->Section11.NumberOfStatements = *(uint8_t*)(PtrCurSect+curSectPos+8); aECG->Section11.Statements= (char**)malloc(aECG->Section11.NumberOfStatements*sizeof(char*)); curSectPos += 9; uint8_t k=0; for (; kSection11.NumberOfStatements;k++) { if (curSectPos+4 > len) break; aECG->Section11.Statements[k] = (char*)(PtrCurSect+curSectPos+4); curSectPos += 3+leu16p(PtrCurSect+curSectPos+1); } #endif } #if defined(WITH_SCP3) /**** SECTION 12 ****/ else if ( (curSect==12) && (versionSection > 25) && (versionProtocol > 25) && (len > 70) ) { uint32_t sec12_LN = leu32p(PtrCurSect+curSectPos+62); uint32_t sec12_LMI= leu32p(PtrCurSect+curSectPos+66); uint32_t sec12_Len1 = 70+sec12_LN+sec12_LMI; uint8_t sec12_FRST = *(PtrCurSect+curSectPos+16); // TODO: get rid of this field, no benefit uint8_t sec12_FBMP = *(PtrCurSect+curSectPos+31); uint16_t gdftyp = 0; uint8_t bps = *(uint8_t*)(PtrCurSect+curSectPos+9); double DigMin = -1.0/0.0; double DigMax = +1.0/0.0; switch (bps) { case 1: gdftyp = 1; break; case 2: gdftyp = 3; break; case 3: gdftyp = 255+24; break; case 4: gdftyp = 5; break; default: biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "invalid number of bytes per samplein SCP3:Section12"); } DigMin = -ldexp(1.0,bps-1); DigMax = ldexp(1.0,bps-1)-1.0; // TODO: why is this needed, why is Section 1 not good enough ? struct tm t0; t0.tm_year = leu16p(PtrCurSect+curSectPos+10)-1900; t0.tm_mon = (*(PtrCurSect+curSectPos+12)) - 1; t0.tm_mday = *(PtrCurSect+curSectPos+13); t0.tm_hour = *(PtrCurSect+curSectPos+14); t0.tm_min = *(PtrCurSect+curSectPos+15); t0.tm_sec = *(PtrCurSect+curSectPos+16); hdr->T0 = tm_time2gdf_time(&t0); hdr->SampleRate = leu32p(PtrCurSect+curSectPos); hdr->NS = *(uint8_t*)(PtrCurSect+curSectPos+4); hdr->NRec = leu32p(PtrCurSect+curSectPos+5); hdr->SPR = 1; // multiplexed hdr->AS.bpb = bps*hdr->NS; hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata,4 * hdr->NS * hdr->SPR * hdr->NRec); data = (int32_t*)hdr->AS.rawdata; /* Leads Definition Block */ hdr->CHANNEL = (CHANNEL_TYPE *) realloc(hdr->CHANNEL,hdr->NS* sizeof(CHANNEL_TYPE)); for (i = 0; i < hdr->NS; i++) { CHANNEL_TYPE *hc = hdr->CHANNEL+i; uint8_t LeadIdCode = *(PtrCurSect+curSectPos+sec12_Len1+i*4); if (LeadIdCode > 184) { // consider this as undefined LeadId LeadIdCode = 0; fprintf(stderr,"Warning (SCP): LeadId of channel %i is %i - which is unspecified\n",i+1, LeadIdCode); } hc->bi = bps*i; hc->bi8 = (bps*i)<<3; hc->SPR = 1; hc->LeadIdCode = LeadIdCode; hc->Label[0] = 0; hc->Transducer[0] = 0; hc->OnOff = 1; hc->Impedance = 0.0/0.0; hc->GDFTYP = gdftyp; hc->DigMin = DigMin; hc->DigMax = DigMax; hc->Off = 0.0; hc->Cal = leu16p(PtrCurSect+curSectPos+sec12_Len1+i*4+1)*1e-3; hc->PhysDimCode = 4275; // PhysDimCode("uV") physical unit "uV" hc->PhysMin = DigMin*hc->Cal; hc->PhysMax = DigMax*hc->Cal; if (sec12_FRST) { hc->LowPass = leu16p(PtrCurSect+curSectPos+29); hc->HighPass = leu16p(PtrCurSect+curSectPos+27); hc->Notch = ((sec12_FBMP==0) ? 60 : ((sec12_FBMP==1) ? 50 : NAN)); } else { // From Section 1 tags 27-28 hc->LowPass = LowPass; hc->HighPass = HighPass; hc->Notch = Notch; } } /* size_t sz = GDFTYP_BITS[gdftyp] * hdr->NS * hdr->SPR * hdr->NRec / 8; hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata, sz); memcpy(hdr->AS.rawdata, PtrCurSect+curSectPos+sec12_Len1+hdr->NS*4, sz); */ hdr->AS.rawdata = PtrCurSect+curSectPos+sec12_Len1+hdr->NS*4; hdr->AS.first = 0; hdr->AS.length = hdr->SPR*hdr->NRec; } /**** SECTION 13 ****/ else if (curSect==13) { } /**** SECTION 14 ****/ else if (curSect==14) { } /**** SECTION 15 ****/ else if (curSect==15) { } /**** SECTION 16 ****/ else if (curSect==16) { } /**** SECTION 17 ****/ else if (curSect==17) { } /**** SECTION 18 ****/ else if (curSect==18) { } #endif else { } } /* free allocated memory */ deallocEN1064(en1064); return 0; #ifndef WITHOUT_SCP_DECODE if (AS_DECODE==0) return(0); /* --------------------------------------------------------------------------- Copyright (C) 2006 Eugenio Cervesato. Developed at the Associazione per la Ricerca in Cardiologia - Pordenone - Italy, This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------------- */ /* Fall back method: + implements Huffman, reference beat and Bimodal compression. - uses piece-wise file access - defines intermediate data structure */ #ifndef ANDROID if (VERBOSE_LEVEL > 7) fprintf(stdout, "\nUse SCP_DECODE (Diff=%i Huffman=%i RefBeat=%i Bimodal=%i)\n", aECG->FLAG.DIFF, aECG->FLAG.HUFFMAN, aECG->FLAG.REF_BEAT, aECG->FLAG.BIMODAL); #endif textual.des.acquiring.protocol_revision_number = aECG->Section1.Tag14.VERSION; textual.des.analyzing.protocol_revision_number = aECG->Section1.Tag15.VERSION; decode.flag_Res.bimodal = (aECG->Section1.Tag14.VERSION > 10 ? aECG->FLAG.BIMODAL : 0); decode.Reconstructed = (int32_t*) hdr->AS.rawdata; // TODO: check error handling biosigERROR(hdr, 0, NULL); if (scp_decode(hdr, section, &decode, &record, &textual, add_filter)) { if (Cal0>1) for (i=0; i < hdr->NS * hdr->SPR * hdr->NRec; ++i) data[i] /= Cal0; } else { biosigERROR(hdr, B4C_CANNOT_OPEN_FILE, "SCP-DECODE can not read file"); return(0); } // end of fall back method decode.Reconstructed = NULL; sopen_SCP_clean(&decode, &record, &textual); return(1); #endif }; #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/t210/structures.h0000664000175000017500000002017314752215315015735 /* --------------------------------------------------------------------------- Copyright (C) 2014 Alois Schloegl Copyright (C) 2003 Eugenio Cervesato & Giorgio De Odorico. Developed at the Associazione per la Ricerca in Cardiologia - Pordenone - Italy. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------------- */ // structures.h header file #ifndef __STRUCTURES_H__ #define __STRUCTURES_H__ #include /* // obsolete definition #define int_S int8_t #define int_M int16_t #define int_L int32_t #define U_int_S uint8_t #define U_int_M uint16_t #define U_int_L uint32_t #define dec_S float #define dec_M double #define dec_L long double */ #define str char #define bool char #define true 1 #define false 0 #define TRUE 1 #define FALSE 0 struct alfabetic { uint16_t number; const char *sentence; }; struct numeric { uint16_t value; uint8_t unit; }; struct section_header { uint16_t CRC; uint16_t ID; uint32_t length; uint8_t version; uint8_t protocol_version; char *word; }; struct file_header { uint16_t CRC; uint32_t length; }; struct pointer_section { uint32_t index; int16_t ID; uint32_t length; }; struct device_info { uint16_t institution_number; uint16_t department_number; uint16_t ID; uint8_t type; uint8_t manifacturer; char *model_description; uint8_t protocol_revision_number; uint8_t category; uint8_t language; uint8_t capability[4]; uint8_t AC; char *analysing_program_revision_number; char *serial_number_device; char *device_system_software; char *device_SCP_implementation_software; char *manifacturer_trade_name; }; struct info_drug { uint8_t table; uint8_t classes; uint8_t drug_code; uint16_t length; }; struct Time_Zone { int16_t offset; uint16_t index; const char *description; }; struct demographic { char *first_name; char *last_name; char *ID; char *second_last_name; struct numeric age; time_t date_birth2; // by E.C. feb 2006 struct numeric height; struct numeric weight; uint8_t sex; uint8_t race; uint16_t systolic_pressure; uint16_t diastolic_pressure; }; struct clinic { uint16_t number_drug; struct info_drug *drug; char *text_drug; uint16_t number_diagnose; struct numeric *diagnose; char *text_diagnose; char *referring_physician; char *latest_confirming_physician; char *technician_description; uint16_t number_text; struct numeric *free_text; char *text_free_text; uint16_t number_hystory; struct numeric *medical_hystory; uint16_t number_free_hystory; struct numeric *free_medical_hystory; char *text_free_medical_hystory; }; struct descriptive { struct device_info acquiring; struct device_info analyzing; char *acquiring_institution; char *analyzing_institution; char *acquiring_department; char *analyzing_department; char *room; uint8_t stat_code; }; struct device { time_t date_acquisition2; // by E.C. feb 2006 time_t time_acquisition2; // by E.C. feb 2006 uint16_t baseline_filter; uint16_t lowpass_filter; uint8_t other_filter[4]; char *sequence_number; struct numeric electrode_configuration; struct Time_Zone TZ; }; struct table_H { uint8_t bit_prefix; uint8_t bit_code; uint8_t TMS; int16_t base_value; uint32_t base_code; }; struct f_lead { uint8_t number; bool subtraction; bool all_simultaneously; uint8_t number_simultaneously; }; struct lead { uint8_t ID; uint32_t start; uint32_t end; }; struct Subtraction_Zone { uint16_t beat_type; uint32_t SB; uint32_t fc; uint32_t SE; }; struct Protected_Area { uint32_t QB; uint32_t QE; }; struct f_BdR0 { uint16_t length; uint16_t fcM; uint16_t AVM; uint16_t STM; uint16_t number_samples; uint8_t encoding; }; struct f_Res { uint16_t AVM; uint16_t STM; uint16_t number; uint16_t number_samples; uint8_t encoding; bool bimodal; uint8_t decimation_factor; }; struct spike { uint16_t time; int16_t amplitude; uint8_t type; uint8_t source; uint8_t index; uint16_t pulse_width; }; struct global_measurement { uint8_t number; uint16_t number_QRS; uint8_t number_spike; uint16_t average_RR; uint16_t average_PP; uint16_t ventricular_rate; uint16_t atrial_rate; uint16_t QT_corrected; uint8_t formula_type; uint16_t number_tag; }; struct additional_measurement { uint8_t ID; uint8_t byte[5]; }; struct BdR_measurement { uint16_t P_onset; uint16_t P_offset; uint16_t QRS_onset; uint16_t QRS_offset; uint16_t T_offset; int16_t P_axis; int16_t QRS_axis; int16_t T_axis; }; struct info { uint8_t type; char *date; char *time; uint8_t number; }; struct header_lead_measurement { uint16_t number_lead; uint16_t number_lead_measurement; }; struct lead_measurement_block { uint16_t ID; int16_t P_duration; int16_t PR_interval; int16_t QRS_duration; int16_t QT_interval; int16_t Q_duration; int16_t R_duration; int16_t S_duration; int16_t R1_duration; int16_t S1_duration; int16_t Q_amplitude; int16_t R_amplitude; int16_t S_amplitude; int16_t R1_amplitude; int16_t S1_amplitude; int16_t J_point_amplitude; int16_t Pp_amplitude; int16_t Pm_amplitude; int16_t Tp_amplitude; int16_t Tm_amplitude; int16_t ST_slope; int16_t P_morphology; int16_t T_morphology; int16_t iso_electric_segment_onset_QRS; int16_t iso_electric_segment_offset_QRS; int16_t intrinsicoid_deflection; uint16_t quality_recording[8]; int16_t ST_amplitude_Jplus20; int16_t ST_amplitude_Jplus60; int16_t ST_amplitude_Jplus80; int16_t ST_amplitude_JplusRR16; int16_t ST_amplitude_JplusRR8; }; struct statement_coded { uint8_t sequence_number; uint16_t length; uint8_t type; uint16_t number_field; }; //_____________________________________ //structs for sections: 2, 3, 4, 5, 6 //_____________________________________ struct DATA_DECODE { struct table_H *t_Huffman; uint16_t *flag_Huffman; struct lead *data_lead; struct f_lead flag_lead; struct Protected_Area *data_protected; struct Subtraction_Zone *data_subtraction; struct f_BdR0 flag_BdR0; uint16_t *length_BdR0; uint8_t *samples_BdR0; int32_t *Median; struct f_Res flag_Res; uint16_t *length_Res; uint8_t *samples_Res; int32_t *Residual; int32_t *Reconstructed; }; struct TREE_NODE //struttura di un nodo dell'albero { struct TREE_NODE *next_0; struct TREE_NODE *next_1; int16_t row; }; //_____________________________________ //structs for sections: 7, 10 //_____________________________________ struct DATA_RECORD { struct global_measurement data_global; struct spike *data_spike; uint8_t *type_BdR; struct BdR_measurement *data_BdR; struct additional_measurement *data_additional; struct header_lead_measurement header_lead; struct lead_measurement_block *lead_block; }; //_____________________________________ //structs for sections: 1, 8, 11 //_____________________________________ struct DATA_INFO { struct demographic ana; struct clinic cli; struct descriptive des; struct device dev; struct info flag_report; struct numeric *text_dim; char *text_report; struct info flag_statement; struct statement_coded *data_statement; char *text_statement; }; #endif /*__STRUCTURES_H__*/ //_____________________________________ stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_cfs_read.c0000664000175000017500000013150614752215315016462 /* Copyright (C) 2010-2019 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sourceforge.io/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "../biosig.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) uint16_t cfs_data_type(uint8_t dataType) { switch (dataType) { case 0: //int8 return 1; case 1: //uint8 return 3; case 2: //int16 return 3; case 3: // uint16 return 4; case 4: // int32 return 5; case 5: //float return 16; case 6: // double return 17; case 7: // char return 0; default: return 0xffff; } } /* trim_trailing_space: trims trailing whitespaces from pascal string (pstr), and the string becomes always 0-terminated. This may mean that the last string character might be deleted, if all bytes are filled with non-zero values. no memory allocation or reallication is performed, maxLength+1 is the size of the memory allocation for pstr (pstr[0] to pstr[maxLength]). maxLength specify the string length w/o count or terminating zero byte. pascal string: first byte contains lengths, followed by characters, not null-terminated */ char *trim_trailing_space(uint8_t *pstr, unsigned maxLength) { unsigned len = min(pstr[0], maxLength); while (isspace(pstr[len]) && (len>0)) { len--; } if (len==maxLength) fprintf(stdout,"Warning %s: last and %i-th character of string <%c%c%c%c...> has been deleted\n",__func__,len,pstr[1],pstr[2],pstr[3],pstr[4]); len = min(len+1,maxLength); pstr[len]=0; pstr[0]=len; return (pstr+1); } const char *Signal6_StateTable[]={ "","State 1","State 2","State 3","State 4","State 5","State 6","State 7","State 8","State 9", "State 10","State 11","State 12","State 13","State 14","State 15","State 16","State 17","State 18","State 19", "State 20","State 21","State 22","State 23","State 24","State 25","State 26","State 27","State 28","State 29", "State 30","State 31","State 32","State 33","State 34","State 35","State 36","State 37","State 38","State 39", "State 40","State 41","State 42","State 43","State 44","State 45","State 46","State 47","State 48","State 49", "State 50","State 51","State 52","State 53","State 54","State 55","State 56","State 57","State 58","State 59", "State 60","State 61","State 62","State 63","State 64","State 65","State 66","State 67","State 68","State 69", "State 70" }; EXTERN_C void sopen_cfs_read(HDRTYPE* hdr) { /* this function will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ if (VERBOSE_LEVEL>7) fprintf(stdout,"%s:%i sopen_cfs_read started - %i bytes already loaded\n",__FILE__,__LINE__,hdr->HeadLen); #define H1LEN (8+14+4+8+8+2+2+2+2+2+4+2+2+74+4+40) size_t count = hdr->HeadLen; char flag_FPulse = 0; // indicates whether data was recorded using FPulse #define CFS_NEW // this flag allows to switch back to old version while (!ifeof(hdr)) { hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header,count*2+1); count += ifread(hdr->AS.Header+count,1,count,hdr); } hdr->AS.Header[count] = 0; hdr->FLAG.OVERFLOWDETECTION = 0; /* Implementation is based on the following reference: CFS - The CED Filing System October 2006 */ /* General Header */ // uint32_t filesize = leu32p(hdr->AS.Header+22); // unused hdr->FILE.size = leu32p(hdr->AS.Header+0x16); // file size hdr->NS = leu16p(hdr->AS.Header+0x2a); // 6 number of channels uint16_t n = leu16p(hdr->AS.Header+0x2c); // 7 number of file variables uint16_t d = leu16p(hdr->AS.Header+0x2e); // 8 number of data section variables uint16_t FileHeaderSize = leu16p(hdr->AS.Header+0x30); // 9 byte size of file header uint16_t DataHeaderSize = leu16p(hdr->AS.Header+0x32); // 10 byte size of data section header uint32_t LastDataSectionHeaderOffset = leu32p(hdr->AS.Header+0x34); // 11 last data section header offset uint16_t NumberOfDataSections = leu16p(hdr->AS.Header+0x38); // 12 last data section header offset // decode start time and date { struct tm t; char strtmp[9]; memcpy(strtmp, hdr->AS.Header+0x1a, 8); strtmp[8] = 0; // terminating null character if (VERBOSE_LEVEL>7) fprintf(stdout,"%s:%i sopen_cfs_read started [%s]\n",__FILE__,__LINE__,strtmp); t.tm_hour = atoi(strtok(strtmp,":/")); t.tm_min = atoi(strtok(NULL,":/")); t.tm_sec = atoi(strtok(NULL,":/")); memcpy(strtmp, hdr->AS.Header+0x22, 8); t.tm_mday = atoi(strtok(strtmp,"-:/")); t.tm_mon = atoi(strtok(NULL,"-:/"))-1; t.tm_year = atoi(strtok(NULL,"-:/")); if (t.tm_year<39) t.tm_year+=100; hdr->T0 = tm_time2gdf_time(&t); } if (NumberOfDataSections) { hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP, (hdr->EVENT.N + 2*NumberOfDataSections - 1) * sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS, (hdr->EVENT.N + 2*NumberOfDataSections - 1) * sizeof(*hdr->EVENT.POS)); hdr->EVENT.TimeStamp = (typeof(hdr->EVENT.TimeStamp)) realloc(hdr->EVENT.TimeStamp, (hdr->EVENT.N + 2*NumberOfDataSections - 1) * sizeof(*hdr->EVENT.TimeStamp)); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) CFS - %d,%d,%d,0x%x,0x%x,0x%x,%d,0x%x\n",__FILE__,__LINE__,hdr->NS,n,d,FileHeaderSize,DataHeaderSize,LastDataSectionHeaderOffset,NumberOfDataSections,leu32p(hdr->AS.Header+0x86)); /* channel information */ hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); #define H2LEN (22+10+10+1+1+2+2) char* H2 = (char*)(hdr->AS.Header + H1LEN); double xPhysDimScale[100]; // CFS is limited to 99 channels typeof(hdr->NS) NS = hdr->NS; uint8_t k; uint32_t bpb=0; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; /* 1 offset because CFS uses pascal type strings (first byte contains string length) in addition, the strings are \0 terminated. */ hc->OnOff = 1; hc->LeadIdCode = 0; hc->bi8 = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i) Channel #%i/%i: %i<%s>/%i<%s>\n",__FILE__,__LINE__,k+1, hdr->NS, H2[22 + k*H2LEN], H2 + 23 + k*H2LEN, H2[32 + k*H2LEN], H2 + 33 + k*H2LEN); strncpy(hc->Label, trim_trailing_space(H2 + k*H2LEN, 20), 21); // Channel name hc->PhysDimCode = PhysDimCode (trim_trailing_space(H2 + 22 + k*H2LEN,9)); // Y axis units xPhysDimScale[k] = PhysDimScale(PhysDimCode(trim_trailing_space(H2 + 32 + k*H2LEN,9))); // X axis units uint8_t dataType = H2[42 + k*H2LEN]; uint8_t dataKind = H2[43 + k*H2LEN]; //uint16_t byteSpace = leu16p(H2+44 + k*H2LEN); // stride //uint16_t next = leu16p(H2+46 + k*H2LEN); hc->GDFTYP = cfs_data_type(dataType); if (hc->GDFTYP > 580) // sizeof GDFTYP_BITS[] biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "CFS: unknown/unsupported data type !"); if (H2[43 + k * H2LEN] == 1) { // Matrix data does not return an extra channel, but contains Markers and goes into the event table. hc->OnOff = 0; NS--; } hc->bi = bpb; bpb += GDFTYP_BITS[hc->GDFTYP]>>3; // per single sample hc->Transducer[0] = '\0'; hc->Impedance = NAN; hc->TOffset = NAN; hc->LowPass = NAN; hc->HighPass = NAN; hc->Notch = NAN; hc->XYZ[0] = NAN; hc->XYZ[1] = NAN; hc->XYZ[2] = NAN; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i) Channel #%i: [%s](%i/%i) <%s>/<%s> ByteSpace%i,Next#%i\n", __FILE__, __LINE__, k+1, H2 + 1 + k*H2LEN, dataType, dataKind, H2 + 23 + k*H2LEN, H2 + 33 + k*H2LEN, leu16p(H2+44+k*H2LEN), leu16p(H2+46+k*H2LEN)); } hdr->AS.bpb = bpb; size_t datapos = H1LEN + H2LEN*hdr->NS; /* file variable information : will be extracted as application specific information // n*36 bytes */ if (VERBOSE_LEVEL>7) fprintf(stdout,"\n******* file variable information (n=%i) *********\n", n); hdr->AS.bci2000= realloc(hdr->AS.bci2000, 3); hdr->AS.bci2000[0]='\0'; for (k = 0; k < n; k++) { int i=-1; double f=NAN; size_t pos = datapos + k*36; char *desc = (char*)(hdr->AS.Header+pos+1); uint16_t typ = leu16p(hdr->AS.Header+pos+22); char *unit = (char*)(hdr->AS.Header+pos+25); uint16_t off = leu16p(hdr->AS.Header+pos+34); // if (flag_FPulse && !strcmp(desc, "Spare")) continue; /* H1LEN General Header H2LEN*NS Channel Information a 48 byte n*36 File Variable information a 36 byte d*36 DS Variable information */ size_t p3 = H1LEN + H2LEN*hdr->NS + (n+d+2)*36 + off; /***** file variable k *****/ switch (typ) { case 0: case 1: i = hdr->AS.Header[p3]; break; case 2: i = lei16p(hdr->AS.Header+p3); break; case 3: i = leu16p(hdr->AS.Header+p3); break; case 4: i = lei32p(hdr->AS.Header+p3); break; case 5: f = lef32p(hdr->AS.Header+p3); break; case 6: f = lef64p(hdr->AS.Header+p3); break; } if (VERBOSE_LEVEL>8) { fprintf(stdout,"#%2i [%i:%i] <%s>",k,typ,off,desc); if (typ<1) ; else if (typ<5) fprintf(stdout,"[%d]",i); else if (typ<7) fprintf(stdout,"[%g]",f); else if (typ==7) fprintf(stdout,"[%s]",hdr->AS.Header+p3+1); fprintf(stdout,"[%s]\n",unit); } else if (VERBOSE_LEVEL>7) { if (typ==7) fprintf(stdout,"#%2i [%i:] <%s> <%s> <%s>\n",k,typ,desc, hdr->AS.Header+p3+1,unit); } if ((typ==7) && !strncmp(desc,"Script",6)) { char *scriptline=(char*)hdr->AS.Header+p3+1; if (!strncmp(desc,"ScriptBlock",11)) { // only the script block is extracted assert(hdr->AS.Header[p3]==strlen(scriptline)); assert(hdr->AS.Header[p3+1+hdr->AS.Header[p3]]==0); // replace '\r' with '\n' in scriptline while (*scriptline) { switch (*scriptline) { case '\r': *scriptline='\n'; } scriptline++; } scriptline=(char*)hdr->AS.Header+p3+1; hdr->AS.bci2000=realloc(hdr->AS.bci2000, strlen(hdr->AS.bci2000) + strlen(scriptline) + 1); strcat(hdr->AS.bci2000, scriptline); // Flawfinder: ignore } else if (!strncmp(desc,"Scriptline",10)) { hdr->AS.bci2000=realloc(hdr->AS.bci2000, strlen(hdr->AS.bci2000) + strlen(scriptline) + 3); strcat(hdr->AS.bci2000, scriptline); // Flawfinder: ignore strcat(hdr->AS.bci2000, "\n"); // Flawfinder: ignore } } if (k==0) { // File variable zero flag_FPulse = !strcmp(unit,"FPulse"); if (typ==2) hdr->VERSION = i/100.0; else fprintf(stderr,"Warning (%s line %i): File variable zeros is not of type INT2\n",__func__,__LINE__); char *e = (char*)&(hdr->ID.Equipment); memcpy(e,unit,8); lei16a(i,e+6); } } hdr->ID.Manufacturer.Name = "CED - Cambridge Electronic Devices"; hdr->ID.Manufacturer.Model = NULL; hdr->ID.Manufacturer.Version = NULL; hdr->ID.Manufacturer.SerialNumber = NULL; if (VERBOSE_LEVEL>7) fprintf(stdout,"\n******* Data Section variable information (n=%i,%i)*********\n", d,NumberOfDataSections); datapos = LastDataSectionHeaderOffset; //H1LEN + H2LEN*hdr->NS + n*36; // reverse order of data sections uint32_t *DATAPOS = (uint32_t*)malloc(sizeof(uint32_t)*NumberOfDataSections); uint16_t m; for (m = NumberOfDataSections; 0 < m; ) { DATAPOS[--m] = datapos; datapos = leu32p(hdr->AS.Header + datapos); if (VERBOSE_LEVEL>7) fprintf(stdout, "%s:%i sopen_cfs_read started: section %"PRIi16" pos %"PRIuPTR" 0x%"PRIxPTR"\n",__FILE__,__LINE__,m,datapos,datapos); } if (hdr->AS.SegSel[0] > NumberOfDataSections) { fprintf(stderr,"Warning loading CFS file: selected sweep number is larger than number of sweeps [%d,%d] - no data is loaded\n",hdr->AS.SegSel[0], NumberOfDataSections); NumberOfDataSections = 0; } else if (0 < hdr->AS.SegSel[0]) { // hack: if sweep is selected, use same method than for data with a single sweep DATAPOS[0] = DATAPOS[hdr->AS.SegSel[0]-1]; NumberOfDataSections = 1; } // void *VarChanInfoPos = hdr->AS.Header + datapos + 30; // unused char flag_ChanInfoChanged = 0; hdr->NRec = NumberOfDataSections; int Signal6_CodeDescLen = 0; size_t SPR = 0, SZ = 0; for (m = 0; m < NumberOfDataSections; m++) { int32_t tmp_event_typ=0; double tmp_event_pos=0; datapos = DATAPOS[m]; for (k = 0; k < d; k++) { /***** DS variable k information *****/ int i=-1; double f=NAN; size_t pos = H1LEN + H2LEN*hdr->NS + (n+k+1)*36; char *desc = (char*)(hdr->AS.Header+pos+1); uint16_t typ = leu16p(hdr->AS.Header+pos+22); char *unit = (char*)(hdr->AS.Header+pos+25); uint16_t off = leu16p(hdr->AS.Header+pos+34); if (flag_FPulse && !strcmp(desc, "Spare")) continue; /***** data section variable k *****/ size_t p3 = DATAPOS[m] + 30 + 24 * hdr->NS + off; switch (typ) { case 0: case 1: i = hdr->AS.Header[p3]; break; case 2: i = lei16p(hdr->AS.Header+p3); break; case 3: i = leu16p(hdr->AS.Header+p3); break; case 4: i = lei32p(hdr->AS.Header+p3); break; case 5: f = lef32p(hdr->AS.Header+p3); break; case 6: f = lef64p(hdr->AS.Header+p3); break; } if ((k==1) && (typ==4) && !strcmp(desc,"State")) { tmp_event_typ = i; if ((Signal6_CodeDescLen < i) && (i < 256)) Signal6_CodeDescLen = i; } else if ((k==3) && (typ==6) && !strcmp(desc,"Start") && !strcmp(unit,"s")) tmp_event_pos = f; if (VERBOSE_LEVEL>7) { fprintf(stdout,"#%2i [%i:%i] <%s>",k,typ,off,desc); if (typ<1) ; else if (typ<5) fprintf(stdout,"[%d]",i); else if (typ<7) fprintf(stdout,"[%g]",f); else if (typ==7) fprintf(stdout,"[%s]",hdr->AS.Header+p3+1); fprintf(stdout,"[%s]\n",unit); } } typeof (hdr->T0) TS = tmp_event_pos ? (hdr->T0 + ldexp(tmp_event_pos/(24.0*3600.0),32)) : 0; if (m>0) { hdr->EVENT.TYP[hdr->EVENT.N] = 0x7ffe; hdr->EVENT.POS[hdr->EVENT.N] = SPR; hdr->EVENT.TimeStamp[hdr->EVENT.N] = TS; hdr->EVENT.N++; } if (tmp_event_typ > 0) { hdr->EVENT.TYP[hdr->EVENT.N] = tmp_event_typ; hdr->EVENT.POS[hdr->EVENT.N] = SPR; hdr->EVENT.TimeStamp[hdr->EVENT.N] = TS; hdr->EVENT.N++; } if (!leu32p(hdr->AS.Header+datapos+8)) continue; // empty segment if (VERBOSE_LEVEL>7) fprintf(stdout,"\n******* DATA SECTION --%03i-- %i *********\n",m,flag_ChanInfoChanged); if (VERBOSE_LEVEL>7) fprintf(stdout,"\n[DS#%3i] 0x%x 0x%x [0x%x 0x%x szChanData=%i] 0x02%x\n", m, FileHeaderSize, \ (int)datapos, leu32p(hdr->AS.Header+datapos), leu32p(hdr->AS.Header+datapos+4), \ leu32p(hdr->AS.Header+datapos+8), leu16p(hdr->AS.Header+datapos+12)); uint32_t sz = 0; uint32_t bpb = 0, spr = 0; hdr->AS.first = 0; hdr->AS.length = 0; char flag_firstchan = 1; uint32_t xspr0 = 0; for (k = 0; k < hdr->NS; k++) { uint8_t *pos = hdr->AS.Header + datapos + 30 + 24 * k; CHANNEL_TYPE *hc = hdr->CHANNEL + k; // uint32_t bi = leu32p(pos); // unused uint32_t xspr = leu32p(pos+4); float Cal = lef32p(pos+8); float Off = lef32p(pos+12); double XCal = lef32p(pos+16); double XOff = lef32p(pos+20);// unused if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i/%i %i/%i %f+%f change SPR:%i->%i, Cal:%f->%f, Off: %f->%f\n", \ __FILE__,__LINE__, (int)m, (int)NumberOfDataSections, (int)k,(int)hdr->NS, XCal, XOff, \ (int)hc->SPR,(int)xspr,hc->Cal,Cal,hc->Off,Off); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) [%i %i] %i %i %p %i\n", __FILE__, __LINE__, m, k, xspr0, xspr, pos, (int)(datapos + 30 + 24 * k)); if (xspr0 == 0) xspr0 = xspr; else if (xspr>0) xspr0 = lcm(xspr0,xspr); else if (xspr==0) if (VERBOSE_LEVEL>7) fprintf(stdout,"Warning : #%i of section %i contains %i samples \n", (int)k, (int)m, (int)xspr); if (m > 0) { if ( (hc->Cal != Cal) || (hc->Off != Off) ) switch (hc->GDFTYP) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 16: hc->GDFTYP = 16; // float, single precision break; case 7: case 8: case 17: hc->GDFTYP = 17; // double break; case 18: // quadruple default: ; } } else { hc->Cal = Cal; hc->Off = Off; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %i #%i: SPR=%i=%i=%i x%f+-%f %i x%g %g %g\n", __func__,__LINE__,m,k,spr,(int)SPR,hc->SPR,hc->Cal,hc->Off,hc->bi,xPhysDimScale[k], XCal, XOff); double Fs = 1.0 / (xPhysDimScale[k] * XCal); if ( (hc->OnOff == 0) || (XCal == 0.0) ) { ; // do nothing: } else if (flag_firstchan) { hdr->SampleRate = Fs; flag_firstchan = 0; } else if (fabs(hdr->SampleRate - Fs) > 1e-3) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CED/CFS: different sampling rates are not supported\n"); } sz += hc->SPR * GDFTYP_BITS[hc->GDFTYP] >> 3; hc->bi = bpb; bpb += GDFTYP_BITS[hc->GDFTYP]>>3; // per single sample hdr->AS.length += hc->SPR; } SPR += xspr0; SZ += sz; hdr->AS.bpb = bpb; } if (Signal6_CodeDescLen > 0) { if (Signal6_CodeDescLen > 70) { // 19 is sizeof Signal6_StateTable fprintf(stderr, "Warning %s (line %i): Event code description exceed table (Signal6_CodeDescLen=%i)\n",__func__,__LINE__,Signal6_CodeDescLen); Signal6_CodeDescLen = 70; } hdr->EVENT.LenCodeDesc = Signal6_CodeDescLen+1; //70 is sizeof(Signal6_StateTable) hdr->EVENT.CodeDesc = realloc(hdr->EVENT.CodeDesc, sizeof(char*) * (Signal6_CodeDescLen+1)); for (int k=0; k <= Signal6_CodeDescLen; k++) { hdr->EVENT.CodeDesc[k] = Signal6_StateTable[k]; } } /* The previous and the next loop have been split, in order to avoid multiple reallocations. Multiple reallocations seem to be a major issue for performance problems of Windows (a 50 MB file with 480 sweeps took 50 s to load). However, the two loops might contain some redundant operations. */ hdr->AS.flag_collapsed_rawdata = 0; void *ptr = realloc(hdr->AS.rawdata, hdr->AS.bpb * SPR); if (!ptr) biosigERROR(hdr,B4C_MEMORY_ALLOCATION_FAILED, "CFS: memory allocation failed in line __LINE__"); hdr->AS.rawdata = (uint8_t*)ptr; SPR = 0, SZ = 0; for (m = 0; m < NumberOfDataSections; m++) { datapos = DATAPOS[m]; if (!leu32p(hdr->AS.Header+datapos+8)) continue; // empty segment uint32_t sz = 0; uint32_t bpb = 0, spr = 0; hdr->AS.first = 0; hdr->AS.length = 0; char flag_firstchan = 1; uint32_t xspr0 = 0; float Cal, Off; for (k = 0; k < hdr->NS; k++) { uint8_t *pos = hdr->AS.Header + datapos + 30 + 24 * k; CHANNEL_TYPE *hc = hdr->CHANNEL + k; //uint32_t bi = leu32p(pos); // unused uint32_t xspr = leu32p(pos+4); hc->SPR = leu32p(pos+4); hc->Cal = lef32p(pos+8); hc->Off = lef32p(pos+12); Cal = lef32p(pos+8); Off = lef32p(pos+12); double XCal = lef32p(pos+16); double XOff = lef32p(pos+20);// unused if (xspr0 == 0) xspr0 = xspr; else if (xspr>0) xspr0 = lcm(xspr0, xspr); else if (xspr==0) if (VERBOSE_LEVEL>7) fprintf(stdout,"Warning : #%i of section %i contains %i samples \n", (int)k, (int)m, (int)xspr); assert( (xspr==0) || ((xspr0 % xspr) == 0) ); double Fs = 1.0 / (xPhysDimScale[k] * XCal); if ( (hc->OnOff == 0) || (XCal == 0.0) ) { ; // do nothing: } else if (flag_firstchan) { hdr->SampleRate = Fs; flag_firstchan = 0; } else if (fabs(hdr->SampleRate - Fs) > 1e-3) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CED/CFS: different sampling rates are not supported\n"); } sz += xspr * GDFTYP_BITS[hc->GDFTYP] >> 3; hc->bi = bpb; bpb += GDFTYP_BITS[hc->GDFTYP]>>3; // per single sample hdr->AS.length += xspr; } if (xspr0 > 0) { /* hack: copy data into a single block (rawdata) this is used as a data cache, no I/O is needed in sread, at the cost that sopen is slower sread_raw does not attempt to reload the data */ hdr->AS.first = 0; uint8_t ns = 0; for (k = 0; k < hdr->NS; k++) { uint8_t *pos = hdr->AS.Header + datapos + 30 + 24 * k; CHANNEL_TYPE *hc = hdr->CHANNEL + k; uint32_t memoffset = leu32p(pos); uint8_t *srcaddr = hdr->AS.Header + leu32p(hdr->AS.Header+datapos + 4) ; //uint16_t byteSpace = leu16p(H2+44 + k*H2LEN); uint8_t dataType = H2[42 + k*H2LEN]; uint8_t dataKind = H2[43 + k*H2LEN]; // equidistant, Subsidiary or Matrix data uint16_t stride = leu16p(H2+44 + k*H2LEN); // byteSpace uint16_t next = leu16p(H2+46 + k*H2LEN); uint16_t gdftyp = cfs_data_type(dataType); if (gdftyp > 580) // sizeof GDFTYP_BITS[] biosigERROR(hdr, B4C_DATATYPE_UNSUPPORTED, "CFS: unknown/unsupported data type !"); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) #%i %i,%i %i %i %i %i: %i @%p %i\n", __func__, __LINE__, k, dataType, dataKind, hc->SPR, gdftyp,hc->GDFTYP, stride, memoffset, srcaddr, leu32p(hdr->AS.Header+datapos + 4) + leu32p(hdr->AS.Header + datapos + 30 + 24 * k)); if (hc->OnOff==0) continue; // Time and Marker channels are not supported, yet if ((hc->SPR > 0) && (xspr0 != hc->SPR)) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CED/CFS: samples-per-record (SPR) changes between channels - this is not supported yet."); } size_t k2; if (gdftyp == hc->GDFTYP) { for (k2 = 0; k2 < xspr0; k2++) { uint8_t *ptr = srcaddr + memoffset + k2*stride; uint8_t *dest = hdr->AS.rawdata + hc->bi + (SPR + k2) * hdr->AS.bpb; double val=NAN; switch (gdftyp) { // reorder for performance reasons - more frequent gdftyp's come first case 3: //val = lei16p(ptr); case 4: //val = leu16p(ptr); memcpy(dest, ptr, 2); break; case 16: //val = lef32p(ptr); memcpy(dest, ptr, 4); break; case 7: //val = lei64p(ptr); case 8: //val = leu64p(ptr); case 17: //val = lef64p(ptr); memcpy(dest, ptr, 8); break; case 0: //val = *( char*) ptr; case 1: //val = *( int8_t*) ptr; case 2: //val = *(uint8_t*) ptr; *dest = *ptr; break; case 5: val = lei32p(ptr); case 6: //val = leu32p(ptr); memcpy(dest, ptr, 4); break; default: val = NAN; biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CED/CFS: invalid data type"); } if (hc->OnOff) continue; if (!strncmp(hc->Label,"Marker",6) && hc->PhysDimCode==2176 && hc->GDFTYP==5 && next != 0) { // matrix data might contain time markers. // memory allocation for additional events - more efficient implementation would be nice hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP, (hdr->EVENT.N + NumberOfDataSections) * sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS, (hdr->EVENT.N + NumberOfDataSections) * sizeof(*hdr->EVENT.POS)); /* char Desc[2]; Desc[0] = srcaddr[hdr->CHANNEL[next].bi + k2*stride]; Desc[1] = 0; this does currently not work because FreeTextEvent expects that the string constant is available as long as hdr, which is not the case here. */ // typically a single character within a 4 byte integer, this should be sufficient to ensure \0 termination char *Desc = (char*)srcaddr + hdr->CHANNEL[next].bi + k2 * stride; Desc[1] = 0; FreeTextEvent(hdr, hdr->EVENT.N, Desc); hdr->EVENT.POS[hdr->EVENT.N] = lround( (val * hc->Cal + hc->Off) * hdr->SampleRate) + SPR; hdr->EVENT.N++; } } } else { for (k2 = 0; k2 < xspr0; k2++) { uint8_t *ptr = srcaddr + memoffset + k2*stride; uint8_t *dest = hdr->AS.rawdata + hc->bi + (SPR + k2) * hdr->AS.bpb; double val; if (hc->GDFTYP==16) { // float switch (gdftyp) { // reorder for performance reasons - more frequent gdftyp's come first case 3: val = lei16p(ptr) * Cal + Off; break; case 4: val = leu16p(ptr) * Cal + Off; break; case 16: val = lef32p(ptr) * Cal + Off; break; case 7: val = lei64p(ptr) * Cal + Off; break; case 8: val = leu64p(ptr) * Cal + Off; break; case 17: val = lef64p(ptr) * Cal + Off; break; case 0: val = (*( char*) ptr) * Cal + Off; break; case 1: val = (*( int8_t*) ptr) * Cal + Off; break; case 2: val = (*(uint8_t*) ptr) * Cal + Off; break; case 5: val = lei32p(ptr) * Cal + Off; break; case 6: val = leu32p(ptr) * Cal + Off; break; default: val = NAN; biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CED/CFS: invalid data type"); } lef32a(val, dest); // hdr->AS.rawdata uses the native endian format of the platform } else { // any conversion to anything but float is not supported yet. biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CED/CFS: data type changes between segments - this is not supported yet."); } // scaling has been already consider when converting to float, do not scale in sread anymore. hc->Cal = 1.0; hc->Off = 0.0; if (hc->OnOff) continue; if (!strncmp(hc->Label,"Marker",6) && hc->PhysDimCode==2176 && hc->GDFTYP==5 && next != 0) { // matrix data might contain time markers. // memory allocation for additional events - more efficient implementation would be nice hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP, (hdr->EVENT.N + NumberOfDataSections) * sizeof(*hdr->EVENT.TYP)); hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS, (hdr->EVENT.N + NumberOfDataSections) * sizeof(*hdr->EVENT.POS)); /* char Desc[2]; Desc[0] = srcaddr[hdr->CHANNEL[next].bi + k2*stride]; Desc[1] = 0; this does currently not work because FreeTextEvent expects that the string constant is available as long as hdr, which is not the case here. */ // typically a single character within a 4 byte integer, this should be sufficient to ensure \0 termination char *Desc = (char*)srcaddr + hdr->CHANNEL[next].bi + k2 * stride; Desc[1] = 0; FreeTextEvent(hdr, hdr->EVENT.N, Desc); hdr->EVENT.POS[hdr->EVENT.N] = lround( (val * hc->Cal + hc->Off) * hdr->SampleRate) + SPR; hdr->EVENT.N++; } } } ns += hc->OnOff; } } SPR += xspr0; SZ += sz; datapos = leu32p(hdr->AS.Header + datapos); } free(DATAPOS); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): SPR=%i=%i NRec=%i @%p\n",__FILE__,__LINE__,(int)SPR,hdr->SPR,(int)hdr->NRec, hdr->AS.rawdata); // set variables such that sread_raw does not attempt to reload the data hdr->AS.first = 0; hdr->EVENT.SampleRate = hdr->SampleRate; if (NumberOfDataSections < 1) { hdr->SPR = 0; } else { hdr->SPR = 1; hdr->NRec = SPR; hdr->AS.length = SPR; size_t bpb = 0; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; assert(hc->bi==bpb); bpb += GDFTYP_BITS[hc->GDFTYP] >> 3; hc->SPR = hdr->SPR; } assert(hdr->AS.bpb==bpb); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): SPR=%i=%i NRec=%i\n",__func__,__LINE__,(int)SPR,hdr->SPR,(int)hdr->NRec); datapos = FileHeaderSize; //+DataHeaderSize; if (flag_ChanInfoChanged) { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "CED/CFS: varying channel information not supported"); } for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL + k; switch (hc->GDFTYP) { case 0: case 1: hc->DigMax = 127; hc->DigMin = -128; break; case 2: hc->DigMax = 255; hc->DigMin = 0; break; case 3: hc->DigMax = (int16_t)0x7fff; hc->DigMin = (int16_t)0x8000; break; case 4: hc->DigMax = 0xffff; hc->DigMin = 0; break; case 16: case 17: hc->DigMax = 1e9; hc->DigMin = -1e9; break; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (%i): %f %f %f %f %f %f\n",__FILE__,__LINE__,hc->PhysMax, hc->DigMax, hc->Cal, hc->Off,hc->PhysMin, hc->DigMin ); hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (%i): %f %f %f %f %f %f\n",__FILE__,__LINE__,hc->PhysMax, hc->DigMax, hc->Cal, hc->Off,hc->PhysMin, hc->DigMin ); } #undef H1LEN } /***************************************************************************** SOPEN_SMR_READ for reading SON/SMR files son.h, sonintl.h are used just for understanding the file format. and are not needed for the core functionality. TODO: Currently waveform data is supported, events and marker information is ignored *****************************************************************************/ #if defined(WITH_SON) #include "sonintl.h" // defines __SONINTL__ #else #define ADCdataBlkSize 32000 #endif EXTERN_C void sopen_smr_read(HDRTYPE* hdr) { /*TODO: implemnt SON/SMR format */ fprintf(stdout,"SOPEN: Support for CED's SMR/SON format is under construction \n"); size_t count = hdr->HeadLen; if (count < 512) { hdr->HeadLen = 512; // make sure fixed header (first 512 bytes) are read hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen+1); count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); hdr->AS.Header[count]=0; } // get Endianity, Version and Header size hdr->FILE.LittleEndian = (*(uint16_t*)(hdr->AS.Header+38) == 0); // 0x0000: little endian, 0x0101: big endian if (hdr->FILE.LittleEndian) { hdr->VERSION = leu16p(hdr->AS.Header); hdr->HeadLen = leu32p(hdr->AS.Header + 26 ); // first data } else { hdr->VERSION = beu16p(hdr->AS.Header); hdr->HeadLen = beu32p(hdr->AS.Header + 26); // first data // TODO: relax this restriction biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "SON/SMR: big-endian file not supported,yet"); } size_t HeadLen = hdr->HeadLen; size_t size_factor = 1; if (hdr->VERSION >= 9) { size_factor = 512; HeadLen *= size_factor; if (sizeof(size_t) <= 4) { // TODO: relax that restriction biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "SON/SMR: version 9 (bigfile) not supported,yet"); return; } } if (count < HeadLen) { // read channel header and extra data (i.e. everything up to firstData) hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,HeadLen+1); count += ifread(hdr->AS.Header+count, 1, HeadLen-count, hdr); hdr->AS.Header[count]=0; } #ifdef __SONINTL__ if (VERBOSE_LEVEL > 6) { TFileHead *tfh = (void*)(hdr->AS.Header); TChannel *tc = (void*)(hdr->AS.Header+512); // debugging information fprintf(stdout,"\tsizeof TFileHead %i\n\tsizeof TChannel %i\n\tsizeof TDataBlock %i\n", (int)sizeof(TFileHead),(int)sizeof(TChannel),(int)sizeof(TDataBlock)); fprintf(stdout,"%i NS=%i %i %i %i\n", (int)sizeof(*tfh),hdr->NS,(int)offsetof(TFileHead,channels),(int)sizeof(TChannel),(int)sizeof(TDataBlock)); fprintf(stdout,"systemID\t%i %i %i\n",(int)offsetof(TFileHead,systemID), (int)sizeof(tfh->systemID),lei16p(hdr->AS.Header+offsetof(TFileHead,systemID))); fprintf(stdout,"copyright\t%i %i\n",(int)offsetof(TFileHead,copyright),(int)sizeof(tfh->copyright)); fprintf(stdout,"creator \t%i %i <%8s>\n",(int)offsetof(TFileHead,creator), (int)sizeof(tfh->creator),hdr->AS.Header+offsetof(TFileHead,creator)); fprintf(stdout,"usPerTime\t%i %i %i\n",(int)offsetof(TFileHead,usPerTime), (int)sizeof(tfh->usPerTime),lei16p(hdr->AS.Header+offsetof(TFileHead,usPerTime))); fprintf(stdout,"timePerADC\t%i %i %i\n",(int)offsetof(TFileHead,timePerADC), (int)sizeof(tfh->timePerADC),lei16p(hdr->AS.Header+offsetof(TFileHead,timePerADC))); fprintf(stdout,"fileState\t%i %i %i\n",(int)offsetof(TFileHead,fileState), (int)sizeof(tfh->fileState),lei16p(hdr->AS.Header+offsetof(TFileHead,fileState))); fprintf(stdout,"firstData\t%i %i %i\n",(int)offsetof(TFileHead,firstData), (int)sizeof(tfh->firstData),lei32p(hdr->AS.Header+offsetof(TFileHead,firstData))); fprintf(stdout,"channels\t%i %i 0x%04x\n",(int)offsetof(TFileHead,channels), (int)sizeof(tfh->channels),lei16p(hdr->AS.Header+offsetof(TFileHead,channels))); fprintf(stdout,"chanSize\t%i %i 0x%04x\n",(int)offsetof(TFileHead,chanSize), (int)sizeof(tfh->chanSize),lei16p(hdr->AS.Header+offsetof(TFileHead,chanSize))); fprintf(stdout,"extraData\t%i %i %i\n",(int)offsetof(TFileHead,extraData), (int)sizeof(tfh->extraData),lei16p(hdr->AS.Header+offsetof(TFileHead,extraData))); fprintf(stdout,"bufferSz\t%i %i %i\n",(int)offsetof(TFileHead,bufferSz), (int)sizeof(tfh->bufferSz),lei16p(hdr->AS.Header+offsetof(TFileHead,bufferSz))); fprintf(stdout,"osFormat\t%i %i %i\n",(int)offsetof(TFileHead,osFormat), (int)sizeof(tfh->osFormat),lei16p(hdr->AS.Header+offsetof(TFileHead,osFormat))); fprintf(stdout,"maxFTime\t%i %i %i\n",(int)offsetof(TFileHead,maxFTime), (int)sizeof(tfh->maxFTime),lei32p(hdr->AS.Header+offsetof(TFileHead,maxFTime))); fprintf(stdout,"dTimeBase\t%i %i %g\n",(int)offsetof(TFileHead,dTimeBase), (int)sizeof(tfh->dTimeBase),lef64p(hdr->AS.Header+offsetof(TFileHead,dTimeBase))); fprintf(stdout,"timeDate\t%i %i\n",(int)offsetof(TFileHead,timeDate),(int)sizeof(tfh->timeDate)); fprintf(stdout,"cAlignFlag\t%i %i\n",(int)offsetof(TFileHead,cAlignFlag),(int)sizeof(tfh->cAlignFlag)); fprintf(stdout,"pad0 \t%i %i\n",(int)offsetof(TFileHead,pad0),(int)sizeof(tfh->pad0)); fprintf(stdout,"LUTable \t%i %i\n",(int)offsetof(TFileHead,LUTable),(int)sizeof(tfh->LUTable)); fprintf(stdout,"pad \t%i %i\n",(int)offsetof(TFileHead,pad),(int)sizeof(tfh->pad)); fprintf(stdout,"fileComment\t%i %i\n",(int)offsetof(TFileHead,fileComment),(int)sizeof(tfh->fileComment)); fprintf(stdout,"==CHANNEL==\n"); fprintf(stdout,"delSize \t%i %i\n",(int)offsetof(TChannel,delSize),(int)sizeof(tc->delSize)); fprintf(stdout,"nextDelBlock\t%i %i\n",(int)offsetof(TChannel,nextDelBlock),(int)sizeof(tc->nextDelBlock)); fprintf(stdout,"firstBlock\t%i %i\n",(int)offsetof(TChannel,firstBlock),(int)sizeof(tc->firstBlock)); fprintf(stdout,"lastBlock\t%i %i\n",(int)offsetof(TChannel,lastBlock),(int)sizeof(tc->lastBlock)); fprintf(stdout,"blocks \t%i %i\n",(int)offsetof(TChannel,blocks),(int)sizeof(tc->blocks)); fprintf(stdout,"nExtra \t%i %i\n",(int)offsetof(TChannel,nExtra),(int)sizeof(tc->nExtra)); fprintf(stdout,"preTrig \t%i %i\n",(int)offsetof(TChannel,preTrig),(int)sizeof(tc->preTrig)); fprintf(stdout,"blocksMSW\t%i %i\n",(int)offsetof(TChannel,blocksMSW),(int)sizeof(tc->blocksMSW)); fprintf(stdout,"phySz \t%i %i\n",(int)offsetof(TChannel,phySz),(int)sizeof(tc->phySz)); fprintf(stdout,"maxData \t%i %i\n",(int)offsetof(TChannel,maxData),(int)sizeof(tc->maxData)); fprintf(stdout,"comment \t%i %i\n",(int)offsetof(TChannel,comment),(int)sizeof(tc->comment)); fprintf(stdout,"maxChanTime \t%i %i\n",(int)offsetof(TChannel,maxChanTime),(int)sizeof(tc->maxChanTime)); fprintf(stdout,"lChanDvd\t%i %i\n",(int)offsetof(TChannel,lChanDvd),(int)sizeof(tc->lChanDvd)); fprintf(stdout,"phyChan \t%i %i\n",(int)offsetof(TChannel,phyChan),(int)sizeof(tc->phyChan)); fprintf(stdout,"title \t%i %i %s\n",(int)offsetof(TChannel,title),(int)sizeof(tc->title),((char*)&(tc->title))+1); fprintf(stdout,"idealRate\t%i %i\n",(int)offsetof(TChannel,idealRate),(int)sizeof(tc->idealRate)); fprintf(stdout,"kind \t%i %i\n",(int)offsetof(TChannel,kind),(int)sizeof(tc->kind)); fprintf(stdout,"delSizeMSB\t%i %i\n",(int)offsetof(TChannel,delSizeMSB),(int)sizeof(tc->delSizeMSB)); fprintf(stdout,"v.adc.scale\t%i %i\n",(int)offsetof(TChannel,v.adc.scale),(int)sizeof(tc->v.adc.scale)); fprintf(stdout,"v.adc.offset\t%i %i\n",(int)offsetof(TChannel,v.adc.offset),(int)sizeof(tc->v.adc.offset)); fprintf(stdout,"v.adc.units\t%i %i\n",(int)offsetof(TChannel,v.adc.units),(int)sizeof(tc->v.adc.units)); fprintf(stdout,"v.adc.divide\t%i %i\n",(int)offsetof(TChannel,v.adc.divide),(int)sizeof(tc->v.adc.divide)); fprintf(stdout,"v.event.initLow\t%i %i\n",(int)offsetof(TChannel,v.event.initLow),(int)sizeof(tc->v.event.initLow)); fprintf(stdout,"v.event.nextLow\t%i %i\n",(int)offsetof(TChannel,v.event.nextLow),(int)sizeof(tc->v.event.nextLow)); fprintf(stdout,"v.real.min\t%i %i\n",(int)offsetof(TChannel,v.real.min),(int)sizeof(tc->v.real.min)); fprintf(stdout,"v.real.max\t%i %i\n",(int)offsetof(TChannel,v.real.max),(int)sizeof(tc->v.real.max)); fprintf(stdout,"v.real.units\t%i %i\n",(int)offsetof(TChannel,v.real.units),(int)sizeof(tc->v.real.units)); assert(sizeof(TSONTimeDate)==8); assert(sizeof(TFileHead)==512); assert(sizeof(TChannel)==140); assert(sizeof(TDataBlock)==64020); } #endif uint16_t timePerADC; uint32_t maxFTime; double timebase,dTimeBase; memcpy(&hdr->ID.Equipment, hdr->AS.Header+12, 8); if (hdr->FILE.LittleEndian) { timebase = hdr->VERSION < 6 ? 1e-6 : lef64p(hdr->AS.Header + 44); hdr->SampleRate = 1.0 / (timebase * leu16p(hdr->AS.Header + 20) ); hdr->NS = leu16p(hdr->AS.Header + 30 ); timePerADC = lei16p(hdr->AS.Header + 22); maxFTime = leu32p(hdr->AS.Header + 40); dTimeBase = lef64p(hdr->AS.Header + 44); } else { timebase = hdr->VERSION < 6 ? 1e-6 : bef64p(hdr->AS.Header + 44); hdr->SampleRate = 1.0 / (timebase * beu16p(hdr->AS.Header + 20)); hdr->NS = beu16p(hdr->AS.Header + 30); timePerADC = bei16p(hdr->AS.Header + 22); maxFTime = beu32p(hdr->AS.Header + 40); dTimeBase = bef64p(hdr->AS.Header + 44); } hdr->SPR = 1; while (!ifeof(hdr)) { // read channel header and extra data hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header,hdr->HeadLen*2); hdr->HeadLen *= 2; count += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr); } hdr->HeadLen = count; /********************************************* read channel header *********************************************/ hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); typeof(hdr->NS) k; size_t bpb = 0; for (k = 0; k < hdr->NS; k++) { uint32_t off = 512 + k*140; CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->Cal = lef32p(hdr->AS.Header + off + 124); // v.adc.scale hc->Off = lef32p(hdr->AS.Header + off + 128); // v.adc.off hc->OnOff = 0; //*(int16_t*)(hdr->AS.Header + off + 106) != 0; hc->SPR = 0; hc->GDFTYP = 3; hc->LeadIdCode = 0; hc->Transducer[0] = '\0'; int stringLength = hdr->AS.Header[off+108]; assert(stringLength < MAX_LENGTH_LABEL); memcpy(hc->Label, hdr->AS.Header+off+108+1, stringLength); hc->Label[stringLength] = '\0'; { // extract Physical units (pascal string - first byte indicates the length, no 0-terminator) stringLength = hdr->AS.Header[off+132]; char PhysicalUnit[6]; assert( stringLength < sizeof(PhysicalUnit) ); memcpy(PhysicalUnit, hdr->AS.Header+off+132+1, stringLength); PhysicalUnit[stringLength] = '\0'; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): #%i <%s> <%s>\n",__FILE__,__LINE__, k+1, hc->Label, PhysicalUnit); if (!strcmp(PhysicalUnit,"Volt") || !strcmp(PhysicalUnit," Volt")) hc->PhysDimCode = 4256; else if (!strcmp(PhysicalUnit,"mVolt")) hc->PhysDimCode = 4274; else if (!strcmp(PhysicalUnit,"uVolt")) hc->PhysDimCode = 4275; else hc->PhysDimCode = PhysDimCode(PhysicalUnit); } uint32_t firstBlock = leu32p(hdr->AS.Header+off+6); uint32_t lastBlock = leu32p(hdr->AS.Header+off+10); hc->bi = bpb; hc->bi8= 0; uint8_t kind = hdr->AS.Header[off+122]; switch (kind) { case 0: // // ChanOff=0, /* the channel is OFF - */ hc->OnOff = 0; break; case 1: { // Adc, /* a 16-bit waveform channel */ hc->OnOff = 1; hc->GDFTYP = 3; hc->Cal = lef32p(hdr->AS.Header + off + 124) / 6553.6; hc->Off = lef32p(hdr->AS.Header + off + 128); hc->DigMax = (double)(int16_t)0x7fff; hc->DigMin = (double)(int16_t)0x8000; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; uint32_t blocks = leu16p(hdr->AS.Header+off+14); size_t bpbnew = bpb + blocks * ADCdataBlkSize * 2; hdr->AS.rawdata = realloc(hdr->AS.rawdata,bpbnew); uint32_t pos = firstBlock; while (1) { uint32_t items = leu16p(hdr->AS.Header+pos+18); memcpy(hdr->AS.rawdata+bpb, hdr->AS.Header+pos+20, items*2); bpb += items*2; hc->SPR += items; if (pos == lastBlock) break; pos = leu32p(hdr->AS.Header+pos+4); }; hdr->SPR = lcm(hdr->SPR, hc->SPR); break; } case 2: // EventFall, /* Event times (falling edges) */ hc->OnOff = 0; break; case 3: // EventRise, /* Event times (rising edges) */ hc->OnOff = 0; break; case 4: // EventBoth, /* Event times (both edges) */ hc->OnOff = 0; break; case 5: // Marker, /* Event time plus 4 8-bit codes */ hc->OnOff = 0; break; case 6: // AdcMark, /* Marker plus Adc waveform data */ hc->OnOff = 0; break; case 7: // RealMark, /* Marker plus float numbers */ hc->OnOff = 0; break; case 8: // TextMark, /* Marker plus text string */ hc->OnOff = 0; break; case 9: { // RealWave /* waveform of float numbers */ hc->OnOff = 1; hc->GDFTYP = 16; hc->LeadIdCode = 0; hc->Cal = lef32p(hdr->AS.Header + off + 124) / 6553.6; hc->Off = lef32p(hdr->AS.Header + off + 128); hc->DigMax = +1e9; hc->DigMin = -1e9; hc->PhysMax = hc->DigMax * hc->Cal + hc->Off; hc->PhysMin = hc->DigMin * hc->Cal + hc->Off; uint32_t blocks = leu16p(hdr->AS.Header+off+14); size_t bpbnew = bpb + blocks * ADCdataBlkSize * 4; hdr->AS.rawdata = realloc(hdr->AS.rawdata, bpbnew); uint32_t pos = firstBlock; while (1) { uint32_t items = leu16p(hdr->AS.Header+pos+18); memcpy(hdr->AS.rawdata+bpb, hdr->AS.Header+pos+20, items*4); bpb += items*4; hc->SPR += items; if (pos == lastBlock) break; pos = leu32p(hdr->AS.Header+pos+4); } hdr->SPR = lcm(hdr->SPR, hc->SPR); break; } default: // unknown hc->OnOff = 0; fprintf(stderr,"SMR/SON: channel %i ignored - unknown type %i\n",k,kind); } if (VERBOSE_LEVEL > 6) { char tmp[98-26+1]; fprintf(stdout,"[%i].delSize\t%i\n",k,lei16p(hdr->AS.Header+off)); fprintf(stdout,"[%i].nextDelBlock\t%i\n",k,leu32p(hdr->AS.Header+off+2)); fprintf(stdout,"[%i].firstBlock\t%i\n",k,leu32p(hdr->AS.Header+off+6)); fprintf(stdout,"[%i].lastBlock\t%i\n",k,leu32p(hdr->AS.Header+off+10)); fprintf(stdout,"[%i].blocks\t%i\n",k,leu16p(hdr->AS.Header+off+14)); fprintf(stdout,"[%i].nExtra\t%i\n",k,leu16p(hdr->AS.Header+off+16)); fprintf(stdout,"[%i].preTrig\t%i\n",k,lei16p(hdr->AS.Header+off+18)); fprintf(stdout,"[%i].blocksMSW\t%i\n",k,lei16p(hdr->AS.Header+off+20)); fprintf(stdout,"[%i].phySz\t%i\n",k,lei16p(hdr->AS.Header+off+22)); fprintf(stdout,"[%i].maxData\t%i\n",k,lei16p(hdr->AS.Header+off+24)); stringLength = hdr->AS.Header[off+26]; assert(stringLength < sizeof(tmp)); memcpy(tmp, hdr->AS.Header+off+26+1, 9); tmp[stringLength] = 0; fprintf(stdout,"[%i].comment\t<%s>\n",(int)k,tmp); fprintf(stdout,"[%i].maxChanTime\t%i\t%i\n",(int)k,lei32p(hdr->AS.Header+off+98),*(int32_t*)(hdr->AS.Header+off+98)); fprintf(stdout,"[%i].lChanDvd\t%i\n",(int)k,lei32p(hdr->AS.Header+off+102)); fprintf(stdout,"[%i].phyChan\t%i\n",(int)k,lei16p(hdr->AS.Header+off+106)); stringLength = hdr->AS.Header[off+108]; assert(stringLength < sizeof(tmp)); memcpy(tmp, hdr->AS.Header+off+108+1,9); tmp[stringLength] = 0; fprintf(stdout,"[%i].title\t<%s>\n",(int)k,tmp); fprintf(stdout,"[%i].idealRate\t%f\n",(int)k,lef32p(hdr->AS.Header+off+118)); fprintf(stdout,"[%i].kind\t%i\n",(int)k,*(hdr->AS.Header+off+122)); fprintf(stdout,"[%i].delSizeMSB\t%i\n",(int)k,*(hdr->AS.Header+off+123)); fprintf(stdout,"[%i].v.adc.scale\t%f\n",(int)k,lef32p(hdr->AS.Header+off+124)); fprintf(stdout,"[%i].v.adc.offset\t%f\n",(int)k,lef32p(hdr->AS.Header+off+128)); stringLength = hdr->AS.Header[off+132]; assert(stringLength < sizeof(tmp)); memcpy(tmp, hdr->AS.Header+off+132+1, 5); tmp[stringLength] = 0; fprintf(stdout,"[%i].v.adc.units\t%s\n", (int)k, tmp); fprintf(stdout,"[%i].v.adc.divide\t%i\n", (int)k, lei16p(hdr->AS.Header+off+138)); fprintf(stdout,"[%i].v.real.max\t%f\n", (int)k, lef32p(hdr->AS.Header+off+124)); fprintf(stdout,"[%i].v.real.min\t%f\n", (int)k, lef32p(hdr->AS.Header+off+128)); fprintf(stdout,"[%i].v.real.units\t%s\n", (int)k, hdr->AS.Header+off+132+1); fprintf(stdout,"[%i].v.event\t%0x\t%g\n", (int)k, leu32p(hdr->AS.Header+off+124), lef32p(hdr->AS.Header+off+124)); } } hdr->NRec = 1; hdr->AS.bpb = bpb; } stimfit-0.16.7/src/biosig/biosig4c++/t210/scp-decode.cpp0000664000175000017500000031101314752215315016047 /* $Id: scp-decode.cpp,v 1.24 2008-07-12 20:46:58 schloegl Exp $ Copyright (C) 2011,2014 Alois Schloegl Copyright (C) 2011 Stoyan Mihaylov This function is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ Modifications by Alois Schloegl Jul 2011: get rid of warnings for unitialized variables and signed/unsigned comparison Jun 2007: replaced ultoa with sprintf Aug 2007: On-The-Fly-Decompression using ZLIB Oct 2007: Consider SunOS/SPARC platform obsolete code sections marked, this reduced SegFault from 18 to 1. --------------------------------------------------------------------------- Copyright (C) 2006 Eugenio Cervesato. Developed at the Associazione per la Ricerca in Cardiologia - Pordenone - Italy, based on the work of Eugenio Cervesato & Giorgio De Odorico. The original Copyright and comments follow. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------------- ______________________________________________________________________________ scp-decode.cpp This is the "decode" module of the program SCP-AV. It opens an SCP-ECG v1.0 to v2.0 test file and extracts all the informations. Release 2.3 - feb 2006 --------------------------------------------------------------------------- ************************************************************************** ************************* original Copyright ***************************** Copyright (C) 2003-2004 Eugenio Cervesato & Giorgio De Odorico. Developed at the Associazione per la Ricerca in Cardiologia - Pordenone - Italy. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --------------------------------------------------------------------------- */ //______________________________________________________________________________ /* scp-decode.cpp This is the "decode" module of the program SCP-AV. It opens an SCP-ECG v1.3 or v2.0 test file and extracts all the informations. Developed by ING. GIORGIO DE ODORICO (giorgio.deodorico@tiscali.it) Documentation of the standard comes mainly from: http://www.centc251.org/TCMeet/doclist/TCdoc02/N02-015-prEN1064.pdf Internationalization, test, bug fix by Eugenio Cervesato (eugenio.cervesato@aopn.fvg.it) Release 2.1 - february 2004 */ // ************************* end of the original Copyright ***************************** // contribution of Michael Breuss . see 'by MB' in the sources // contribution of Stelios Sfakianakis . see 'by SS' in the sources // contribution of Federico cantini . see 'by FeC' in the sources //void remark(char *string); // #define WITH_OBSOLETE_PARTS // by E.C. 13.10.2003 part nedded to compile with gcc (Linux). // To compile with Borland C++ add the conditional define: WIN32. // In porting, I nedded to adapt fseek() and write a custom ultoa() #define COMPAT //______________________________________________________________________________ //#include #include //strcat, strcpy #include #include using namespace std; /* error handling should use error variables local to each HDR otherwise, sopen() etc. is not re-entrant. Therefore, use of variables B4C_ERRNUM and B4C_ERRMSG is deprecated; Instead, use biosigERROR for setting error status, and serror2(hdr), hdr->AS.B4C_ERRNUM, hdr->AS.B4C_ERRMSG for error handling. */ __attribute__ ((deprecated)) extern int B4C_ERRNUM; __attribute__ ((deprecated)) extern const char *B4C_ERRMSG; //______________________________________________________________________________ // FILE POINTERS #include "../biosig-dev.h" #include "structures.h" #include "codes.h" // the following define is private of Eugenio Cervesato. Please other readers ignore it! #ifdef CPPBUILDER3 #include "CPPBUILDER3.h" // inside are definitions needed to run on C++Builder GUI as a standalone module and bypass ZLIB #endif // end of private define. HDRTYPE* in; //--------------------------------------------------------------------------- static uint32_t _COUNT_BYTE=1UL; // counter of bytes read static uint32_t _DIM_FILE; // file length in byte static const uint8_t _NUM_SECTION=12U; // sections over 11 are not considered //______________________________________________________________________________ // section 2 uint8_t Input_Bit(uint8_t*,uint16_t&,uint16_t,uint8_t&,bool&); int16_t Input_Bits(uint8_t*,uint16_t&,uint16_t,uint8_t&,uint8_t,bool&); void decompress(TREE_NODE*,int16_t*,uint8_t&,uint16_t&,int32_t*,uint16_t,uint16_t&,table_H*,uint16_t*,uint16_t&); void Tree_Destroy(TREE_NODE*); TREE_NODE *Tree_Create(TREE_NODE*,uint16_t,table_H*,uint16_t); void Huffman(int32_t*,uint16_t*,uint8_t*,uint16_t&,uint16_t,table_H*,uint16_t*); void InitHuffman(table_H*); //inizialize default Huffman table //______________________________________________________________________________ // sections 3, 4, 5 and 6 template void Differences(int32_t*,t1,uint8_t); void Multiply(int32_t*,uint32_t,uint16_t); void Interpolate(int32_t*,int32_t*,f_lead,lead*,f_Res,Protected_Area*,uint32_t); void ExecFilter(int32_t*,int32_t*,uint32_t&,uint16_t); void DoFilter(int32_t*,int32_t*,f_Res,f_lead,lead*,Protected_Area*,Subtraction_Zone*); void DoAdd(int32_t*,int32_t*,f_Res,int32_t*,f_BdR0,Subtraction_Zone*,f_lead,lead*); void Opt_Filter(int32_t*, int32_t*, f_Res, f_lead, lead*, Protected_Area*); //______________________________________________________________________________ // INTERNAL FUNCTIONS char* ReadString(char*,uint16_t); //read a string char *FindString(char*,uint16_t); // calculate the length of a string and write it down int16_t Look(alfabetic*,uint16_t,uint16_t,uint16_t); //look at a number in alfabetic and give the position of the array //______________________________________________________________________________ template void ReadByte(t1&); //read a byte from stream void Skip(uint16_t); //skip some bytes //______________________________________________________________________________ uint16_t ReadCRC(); //read first 6 bytes of the file bool Check_CRC(uint16_t,uint32_t,uint32_t); // CRC check //______________________________________________________________________________ uint32_t ID_section(uint32_t, int8_t &version); //read section ID header void sectionsOptional(pointer_section*,DATA_DECODE &,DATA_RECORD&,DATA_INFO&); //handles optional sections #ifdef WITH_OBSOLETE_PARTS void section_0(pointer_section*, int size_max); //read section 0 void Init_S1(DATA_INFO &inf); void section_1(pointer_section,DATA_INFO&); //read section 1 data void section_1_0(demographic&); //read tag 0 of section 1 void section_1_1(demographic&); //read tag 1 of section 1 void section_1_2(demographic&); // ... and so on ... void section_1_3(demographic&); void section_1_4(demographic&); void section_1_5(demographic&); void section_1_6(demographic&); void section_1_7(demographic&); void section_1_8(demographic&); void section_1_9(demographic&); void section_1_10(clinic&,uint16_t&); void section_1_11(demographic&); void section_1_12(demographic&); void section_1_13(clinic&,uint16_t&); void section_1_14(descriptive&); void section_1_15(descriptive&); void section_1_16(descriptive&); void section_1_17(descriptive&); void section_1_18(descriptive&); void section_1_19(descriptive&); void section_1_20(clinic&); void section_1_21(clinic&); void section_1_22(clinic&); void section_1_23(descriptive&); void section_1_24(descriptive&); void section_1_25(device&); void section_1_26(device&); void section_1_27(device&); void section_1_28(device&); void section_1_29(device&); void section_1_30(clinic&,uint16_t&); void section_1_31(device&); void section_1_32(clinic&,uint16_t&, int8_t version); void section_1_33(device&); void section_1_34(device&); void section_1_35(clinic&,uint16_t&); void section_1_(); //skip tags of the manufacturer of the section 1 void section_1_255(); //read tag 255 of section 1 void section_7(pointer_section,DATA_RECORD&, int8_t version); //read section 7 void section_8(pointer_section,DATA_INFO&); //read section 8 void section_10(pointer_section,DATA_RECORD&, int8_t version); //read section 10 void section_11(pointer_section,DATA_INFO&); //read section 11 #endif void section_2(pointer_section,DATA_DECODE&); //read section 2 void section_3(pointer_section,DATA_DECODE&, int8_t version); //read section 3 void section_4(pointer_section,DATA_DECODE&, int8_t version); //read section 4 bool section_5(pointer_section,DATA_DECODE&,bool); //read section 5 void section_6(pointer_section,DATA_DECODE&,bool); //read section 6 //______________________________________________________________________________ void Decode_Data(pointer_section*,DATA_DECODE&,bool&); //______________________________________________________________________________ #define STR_NULL StrNull() void *FreeWithCare(void*P){ //Stoyan - else I got problems with some scp files - prestandart or so if(P) free(P); return NULL; } void *mymalloc(size_t size) // by E.C. 07.11.2003 this is a workaround for a bug { // present somewhere in memory allocation. // char buff[30]; // this problem should be fixed next! // ultoa(size, buff, 10); // used for debug purposes, shows the size // remark(buff); // fprintf(stdout,"MYMEMALLOC: %i\n",size); // void *res=malloc(size*2); // this way each time a doubled memory is requested. And it works!! void *res=malloc(size); return res; } const int StrNullLen=strlen(" unspecified/unknown "); char * StrNull(){ //Stoyan this way we can release everything char*Ret=(char*)mymalloc(StrNullLen+4); strcpy(Ret," unspecified/unknown "); return Ret; } /* moved by MB must be declared before first call (otherwise compiler error) */ //--------------------------------BYTE & BIT------------------------------------ template void ReadByte(t1 &number) { //read the requested number of bytes and //convert in decimal, taking into account that the first byte is the LSB. //the sign of the number is kept uint8_t *num, dim=sizeof(t1); uint8_t mask=0xFF; if(dim!=0 && (num=(uint8_t*)mymalloc(dim))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } ifread(num,dim,1,in); // *num = *(uint8_t*)(in->AS.Header+_COUNT_BYTE); number=0; _COUNT_BYTE+=dim; while((dim--)>0) { number<<=8; number+=num[dim]&mask; } free(num); }//end ReadByte // MAIN EXTERN_C void sopen_SCP_clean(struct DATA_DECODE *decode, struct DATA_RECORD *record, struct DATA_INFO *textual) { FreeWithCare(decode->length_BdR0); FreeWithCare(decode->samples_BdR0); FreeWithCare(decode->length_Res); FreeWithCare(decode->samples_Res); FreeWithCare(decode->t_Huffman); FreeWithCare(decode->flag_Huffman); FreeWithCare(decode->data_lead); FreeWithCare(decode->data_protected); FreeWithCare(decode->data_subtraction); FreeWithCare(decode->Median); FreeWithCare(decode->Residual); FreeWithCare(decode->Reconstructed); FreeWithCare(record->data_spike); FreeWithCare(record->type_BdR); FreeWithCare(record->data_BdR); FreeWithCare(record->data_additional); FreeWithCare(record->lead_block); FreeWithCare(textual->text_dim); FreeWithCare(textual->data_statement); FreeWithCare(textual->text_statement); FreeWithCare(textual->ana.last_name); FreeWithCare(textual->ana.first_name); FreeWithCare(textual->ana.ID); FreeWithCare(textual->ana.second_last_name); FreeWithCare(textual->cli.text_drug); FreeWithCare(textual->cli.text_diagnose); FreeWithCare(textual->cli.referring_physician); FreeWithCare(textual->cli.latest_confirming_physician); FreeWithCare(textual->cli.technician_description); FreeWithCare(textual->cli.text_free_text); FreeWithCare(textual->cli.text_free_medical_hystory); FreeWithCare(textual->cli.medical_hystory); FreeWithCare(textual->cli.free_text); FreeWithCare(textual->cli.drug); FreeWithCare(textual->des.acquiring.model_description); FreeWithCare(textual->des.acquiring.analysing_program_revision_number); FreeWithCare(textual->des.acquiring.serial_number_device); FreeWithCare(textual->des.acquiring.device_system_software); FreeWithCare(textual->des.acquiring.device_SCP_implementation_software); FreeWithCare(textual->des.acquiring.manifacturer_trade_name); FreeWithCare(textual->des.analyzing.model_description); FreeWithCare(textual->des.analyzing.analysing_program_revision_number); FreeWithCare(textual->des.analyzing.serial_number_device); FreeWithCare(textual->des.analyzing.device_system_software); FreeWithCare(textual->des.analyzing.device_SCP_implementation_software); FreeWithCare(textual->des.analyzing.manifacturer_trade_name); FreeWithCare(textual->des.acquiring_institution); FreeWithCare(textual->des.analyzing_institution); FreeWithCare(textual->des.acquiring_department); FreeWithCare(textual->des.analyzing_department); FreeWithCare(textual->des.room); FreeWithCare(textual->dev.sequence_number); FreeWithCare((char*)textual->dev.TZ.description); } //There is serious problem if we try to transfer whole structures between c and c++. I am not sure were exactly it is, but using pointers - solve it. extern C is not enough. Stoyan EXTERN_C int scp_decode(HDRTYPE* hdr, pointer_section *section, struct DATA_DECODE *decode, struct DATA_RECORD *info_recording, struct DATA_INFO *info_textual, bool add_filter) { uint16_t CRC; uint32_t pos; if (hdr->FILE.OPEN) { ifseek(hdr,0,SEEK_SET); } else hdr = ifopen(hdr,"rb"); if (!hdr->FILE.OPEN) { fprintf(stdout,"Cannot open the file %s.\n",hdr->FileName); return FALSE; // by E.C. 15.10.2003 now return FALSE } in = hdr; _COUNT_BYTE=1UL; CRC=ReadCRC(); pos=_COUNT_BYTE; ReadByte(_DIM_FILE); // if (CRC != 0xFFFF) Check_CRC(CRC,pos,_DIM_FILE-2U); // by E.C. may 2004 CARDIOLINE 1.0 ifseek(in, 0L, SEEK_SET); //mandatory sections #ifdef WITH_OBSOLETE_PARTS section_0(section, _DIM_FILE); // by E.C. may 2004 check file size section_1(section[1],*info_textual); sectionsOptional(section,*decode,*info_recording,*info_textual); #else if (section[2].length>0) section_2(section[2],*decode); //HUFFMAN if (section[3].length>0) section_3(section[3],*decode,hdr->aECG->Section1.Tag14.VERSION); //lead if (section[4].length) section_4(section[4],*decode,hdr->aECG->Section1.Tag15.VERSION); // fiducial locations if (section[5].length) if (!section_5(section[5],*decode,section[2].length)) section[5].length=0 ; //type 0 median beat if (section[6].length) section_6(section[6],*decode,section[2].length); //rhythm compressed data #endif ifclose(in); Decode_Data(section,*decode,add_filter); return TRUE; // by E.C. 15.10.2003 now return TRUE } //______________________________________________________________________________ // COMPUTATIONAL FUNCTIONS #ifdef WITH_OBSOLETE_PARTS //------------------------------STRINGS---------------------------------------- char *ReadString(char *temp_string, uint16_t num) //read a string from the stream. //the first extracted byte is written for fist. //each byte read from the stream is first "transformed" in char. { if(temp_string) free(temp_string); if(!num) return NULL;//before alocating memory, which will be loosed in case of num=0 if((temp_string=(char*)mymalloc(sizeof(char)*(num+2)))==NULL) // by E.C. 26.02.2004 one more byte { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return NULL; } _COUNT_BYTE+=num; ifread(temp_string,sizeof(char),num,in); if (temp_string[num-1]!='\0') temp_string[num]='\0'; return temp_string; }//end ReadString int16_t Look(alfabetic *code_, uint16_t a, uint16_t b, uint16_t key_) // look num in code_.number and give the element position { uint16_t middle=(a+b)/2U; if(code_[middle].number==key_) return middle; if(a>=b) return -1; if(code_[middle].number0U) ifseek(in,num,1U); _COUNT_BYTE+=num; }//end Skip //______________________________________________________________________________ // INITIALIZATION FUNCTIONS void InitHuffman(table_H *riga) //build the default Huffman table { /* The table is contructed as stated in the protocol SCP-ECG; each structure in each line. Columns are: bit_prefix = number of bits in the prefix bit_code = number of bits in the code TMS = table mode base_value = base value (decoded) cp = prefix code (in bits) base_code = decimal value of reversed cp From the stream I take a bit at a time until I find a correspondent value in the Huffman table. If: nbp=nbc the decode value is vb nbp!=nbc if m=1 I take nbc-nbp bits next in the stream if m=0 change to table vb Remark: Huffman tables stored in the stream contain vb in 2 complemented bytes. The decimal value of cp is included. Furthermore, always the MSB comes first! In my Huffman tables I set cp as a decimal value. Infact, I read a group of bits from the stream and convert them by multipying by 2^pos (where pos is 0 for bit 0, 1 for bit 1 and so on). So I read bits as they are. DEFAULT HUFFMAN TABLE nbp nbc m vb cp10 cp 1, 1, 1, 0, 0, 0, 3, 3, 1, 1, 1, 4, 3, 3, 1, -1, 5, 5, 4, 4, 1, 2, 3, 12, 4, 4, 1, -2, 11, 13, 5, 5, 1, 3, 7, 28, 5, 5, 1, -3, 23, 29, 6, 6, 1, 4, 15, 60, 6, 6, 1, -4, 47, 61, 7, 7, 1, 5, 31, 124, 7, 7, 1, -5, 95, 125, 8, 8, 1, 6, 63, 252, 8, 8, 1, -6, 191, 253, 9, 9, 1, 7, 127, 508, 9, 9, 1, -7, 383, 509, 10, 10, 1, 8, 255, 1020, 10, 10, 1, -8, 767, 1021, 10, 18, 1, 0, 511, 1022, 10, 26, 1, 0, 1023, 1023, */ uint8_t i; i= 0U; riga[i].bit_prefix= 1U; riga[i].bit_code= 1U; riga[i].TMS=1U; riga[i].base_value= 0; riga[i].base_code= 0UL; i= 1U; riga[i].bit_prefix= 3U; riga[i].bit_code= 3U; riga[i].TMS=1U; riga[i].base_value= 1; riga[i].base_code= 1UL; i= 2U; riga[i].bit_prefix= 3U; riga[i].bit_code= 3U; riga[i].TMS=1U; riga[i].base_value=-1; riga[i].base_code= 5UL; i= 3U; riga[i].bit_prefix= 4U; riga[i].bit_code= 4U; riga[i].TMS=1U; riga[i].base_value= 2; riga[i].base_code= 3UL; i= 4U; riga[i].bit_prefix= 4U; riga[i].bit_code= 4U; riga[i].TMS=1U; riga[i].base_value=-2; riga[i].base_code= 11UL; i= 5U; riga[i].bit_prefix= 5U; riga[i].bit_code= 5U; riga[i].TMS=1U; riga[i].base_value= 3; riga[i].base_code= 7UL; i= 6U; riga[i].bit_prefix= 5U; riga[i].bit_code= 5U; riga[i].TMS=1U; riga[i].base_value=-3; riga[i].base_code= 23UL; i= 7U; riga[i].bit_prefix= 6U; riga[i].bit_code= 6U; riga[i].TMS=1U; riga[i].base_value= 4; riga[i].base_code= 15UL; i= 8U; riga[i].bit_prefix= 6U; riga[i].bit_code= 6U; riga[i].TMS=1U; riga[i].base_value=-4; riga[i].base_code= 47UL; i= 9U; riga[i].bit_prefix= 7U; riga[i].bit_code= 7U; riga[i].TMS=1U; riga[i].base_value= 5; riga[i].base_code= 31UL; i=10U; riga[i].bit_prefix= 7U; riga[i].bit_code= 7U; riga[i].TMS=1U; riga[i].base_value=-5; riga[i].base_code= 95UL; i=11U; riga[i].bit_prefix= 8U; riga[i].bit_code= 8U; riga[i].TMS=1U; riga[i].base_value= 6; riga[i].base_code= 63UL; i=12U; riga[i].bit_prefix= 8U; riga[i].bit_code= 8U; riga[i].TMS=1U; riga[i].base_value=-6; riga[i].base_code= 191UL; i=13U; riga[i].bit_prefix= 9U; riga[i].bit_code= 9U; riga[i].TMS=1U; riga[i].base_value= 7; riga[i].base_code= 127UL; i=14U; riga[i].bit_prefix= 9U; riga[i].bit_code= 9U; riga[i].TMS=1U; riga[i].base_value=-7; riga[i].base_code= 383UL; i=15U; riga[i].bit_prefix=10U; riga[i].bit_code=10U; riga[i].TMS=1U; riga[i].base_value= 8; riga[i].base_code= 255UL; i=16U; riga[i].bit_prefix=10U; riga[i].bit_code=10U; riga[i].TMS=1U; riga[i].base_value=-8; riga[i].base_code= 767UL; i=17U; riga[i].bit_prefix=10U; riga[i].bit_code=18U; riga[i].TMS=1U; riga[i].base_value= 0; riga[i].base_code= 511UL; i=18U; riga[i].bit_prefix=10U; riga[i].bit_code=26U; riga[i].TMS=1U; riga[i].base_value= 0; riga[i].base_code=1023UL; }//end InitHuffman //______________________________________________________________________________ // handle sections uint16_t ReadCRC() // read the CRC of the entire file or of a section and convert it to decimal. { uint16_t dim; ReadByte(dim); return dim; }//end ReadCRC bool Check_CRC(uint16_t CRC, uint32_t pos, uint32_t length) /* CRC check starting from pos for Length Remark: all computations are in byte. A = new byte B = temp byte CRCHI = MSB of the CRC (16 bits) CRCLO = LSB of the CRC START: for A=first_byte to last_byte in block do: A = A xor CRCHI CRCHI = A shift A right 4 times {fulfill with zeroes} A = A xor CRCHI {I J K L M N O P} CRCHI = CRCLO {swap CRCHI, CRCLO} CRCLO = A rotate A left 4 times {M N O P I J K L} B = A { temp save } rotate A left once { N O P I J K L M } A = A and $1F { 0 0 0 I J L L M } CRCHI = A xor CRCHI A = B and $F0 { M N O P 0 0 0 0 } CRCHI = A xor CRCHI { CRCHI complete } rotate B left once { N O P 0 0 0 0 M } B = B and $E0 { N O P 0 0 0 0 0 } CRCLO = B xor CRCLO { CRCLO complete } end Final check on the CRC is accomplished by adding or concatenating CRCHI and CRCLO at the end of the data stream. Calculating the checksum of the resulting data stream shall result in a zero CRC if the data was correctly received. */ { uint32_t i; uint8_t A, B; uint8_t CRCLO, CRCHI; CRCLO=0xFF; CRCHI=0xFF; ifseek(in,pos-1,0U); for(i=1;i<=length;i++) { A=ifgetc(in); A^=CRCHI; A^=(A>>4); CRCHI=CRCLO; CRCLO=A; A=(A<<4)|(A>>4U); B=A; A=(A<<1)|(A>>7U); A&=0x1F; CRCHI^=A; A=B&0xF0; CRCHI^=A; B=(B<<1)|(B>>7U); B&=0xE0; CRCLO^=B; }//end for CRCLO-=CRC%256UL; CRCHI-=CRC/256UL; if ((CRCLO==CRCHI) && (CRCLO==0)) return 1; else { fprintf(stderr,"Cannot read the file: BAD CRC.\n"); // exit(2); return 0; } }//end Check_CRC uint32_t ID_section(uint32_t pos, int8_t &version) //read section Header { uint32_t dim; uint16_t CRC; CRC=ReadCRC(); Skip(2U); ReadByte(dim); // if (CRC != 0xFFFF) Check_CRC(CRC,pos+2,dim-2); // by E.C. may 2004 CARDIOLINE 1.0 ifseek(in,pos+7L,0); ReadByte(version); // by E.C. may 2004 store the version number Skip(7U); return dim; }//end ID_section void sectionsOptional(pointer_section *section, DATA_DECODE &block1, DATA_RECORD &block2, DATA_INFO &block3) //handles optional sections { uint8_t i=0, bimodal; //initialization block1.t_Huffman=NULL; block1.flag_Huffman=NULL; block1.data_lead=NULL; block1.data_protected=NULL; block1.data_subtraction=NULL; block1.length_BdR0=NULL; block1.samples_BdR0=NULL; block1.Median=NULL; block1.length_Res=NULL; block1.samples_Res=NULL; block1.Residual=NULL; // block1.Reconstructed=NULL; block2.data_spike=NULL; block2.type_BdR=NULL; block2.data_BdR=NULL; block2.data_additional=NULL; block2.lead_block=NULL; block3.text_dim=NULL; block3.text_report=NULL; block3.data_statement=NULL; block3.text_statement=NULL; //variables inizialization block1.flag_lead.number=0; block1.flag_lead.subtraction=0; block1.flag_lead.all_simultaneously=0; block1.flag_lead.number_simultaneously=0; block1.flag_BdR0.length=0; block1.flag_BdR0.fcM=0; block1.flag_BdR0.AVM=0; block1.flag_BdR0.STM=0; block1.flag_BdR0.number_samples=0; block1.flag_BdR0.encoding=0; block1.flag_Res.AVM=0; block1.flag_Res.STM=0; block1.flag_Res.number=0; block1.flag_Res.number_samples=0; block1.flag_Res.encoding=0; block1.flag_Res.bimodal=0; block1.flag_Res.decimation_factor=0; block2.data_global.number=0; block2.data_global.number_QRS=0; block2.data_global.number_spike=0; block2.data_global.average_RR=0; block2.data_global.average_PP=0; block2.data_global.ventricular_rate=0; block2.data_global.atrial_rate=0; block2.data_global.QT_corrected=0; block2.data_global.formula_type=0; block2.data_global.number_tag=0; block2.header_lead.number_lead=0; block2.header_lead.number_lead_measurement=0; while(i<_NUM_SECTION) { if(section[i].ID) switch(section[i].ID) { case 2: if(section[i].length) section_2(section[i],block1); //HUFFMAN break; case 3: if(section[i].length) section_3(section[i],block1,block3.des.acquiring.protocol_revision_number); //lead break; case 4: if(section[i].length) { if((block3.des.acquiring.protocol_revision_number>10) && section[6].length) // by E.C. 27.02.2004 whole section to be included in {} ! { ifseek(in,section[6].index+22,0); ReadByte(bimodal); block1.flag_Res.bimodal=bimodal; } else block1.flag_Res.bimodal=0; section_4(section[i],block1,block3.des.analyzing.protocol_revision_number); // fiducial locations } break; case 5: if(section[i].length) if (!section_5(section[i],block1,section[2].length)) section[i].length=0 ; //type 0 median beat break; case 6: if(section[i].length) section_6(section[i],block1,section[2].length); //rhythm compressed data break; #ifdef WITH_OBSOLETE_PARTS /* case 7: if(section[i].length) section_7(section[i],block2,block3.des.acquiring.protocol_revision_number); //global measurements break; case 8: if(section[i].length) section_8(section[i],block3); //full text interpretative statements break; case 10:if(section[i].length) section_10(section[i],block2,block3.des.acquiring.protocol_revision_number); //lead measurement block break; case 11:if(section[i].length) //universal ECG interpretative statements // section_11(section[i],block3); break; */ #endif }//end switch ++i; }//end while }//end sectionsOptional //______________________________________________________________________________ // sections //______________________________________________________________________________ #ifdef WITH_OBSOLETE_PARTS //______________________________________________________________________________ // section 0 //______________________________________________________________________________ void section_0(pointer_section *info, int size_max) // section 0 //build info_sections with ID, offset and length of each section { uint32_t pos, dim, ini; uint16_t ind; uint8_t i; int8_t version; ifseek(in,6L,0); pos=ID_section(7L, version)+7L; //length + offset _COUNT_BYTE=7L+16L; for(i=0;i<_NUM_SECTION;i++) { info[i].ID=0; info[i].length=0L; info[i].index=0L; } while((_COUNT_BYTE+10)<=pos) { ReadByte(ind); if(ind>11U) Skip(8U); else { ReadByte(dim); if(dim) { ReadByte(ini); if (ini<(unsigned)size_max) { // by E.C. may 2004 check overflow of file info[ind].ID=ind; info[ind].length=dim; info[ind].index=ini; } }//end if dim else Skip(4U); }//end else }//end while }//end section_0 //______________________________________________________________________________ // section 1 //______________________________________________________________________________ void Init_S1(DATA_INFO &inf) { inf.ana.last_name=STR_NULL; inf.ana.first_name=STR_NULL; inf.ana.ID=STR_NULL; inf.ana.second_last_name=STR_NULL; inf.ana.age.value=0; inf.ana.age.unit=0; inf.ana.height.value=0; inf.ana.height.unit=0; inf.ana.weight.value=0; inf.ana.weight.unit=0; inf.ana.sex=0; inf.ana.race=0; inf.ana.systolic_pressure=0; inf.ana.diastolic_pressure=0; inf.cli.number_drug=0; inf.cli.text_drug=STR_NULL; inf.cli.number_diagnose=0; inf.cli.text_diagnose=STR_NULL; inf.cli.referring_physician=STR_NULL; inf.cli.latest_confirming_physician=STR_NULL; inf.cli.technician_description=STR_NULL; inf.cli.number_text=0; inf.cli.text_free_text=STR_NULL; inf.cli.number_hystory=0; inf.cli.number_free_hystory=0; inf.cli.text_free_medical_hystory=STR_NULL; inf.cli.free_text=NULL; inf.cli.medical_hystory=NULL; inf.cli.drug=NULL; inf.des.acquiring.institution_number=0; inf.des.acquiring.department_number=0; inf.des.acquiring.ID=0; inf.des.acquiring.type=2; inf.des.acquiring.manifacturer=0; inf.des.acquiring.model_description=STR_NULL; inf.des.acquiring.protocol_revision_number=0; inf.des.acquiring.category=255; inf.des.acquiring.language=255; inf.des.acquiring.capability[0]=1; inf.des.acquiring.capability[1]=2; inf.des.acquiring.capability[2]=3; inf.des.acquiring.capability[3]=4; inf.des.acquiring.AC=0; inf.des.acquiring.analysing_program_revision_number=STR_NULL; inf.des.acquiring.serial_number_device=STR_NULL; inf.des.acquiring.device_system_software=STR_NULL; inf.des.acquiring.device_SCP_implementation_software=STR_NULL; inf.des.acquiring.manifacturer_trade_name=STR_NULL; inf.des.analyzing.institution_number=0; inf.des.analyzing.department_number=0; inf.des.analyzing.ID=0; inf.des.analyzing.type=2; inf.des.analyzing.manifacturer=0; inf.des.analyzing.model_description=STR_NULL; inf.des.analyzing.protocol_revision_number=0; inf.des.analyzing.category=255; inf.des.analyzing.language=255; inf.des.analyzing.capability[0]=1; inf.des.analyzing.capability[1]=2; inf.des.analyzing.capability[2]=3; inf.des.analyzing.capability[3]=4; inf.des.analyzing.AC=0; inf.des.analyzing.analysing_program_revision_number=STR_NULL; inf.des.analyzing.serial_number_device=STR_NULL; inf.des.analyzing.device_system_software=STR_NULL; inf.des.analyzing.device_SCP_implementation_software=STR_NULL; inf.des.analyzing.manifacturer_trade_name=STR_NULL; inf.des.acquiring_institution=STR_NULL; inf.des.analyzing_institution=STR_NULL; inf.des.acquiring_department=STR_NULL; inf.des.analyzing_department=STR_NULL; inf.des.room=STR_NULL; inf.des.stat_code=0; inf.dev.baseline_filter=0; inf.dev.lowpass_filter=0; inf.dev.other_filter[0]=0; inf.dev.other_filter[1]=0; inf.dev.other_filter[2]=0; inf.dev.other_filter[3]=0; inf.dev.sequence_number=STR_NULL; inf.dev.electrode_configuration.value=0; inf.dev.electrode_configuration.unit=0; inf.dev.TZ.offset=0; inf.dev.TZ.index=0; inf.dev.TZ.description=STR_NULL; } void section_1(pointer_section info_sections, DATA_INFO &inf) // section 1 { uint8_t tag; uint32_t num=info_sections.length+_COUNT_BYTE; uint16_t dim=0U; int8_t version; _COUNT_BYTE=info_sections.index; ifseek(in,info_sections.index-1,0); ID_section(info_sections.index, version); Init_S1(inf); do { ReadByte(tag); switch(tag) { case 0: section_1_0(inf.ana); break; case 1: section_1_1(inf.ana); break; case 2: section_1_2(inf.ana); break; case 3: section_1_3(inf.ana); break; case 4: section_1_4(inf.ana); break; case 5: section_1_5(inf.ana); break; case 6: section_1_6(inf.ana); break; case 7: section_1_7(inf.ana); break; case 8: section_1_8(inf.ana); break; case 9: section_1_9(inf.ana); break; case 10: if(!inf.cli.number_drug) { inf.cli.drug=NULL; inf.cli.text_drug=(char*)FreeWithCare(inf.cli.text_drug); dim=0; } section_1_10(inf.cli,dim); break; case 11: section_1_11(inf.ana); break; case 12: section_1_12(inf.ana); break; case 13: if(!inf.cli.number_diagnose) { inf.cli.diagnose=NULL; inf.cli.text_diagnose=(char*)FreeWithCare(inf.cli.text_diagnose); dim=0; } section_1_13(inf.cli,dim); break; case 14: section_1_14(inf.des); break; case 15: section_1_15(inf.des); break; case 16: section_1_16(inf.des); break; case 17: section_1_17(inf.des); break; case 18: section_1_18(inf.des); break; case 19: section_1_19(inf.des); break; case 20: section_1_20(inf.cli); break; case 21: section_1_21(inf.cli); break; case 22: section_1_22(inf.cli); break; case 23: section_1_23(inf.des); break; case 24: section_1_24(inf.des); break; case 25: section_1_25(inf.dev); break; case 26: section_1_26(inf.dev); break; case 27: section_1_27(inf.dev); break; case 28: section_1_28(inf.dev); break; case 29: section_1_29(inf.dev); break; case 30: if(!inf.cli.number_text) { inf.cli.text_free_text=(char*)FreeWithCare(inf.cli.text_free_text); dim=0; } section_1_30(inf.cli,dim); break; case 31: section_1_31(inf.dev); break; case 32: if(!inf.cli.number_hystory) { inf.cli.medical_hystory=NULL; dim=0; } section_1_32(inf.cli,dim,inf.des.acquiring.protocol_revision_number); break; case 33: section_1_33(inf.dev); break; case 34: section_1_34(inf.dev); break; case 35: if(!inf.cli.number_free_hystory) { inf.cli.free_medical_hystory=NULL; inf.cli.text_free_medical_hystory=(char*)FreeWithCare(inf.cli.text_free_medical_hystory); dim=0; } section_1_35(inf.cli,dim); break; case 255: section_1_255(); break; default: section_1_(); break; }//end switch }//end do while((tag!=255) && (_COUNT_BYTE0)) inf.des.analyzing.protocol_revision_number=version; // by E.C. may 2004 CARDIOLINE 1.0 }//end section_1 void section_1_0(demographic &ana) // section 1 tag 0 { uint16_t dim; ReadByte(dim); ana.last_name=ReadString(ana.last_name,dim); }//end section_1_0 void section_1_1(demographic &ana) // section 1 tag 1 { uint16_t dim; ReadByte(dim); ana.first_name=ReadString(ana.first_name,dim); }//end section_1_1 void section_1_2(demographic &ana) //section 1 tag 2 { uint16_t dim; ReadByte(dim); ana.ID=ReadString(ana.ID,dim); }//end section_1_2 void section_1_3(demographic &ana) // section 1 tag 3 { uint16_t dim; ReadByte(dim); ana.second_last_name=ReadString(ana.second_last_name,dim); }//end section_1_3 void section_1_4(demographic &ana) // section 1 tag 4 { uint16_t dim; ReadByte(dim); ReadByte(ana.age.value); ReadByte(ana.age.unit); if(ana.age.unit>5) ana.age.unit=0; }//end section_1_4 void section_1_5(demographic &ana) // section 1 tag 5 { uint16_t dim; uint8_t m, g; uint16_t a; ReadByte(dim); ReadByte(a); ReadByte(m); ReadByte(g); struct tm tmf; // by E.C. feb 2006 tmf.tm_year = a - 1900; tmf.tm_mon = m - 1; tmf.tm_mday = g; tmf.tm_hour = 0; tmf.tm_min = 0; tmf.tm_sec = 0; tmf.tm_isdst = 0; ana.date_birth2 = mktime(&tmf); // store date in native format }//end section_1_5 void section_1_6(demographic &ana) // section 1 tag 6 { uint16_t dim; ReadByte(dim); ReadByte(ana.height.value); ReadByte(ana.height.unit); if(ana.height.unit>3) ana.height.unit=0; }//end section_1_6 void section_1_7(demographic &ana) // section 1 tag 7 { uint16_t dim; ReadByte(dim); ReadByte(ana.weight.value); ReadByte(ana.weight.unit); if(ana.weight.unit>4) ana.weight.unit=0; }//end section_1_7 void section_1_8(demographic &ana) // section 1 tag 8 { uint16_t dim; ReadByte(dim); ReadByte(ana.sex); if(ana.sex>2) ana.sex=3; }//end section_1_8 void section_1_9(demographic &ana) // section 1 tag 9 { uint16_t dim; ReadByte(dim); ReadByte(ana.race); if(ana.race>3) ana.race=0; }//end section_1_9 void section_1_10(clinic &cli, uint16_t &dim) // section 1 tag 10 { uint16_t val; uint8_t code_; char *temp_string=NULL, *pos_char; int16_t pos; ReadByte(val); /* this tag may have more instances; each instance have a: table code (1 byte), class code (1 byte) drug code (1 byte), text description of the drug (at least 1 byte with NULL). */ if(val) { if((cli.drug=(info_drug*)realloc(cli.drug,sizeof(info_drug)*(cli.number_drug+1)))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } ReadByte(cli.drug[cli.number_drug].table); ReadByte(code_); if(!cli.drug[cli.number_drug].table) { pos=Look(class_drug,0,15,code_); if(pos<=0) cli.drug[cli.number_drug].classes=0; else cli.drug[cli.number_drug].classes=pos; } else cli.drug[cli.number_drug].classes=code_; ReadByte(cli.drug[cli.number_drug].drug_code ); if(!cli.drug[cli.number_drug].table) { code_=cli.drug[cli.number_drug].drug_code +256*cli.drug[cli.number_drug].classes; pos=Look(class_drug,16,88,code_); if(pos<0) pos=0; cli.drug[cli.number_drug].drug_code =pos; } cli.drug[cli.number_drug].length=val-3; //string length + NULL if(cli.drug[cli.number_drug].length) { temp_string=ReadString(temp_string,cli.drug[cli.number_drug].length); strcat(temp_string,STR_END); dim+=strlen(temp_string); if((cli.text_drug=(char*)realloc(cli.text_drug,sizeof(char)*(dim+1)))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } pos_char=cli.text_drug; pos_char+=dim-strlen(temp_string); strcpy(pos_char,temp_string); free(temp_string); } cli.number_drug++; } }//end section_1_10 void section_1_11(demographic &ana) // section 1 tag 11 { uint16_t dim; ReadByte(dim); if(dim) ReadByte(ana.systolic_pressure); else ana.systolic_pressure=0; }//end section_1_11 void section_1_12(demographic &ana) // section 1 tag 12 { uint16_t dim; ReadByte(dim); if(dim) ReadByte(ana.diastolic_pressure); else ana.diastolic_pressure=0; }//end section_1_12 void section_1_13(clinic &cli, uint16_t &dim) // section 1 tag 13 { uint16_t val; char *temp_string=NULL, *pos_char; ReadByte(val); if(val) { if((cli.diagnose=(numeric*)realloc(cli.diagnose,sizeof(numeric)*(cli.number_diagnose+1)))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } cli.diagnose[cli.number_diagnose].unit=cli.number_diagnose+1; cli.diagnose[cli.number_diagnose].value=val; temp_string=ReadString(temp_string,cli.diagnose[cli.number_diagnose].value); strcat(temp_string,STR_END); dim+=strlen(temp_string); if((cli.text_diagnose=(char*)realloc(cli.text_diagnose,dim+1))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } pos_char=cli.text_diagnose; pos_char+=dim-strlen(temp_string); strcpy(pos_char,temp_string); free(temp_string); cli.number_diagnose++; } }//end section_1_13 void section_1_14(descriptive &des) // section 1 tag 14 { uint16_t dim, dim_to_skip; uint8_t i, mask, code_; int16_t pos; //fpos_t filepos, filepos_iniz; long filepos, filepos_iniz; ReadByte(dim); filepos = iftell(in); //FGETPOS(in,&filepos); //FGETPOS(in,&filepos_iniz); // by E.C. may 2004 ESAOTE save to reposition at the end of this section filepos_iniz=filepos; dim_to_skip=dim; dim+=filepos COMPAT; ReadByte(des.acquiring.institution_number); ReadByte(des.acquiring.department_number); ReadByte(des.acquiring.ID); ReadByte(des.acquiring.type); if(des.acquiring.type>1) des.acquiring.type=2; ReadByte(des.acquiring.manifacturer); if(des.acquiring.manifacturer>20 && des.acquiring.manifacturer!=255) des.acquiring.manifacturer=0; des.acquiring.model_description=ReadString(des.acquiring.model_description,6); ReadByte(des.acquiring.protocol_revision_number); ReadByte(des.acquiring.category); pos=Look(compatibility,0,3,des.acquiring.category); if(pos<0) pos=4; des.acquiring.category=pos; ReadByte(code_); if(code_<128U) pos=0; else if((code_<192U) && (code_>=128U)) pos=1; else { pos=Look(language_code,2,15,code_); if(pos<0) pos=16; } des.acquiring.language=pos; ReadByte(code_); mask=0x10; for(i=0;i<4;i++) { if(code_&mask) des.acquiring.capability[i]=i+4; else des.acquiring.capability[i]=i; mask<<=1; } ReadByte(des.acquiring.AC); if(des.acquiring.AC>2) des.acquiring.AC=0; Skip(16); des.acquiring.analysing_program_revision_number=(char*)FreeWithCare(des.acquiring.analysing_program_revision_number); des.acquiring.serial_number_device=(char*)FreeWithCare(des.acquiring.serial_number_device); des.acquiring.device_system_software=(char*)FreeWithCare(des.acquiring.device_system_software); des.acquiring.device_SCP_implementation_software=(char*)FreeWithCare(des.acquiring.device_SCP_implementation_software); des.acquiring.manifacturer_trade_name=(char*)FreeWithCare(des.acquiring.manifacturer_trade_name); ReadByte(i); if(!i) des.acquiring.analysing_program_revision_number=(char*)FreeWithCare(des.acquiring.analysing_program_revision_number); else des.acquiring.analysing_program_revision_number=ReadString(des.acquiring.analysing_program_revision_number,i); filepos = iftell(in); //FGETPOS(in,&filepos); des.acquiring.serial_number_device=FindString(des.acquiring.serial_number_device,dim-filepos COMPAT); if ((des.acquiring.protocol_revision_number==10) || (des.acquiring.protocol_revision_number==11)) // by E.C. may 2004 CARDIOLINE 1.0 & ESAOTE 1.1 ifseek(in,filepos_iniz COMPAT +dim_to_skip,0); // reposition file pointer else { filepos = iftell(in); //FGETPOS(in,&filepos); des.acquiring.device_system_software=FindString(des.acquiring.device_system_software,dim-filepos COMPAT); filepos = iftell(in); //FGETPOS(in,&filepos); des.acquiring.device_SCP_implementation_software=FindString(des.acquiring.device_SCP_implementation_software,dim-filepos COMPAT); filepos = iftell(in); //FGETPOS(in,&filepos); des.acquiring.manifacturer_trade_name=FindString(des.acquiring.manifacturer_trade_name,dim-filepos COMPAT); } }//end section_1_14 void section_1_15(descriptive &des) // section 1 tag 15 { uint16_t dim; uint8_t i, mask, code_; int16_t pos; //fpos_t filepos; long filepos; ReadByte(dim); filepos = iftell(in); //FGETPOS(in,&filepos); dim+=filepos COMPAT; ReadByte(des.analyzing.institution_number); ReadByte(des.analyzing.department_number); ReadByte(des.analyzing.ID); ReadByte(des.analyzing.type); if(des.analyzing.type>1) des.analyzing.type=2; ReadByte(des.analyzing.manifacturer); if(des.analyzing.manifacturer>20 && des.analyzing.manifacturer!=255) des.analyzing.manifacturer=0; des.analyzing.model_description=ReadString(des.analyzing.model_description,6); ReadByte(des.analyzing.protocol_revision_number); ReadByte(des.analyzing.category); pos=Look(compatibility,0,3,des.analyzing.category); if(pos<0) pos=4; des.analyzing.category=pos; ReadByte(code_); if(code_<128U) pos=0; else if((code_<192U) && (code_>=128U)) pos=1; else { pos=Look(language_code,2,15,code_); if(pos<0) pos=16; } des.analyzing.language=pos; ReadByte(code_); mask=0x10; for(i=0;i<4;i++) { if(code_&mask) des.analyzing.capability[i]=i+4; else des.analyzing.capability[i]=i; mask<<=1; } ReadByte(des.analyzing.AC); if(des.analyzing.AC>2) des.analyzing.AC=0; Skip(16); des.analyzing.analysing_program_revision_number=(char*)FreeWithCare(des.analyzing.analysing_program_revision_number); des.analyzing.serial_number_device=(char*)FreeWithCare(des.analyzing.serial_number_device); des.analyzing.device_system_software=(char*)FreeWithCare(des.analyzing.device_system_software); des.analyzing.device_SCP_implementation_software=(char*)FreeWithCare(des.analyzing.device_SCP_implementation_software); des.analyzing.manifacturer_trade_name=(char*)FreeWithCare(des.analyzing.manifacturer_trade_name); ReadByte(i); if(!i) des.analyzing.analysing_program_revision_number=(char*)FreeWithCare(des.analyzing.analysing_program_revision_number); else des.analyzing.analysing_program_revision_number=ReadString(des.analyzing.analysing_program_revision_number,i); filepos = iftell(in); //FGETPOS(in,&filepos); des.analyzing.serial_number_device=FindString(des.analyzing.serial_number_device,dim-filepos COMPAT); filepos = iftell(in); //FGETPOS(in,&filepos); des.analyzing.device_system_software=FindString(des.analyzing.device_system_software,dim-filepos COMPAT); filepos = iftell(in); //FGETPOS(in,&filepos); des.analyzing.device_SCP_implementation_software=FindString(des.analyzing.device_SCP_implementation_software,dim-filepos COMPAT); filepos = iftell(in); //FGETPOS(in,&filepos); des.analyzing.manifacturer_trade_name=FindString(des.analyzing.manifacturer_trade_name,dim-filepos COMPAT); }//end section_1_15 void section_1_16(descriptive &des) // section 1 tag 16 { uint16_t dim; ReadByte(dim); des.acquiring_institution=ReadString(des.acquiring_institution,dim); }//end section_1_16 void section_1_17(descriptive &des) // section 1 tag 17 { uint16_t dim; ReadByte(dim); des.analyzing_institution=ReadString(des.analyzing_institution,dim); }//end section_1_17 void section_1_18(descriptive &des) // section 1 tag 18 { uint16_t dim; ReadByte(dim); des.acquiring_department=ReadString(des.acquiring_department,dim); }//end section_1_18 void section_1_19(descriptive &des) // section 1 tag 19 { uint16_t dim; ReadByte(dim); des.analyzing_department=ReadString(des.analyzing_department,dim); }//end section_1_19 void section_1_20(clinic &cli) // section 1 tag 20 { uint16_t dim; ReadByte(dim); cli.referring_physician=ReadString(cli.referring_physician,dim); }//end section_1_20 void section_1_21(clinic &cli) // section 1 tag 21 { uint16_t dim; ReadByte(dim); cli.latest_confirming_physician=ReadString(cli.latest_confirming_physician,dim); }//end section_1_21 void section_1_22(clinic &cli) // section 1 tag 22 { uint16_t dim; ReadByte(dim); cli.technician_description=ReadString(cli.technician_description,dim); }//end section_1_22 void section_1_23(descriptive &des) // section 1 tag 23 { uint16_t dim; ReadByte(dim); des.room=ReadString(des.room,dim); }//end section_1_23 void section_1_24(descriptive &des) // section 1 tag 24 { uint16_t dim; ReadByte(dim); ReadByte(des.stat_code); }//end section_1_24 void section_1_25(device &dev) // section 1 tag 25 { uint16_t dim; uint8_t m, g; uint16_t a; ReadByte(dim); ReadByte(a); ReadByte(m); ReadByte(g); struct tm tmf; // by E.C. feb 2006 tmf.tm_year = a - 1900; tmf.tm_mon = m - 1; tmf.tm_mday = g; tmf.tm_hour = 0; tmf.tm_min = 0; tmf.tm_sec = 0; tmf.tm_isdst = 0; dev.date_acquisition2 = mktime(&tmf); // store date in native format }//end section_1_25 void section_1_26(device &dev) // section 1 tag 26 { uint16_t dim; uint8_t h, m, s; ReadByte(dim); ReadByte(h); ReadByte(m); ReadByte(s); dev.time_acquisition2 = (time_t) (s + m*(60 + h*24)); // by E.C. feb 2006 time in seconds }//end section_1_26 void section_1_27(device &dev) // section 1 tag 27 { uint16_t dim; ReadByte(dim); ReadByte(dev.baseline_filter); }//end section_1_27 void section_1_28(device &dev) // section 1 tag 28 { uint16_t dim; ReadByte(dim); ReadByte(dev.lowpass_filter); }//end section_1_28 void section_1_29(device &dev) // section 1 tag 29 { uint16_t dim; uint8_t mask=0x1, val, i, max=4, ris=0; ReadByte(dim); ReadByte(val); for(i=0;i6) pos=0; dev.electrode_configuration.value=pos; ReadByte(pos); if(pos>6) pos=0; dev.electrode_configuration.unit=pos; }//end section_1_33 void section_1_34(device &dev) // section 1 tag 34 { uint16_t dim; ReadByte(dim); ReadByte(dev.TZ.offset); //complemented if negative ReadByte(dev.TZ.index); if(dim-4) dev.TZ.description = FindString((char*)dev.TZ.description,dim-4); else{ dev.TZ.description = (const char*)realloc((char*)dev.TZ.description,4); strcpy((char*)dev.TZ.description,"-"); } }//end section_1_34 void section_1_35(clinic &cli, uint16_t &dim) // section 1 tag 35 { uint16_t val; char *temp_string=NULL, *pos_char; ReadByte(val); if(val) { if((cli.free_medical_hystory=(numeric*)realloc(cli.free_medical_hystory,sizeof(numeric)*(cli.number_free_hystory+1)))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } cli.free_medical_hystory[cli.number_free_hystory].unit=cli.number_free_hystory+1; cli.free_medical_hystory[cli.number_free_hystory].value=val; temp_string=ReadString(temp_string,cli.free_medical_hystory[cli.number_free_hystory].value); strcat(temp_string,STR_END); dim+=strlen(temp_string); if((cli.text_free_medical_hystory=(char*)realloc(cli.text_free_medical_hystory,dim+1))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } pos_char=cli.text_free_medical_hystory; pos_char+=dim-strlen(temp_string); strcpy(pos_char,temp_string); free(temp_string); cli.number_free_hystory++; } }//end section_1_35 void section_1_() // section 1 tag 36..254 are manufacturer specifics and are not utilized { uint16_t dim; ReadByte(dim); Skip(dim); }//end section_1_ void section_1_255() // section 1 tag 255 { uint16_t dim; ReadByte(dim); }//end section_1_255 #endif //______________________________________________________________________________ // section 2 //______________________________________________________________________________ void section_2(pointer_section info_sections,DATA_DECODE &data) //build Huffman tables if included in the file; if none then use del default one //cannot read the dummy Huffman table { uint16_t nt, i, j, ns=0, pos, dim; //fpos_t filepos; long filepos; int8_t version; _COUNT_BYTE=info_sections.index; ifseek(in,info_sections.index-1,0); ID_section(info_sections.index, version); dim=info_sections.length-16; ReadByte(nt); if(nt!=19999U) { if((data.flag_Huffman=(uint16_t*)mymalloc(sizeof(uint16_t)*(nt+1)))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } data.flag_Huffman[0]=nt; filepos = iftell(in); //FGETPOS(in,&filepos); for(i=1;i<=data.flag_Huffman[0];i++) { ReadByte(data.flag_Huffman[i]); ns+=data.flag_Huffman[i]; Skip(9*data.flag_Huffman[i]); } ifseek(in,filepos COMPAT,0); if((ns*9)>dim || !ns) { B4C_ERRNUM = B4C_UNSPECIFIC_ERROR; B4C_ERRMSG = "SCP-DECODE: Cannot read data"; return; } if(ns!=0 && (data.t_Huffman=(table_H*)mymalloc(sizeof(table_H)*ns))==NULL) //array of 5 columns and ns rows { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } pos=0; for(j=0;j>3; if (version==11) // by E.C. may 2004 ESAOTE data.flag_lead.number_simultaneously=8; if(data.flag_lead.number!=0 && (data.data_lead=(lead*)mymalloc(sizeof(lead)*data.flag_lead.number))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } for(i=0;i85) data.data_lead[i].ID=0; } }//end section_3 //______________________________________________________________________________ // section 4 //______________________________________________________________________________ void section_4(pointer_section info_sections,DATA_DECODE &data,int8_t version) { uint16_t i; int8_t version_loc; _COUNT_BYTE=info_sections.index; ifseek(in,info_sections.index-1,0); ID_section(info_sections.index, version_loc); ReadByte(data.flag_BdR0.length); ReadByte(data.flag_BdR0.fcM); ReadByte(data.flag_Res.number); if(data.flag_Res.bimodal || data.flag_lead.subtraction) // by E.C. may 2004 { if(data.flag_Res.number!=0 && (data.data_subtraction=(Subtraction_Zone*)mymalloc(sizeof(Subtraction_Zone)*data.flag_Res.number))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } for(i=0;i2) data.flag_BdR0.encoding=0; Skip(1); if(data.flag_lead.number!=0 && (data.length_BdR0=(uint16_t*)mymalloc(sizeof(uint16_t)*data.flag_lead.number))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return false; } dim=0; for(i=0;i>=1; dim*=sizeof(int32_t); if(dim!=0 && (data.Median=(int32_t*)mymalloc(dim))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return false; } dim/=sizeof(int32_t); for(t=0;t0x7FFF) data.Median[t]|=0xFFFF0000; } } return true; }//end section_5 //______________________________________________________________________________ // section 6 //______________________________________________________________________________ void section_6(pointer_section info_sections,DATA_DECODE &data, bool sez2) { uint16_t i; uint32_t t, dim; uint16_t value; int8_t version; _COUNT_BYTE=info_sections.index; ifseek(in,info_sections.index-1,0); ID_section(info_sections.index, version); ReadByte(data.flag_Res.AVM); ReadByte(data.flag_Res.STM); ReadByte(data.flag_Res.encoding); if(data.flag_Res.encoding>2) data.flag_Res.encoding=0; Skip(1); if(data.flag_lead.number!=0 && (data.length_Res=(uint16_t*)mymalloc(sizeof(uint16_t)*data.flag_lead.number))==NULL) { B4C_ERRNUM = B4C_INSUFFICIENT_MEMORY; B4C_ERRMSG = "SCP-DECODE: Not enough memory"; return; } dim=0; for(i=0;i>=1; dim*=sizeof(int32_t); if(dim!=0 && (data.Residual=(int32_t*)mymalloc(dim))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } dim/=sizeof(int32_t); for(t=0;t0x7FFF) data.Residual[t]|=0xFFFF0000; } } }//end section_6 #ifdef WITH_OBSOLETE_PARTS //______________________________________________________________________________ // section 7 //______________________________________________________________________________ void section_7(pointer_section info_sections ,DATA_RECORD &data, int8_t version) { uint16_t i, j, dim; uint8_t lung; //fpos_t filepos; long filepos; int8_t version_loc; uint32_t length_eval; _COUNT_BYTE=info_sections.index; ifseek(in,info_sections.index-1,0); ID_section(info_sections.index, version_loc); ReadByte(data.data_global.number); //each value should be checked in _special! ReadByte(data.data_global.number_spike); if (version==11) ReadByte(data.data_global.number_spike); // by E.C. may 2004 x ESAOTE!! This is an implementation error, for sure! ReadByte(data.data_global.average_RR); ReadByte(data.data_global.average_PP); if(Look(_special,0,3,data.data_global.number)<0) { if(data.data_global.number!=0 && (data.data_BdR=(BdR_measurement*)mymalloc(sizeof(BdR_measurement)*data.data_global.number))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } for(i=0;i3) data.data_spike[i].type=0; ReadByte(data.data_spike[i].source); if(data.data_spike[i].source>2) data.data_spike[i].source=0; ReadByte(data.data_spike[i].index); ReadByte(data.data_spike[i].pulse_width); }//end for }//end if if (version<13) { // by E.C. may 2004 CARDIOLINE & ESAOTE missing!! if ((data.data_global.average_RR>0) && (data.data_global.average_RR<10000)) data.data_global.ventricular_rate=60000.0/data.data_global.average_RR+0.5; return; } // Insert by F.C. if (version>=13) { length_eval = 16 + 6 + data.data_global.number * 16 + data.data_global.number_spike * 4 + data.data_global.number_spike * 6; if (length_eval >= info_sections.length) return; } // End of F.C. insertion ReadByte(data.data_global.number_QRS); if (data.data_global.number_QRS==29999) return; // by E.C. 12/09/2007 if(Look(_special,0,3,data.data_global.number_QRS)<0) { filepos = iftell(in); //FGETPOS(in,&filepos); //necessary for ESAOTE and CARDIOLINE test files dim=info_sections.index+info_sections.length-filepos COMPAT+1; if(data.data_global.number_QRS>dim) { fprintf(stderr,"Error: Cannot extract these data!!!"); exit(2); //necessary for ESAOTE and CARDIOLINE test files } if(data.data_global.number_QRS!=0 && (data.type_BdR=(uint8_t*)mymalloc(sizeof(uint8_t)*data.data_global.number_QRS))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } for(i=0;i=13) { length_eval += (2 + data.data_global.number_QRS); if (length_eval >= info_sections.length) return; } // End of F.C. insertion ReadByte(data.data_global.ventricular_rate); ReadByte(data.data_global.atrial_rate); ReadByte(data.data_global.QT_corrected); ReadByte(data.data_global.formula_type); if(data.data_global.formula_type>2) data.data_global.formula_type=0; ReadByte(data.data_global.number_tag); if(data.data_global.number_tag) { data.data_global.number_tag-=2; data.data_global.number_tag/=7; // tag number //warnig: this calculation is relative to the structure of STANDARD v2.0! if(data.data_global.number_tag!=0 && (data.data_additional=(additional_measurement*)mymalloc(sizeof(additional_measurement)*data.data_global.number_tag))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } for(i=0;i3) data.data_additional[i].ID=4; ReadByte(lung); if(lung) { //warning:(255 is undefined) for(j=0;j<5;j++) ReadByte(data.data_additional[i].byte[j]); }//end if }//end for }//end if }//end section_7 //______________________________________________________________________________ // section 8 //______________________________________________________________________________ void section_8(pointer_section info_sections,DATA_INFO &data) { uint8_t m, g, h, s, i; uint16_t a, dim; char *c; //fpos_t filepos; long filepos; int8_t version; _COUNT_BYTE=info_sections.index; ifseek(in,info_sections.index-1,0); ID_section(info_sections.index, version); ReadByte(data.flag_report.type); if(data.flag_report.type>2) data.flag_report.type=3; ReadByte(a); ReadByte(m); ReadByte(g); ReadByte(h); ReadByte(m); ReadByte(s); struct tm tmf; tmf.tm_year = a; tmf.tm_mon = m; tmf.tm_mday = g; tmf.tm_hour = h; tmf.tm_min = m; tmf.tm_sec = s; data.flag_report.date = (char*)mymalloc(18); strftime(data.flag_report.date,18,"%d %b %Y", &tmf); data.flag_report.time = (char*)mymalloc(18); strftime(data.flag_report.date,18,"%H:%M:%S", &tmf); ReadByte(data.flag_report.number); if(data.flag_report.number) { filepos = iftell(in); //FGETPOS(in,&filepos); if(data.flag_report.number!=0 && (data.text_dim=(numeric*)mymalloc(data.flag_report.number*sizeof(numeric)))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } dim=0; for(i=0;i>1)-2; if(n1>31) // for now 33 are defined n1=31; //ignore next bytes data.header_lead.number_lead_measurement=n1; //max number of statements by the manufacturer (2 bytes each) if(data.header_lead.number_lead) // by E.C. 17.11.2003 deleted "!" in the if { if((data.lead_block=(lead_measurement_block*)mymalloc(data.header_lead.number_lead*sizeof(lead_measurement_block)))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } for(i=0;i85) id=0; ReadByte(dim); n2=(dim>>1); if(n2>n1) skip=(n2-n1)<<1; // bytes to skip else skip=0; data.lead_block[i].ID=id; //warnig: values relative to _SPECIAL for(j=1;j<=data.header_lead.number_lead_measurement;j++) { switch(j) { case 1: ReadByte(data.lead_block[i].P_duration); break; case 2: ReadByte(data.lead_block[i].PR_interval); break; case 3: ReadByte(data.lead_block[i].QRS_duration); break; case 4: ReadByte(data.lead_block[i].QT_interval); break; case 5: ReadByte(data.lead_block[i].Q_duration); break; case 6: ReadByte(data.lead_block[i].R_duration); break; case 7: ReadByte(data.lead_block[i].S_duration); break; case 8: ReadByte(data.lead_block[i].R1_duration); break; case 9: ReadByte(data.lead_block[i].S1_duration); break; case 10: ReadByte(data.lead_block[i].Q_amplitude); break; case 11: ReadByte(data.lead_block[i].R_amplitude); break; case 12: ReadByte(data.lead_block[i].S_amplitude); break; case 13: ReadByte(data.lead_block[i].R1_amplitude); break; case 14: ReadByte(data.lead_block[i].S1_amplitude); break; case 15: ReadByte(data.lead_block[i].J_point_amplitude); break; case 16: ReadByte(data.lead_block[i].Pp_amplitude); break; case 17: ReadByte(data.lead_block[i].Pm_amplitude); break; case 18: ReadByte(data.lead_block[i].Tp_amplitude); break; case 19: ReadByte(data.lead_block[i].Tm_amplitude); break; case 20: ReadByte(data.lead_block[i].ST_slope); break; case 21: ReadByte(data.lead_block[i].P_morphology); if(data.lead_block[i].P_morphology) data.lead_block[i].P_morphology=0; break; case 22: ReadByte(data.lead_block[i].T_morphology); if(data.lead_block[i].T_morphology) data.lead_block[i].T_morphology=0; break; case 23: ReadByte(data.lead_block[i].iso_electric_segment_onset_QRS); break; case 24: ReadByte(data.lead_block[i].iso_electric_segment_offset_QRS); break; case 25: ReadByte(data.lead_block[i].intrinsicoid_deflection); break; case 26: ReadByte(val); mask=0x3; for(k=0;k<8;k++) { data.lead_block[i].quality_recording[k]=mask&val; // TODO: code has no effect mask<<2; } break; case 27: ReadByte(data.lead_block[i].ST_amplitude_Jplus20); break; case 28: ReadByte(data.lead_block[i].ST_amplitude_Jplus60); break; case 29: ReadByte(data.lead_block[i].ST_amplitude_Jplus80); break; case 30: ReadByte(data.lead_block[i].ST_amplitude_JplusRR16); break; case 31: ReadByte(data.lead_block[i].ST_amplitude_JplusRR8); break; }//end switch }//end for if(skip) Skip(skip); }//end if }//end for }//end if }//end section_10 //______________________________________________________________________________ // section 11 //______________________________________________________________________________ void section_11(pointer_section info_sections,DATA_INFO &data) /* expressions (ASCII) should be either: 1) diagnostic statement_probability_modifiers; 2) diagnostic statement_probability_modifier_conjunctive term_diagnostic statement_probability_modifier...; in the test files I found only 1 diagnostic statement per expression, ending with a NULL. */ { uint8_t m, g, h, s, i, j; uint16_t a, dim; char *temp_string=0, *punt, c; //fpos_t filepos; long filepos; int8_t version; _COUNT_BYTE=info_sections.index; ifseek(in,info_sections.index-1,0); ID_section(info_sections.index, version); ReadByte(data.flag_statement.type); if(data.flag_statement.type>2) data.flag_statement.type=3; ReadByte(a); ReadByte(m); ReadByte(g); ReadByte(h); ReadByte(m); ReadByte(s); struct tm tmf; tmf.tm_year = a; tmf.tm_mon = m; tmf.tm_mday = g; tmf.tm_hour = h; tmf.tm_min = m; tmf.tm_sec = s; data.flag_statement.date = (char*)mymalloc(18); strftime(data.flag_statement.date,18,"%d %b %Y", &tmf); data.flag_statement.time = (char*)mymalloc(18); strftime(data.flag_statement.time,18,"%H:%M:%S", &tmf); ReadByte(data.flag_statement.number); //number of expressions if(!data.flag_statement.number) { filepos = iftell(in); //FGETPOS(in,&filepos); if(data.flag_statement.number!=0 && (data.data_statement=(statement_coded*)mymalloc(data.flag_statement.number*sizeof(statement_coded)))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } dim=0; for(i=0;i void Differences(int32_t *dati, t1 flag, uint8_t num) { uint8_t i; uint16_t j; for(i=0;inext_0); Tree_Destroy(radix->next_1); free(radix); } return; } TREE_NODE *Tree_Create(TREE_NODE *tree, uint16_t n_of_struct, table_H *table, uint16_t pos) //build a tree { uint8_t i,j; uint32_t mask; TREE_NODE *temp; //build the root if((tree=(TREE_NODE *)mymalloc(sizeof(TREE_NODE)))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } tree->next_0=NULL; tree->next_1=NULL; tree->row=-1; //-1 means no row in the table for (j=0;jnext_1==NULL) { if((temp->next_1=(TREE_NODE *)mymalloc(sizeof(TREE_NODE)))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } temp->next_1->next_0=NULL; temp->next_1->next_1=NULL; temp->next_1->row=-1; } temp=temp->next_1; }//end if else { if (temp->next_0==NULL) { if((temp->next_0=(TREE_NODE *)mymalloc(sizeof(TREE_NODE)))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } temp->next_0->next_0=NULL; temp->next_0->next_1=NULL; temp->next_0->row=-1; } temp=temp->next_0; }//end else mask <<=1; }//end for i temp->row=j; //marks the j row in the table }//end for j return tree; }//end Tree_Create uint8_t Input_Bit(uint8_t *raw, uint16_t &pos, uint16_t max, uint8_t &mask, bool &err) { uint8_t value; if(pos==max) { err=1; return 0; } value=raw[pos]&mask; mask>>=1; if(!mask) { mask=0x80; ++pos; } return( value ? 1 : 0 ); }//end Input_Bit int16_t Input_Bits(uint8_t *raw, uint16_t &pos, uint16_t max, uint8_t &mask, uint8_t bit_count, bool &err) { uint16_t temp; int16_t value; if(pos==max) { err=1; return 0; } temp=1<<(bit_count-1); value=0; do { if(raw[pos]&mask) value |= temp; temp>>=1; mask>>=1; if(!mask) { mask=0x80; ++pos; if(pos==max) { mask=0; // by E.C. may 2004 break; } } } while(temp); if(temp) err=1; if (value & (1<<(bit_count-1))) // by E.C. may 2004 negative value. extend to the left value|=(-1<next_1; else temp=temp->next_0; if (temp==NULL) { fprintf(stderr,"Tree overflow"); err=1; break; } if (temp->row > -1) // row found in the table: exit for break; if(pos_in==maxIN) err=1; if(err) break; }//end for if(err) // check for error conditions and if exit while { break; // by E.C. may 2004 } if(table[temp->row+pos_tH].TMS!=1) // switch to another table { Tree_Destroy(tree); // destroy the tree and rebuild with the new table pos_tH=0; for(i=1;irow+pos_tH].base_value;i++) pos_tH+=flag[i]; // offset of the table tree=Tree_Create(tree,flag[table[temp->row+pos_tH].base_value],table,pos_tH); continue; }//end if table else { nbits=table[temp->row+pos_tH].bit_code-table[temp->row+pos_tH].bit_prefix; if (nbits) // bit of the code != bit of the prefix { if(pos_in==maxIN) { err=1; break; // by E.C. may 2004 } raw_out[pos_out]=Input_Bits(raw_in,pos_in,maxIN,mask,nbits,err); // take value from the stream if(err) // check for error conditions and if exit while { break; // by E.C. may 2004 } ++pos_out; }//end if nbits else // bit of the code = bit of the prefix { raw_out[pos_out]=table[temp->row+pos_tH].base_value; // take value from the table ++pos_out; } }//end else if table ++j; if (j==max_out) break; // by E.C. may 2004 } //end while pos_in=maxIN; // by E.C. 23.02.2004: align for safety max_out=j; // flows here anyhow! if (max_out>4900) { max_out=5000; // by E.C. may 2004 ESAOTE pos_out=(pos_out+100)/max_out*max_out; // align pointer } }//end decompress //data.data_BdR0 , data.length_BdR0 , data.samples_BdR0 , data.flag_BdR0.number_samples , data.flag_lead.number , data.t_Huffman , data.flag_Huffman //out_data , length , in_data , n_samples , n_lead , t_Huffman , flag_Huffman void Huffman(int32_t *out_data, uint16_t *length, uint8_t *in_data, uint16_t &n_samples, uint16_t n_lead, table_H *t_Huffman, uint16_t *flag_Huffman) { TREE_NODE *tree = NULL; uint16_t pos_in, pos_out, pos_tH; uint8_t i; pos_in=0; pos_out=0; pos_tH=0; tree=Tree_Create(tree,flag_Huffman[1],t_Huffman,pos_tH); for(i=0;i1) // by E.C. 19.02.2004 (i.e. to open pd3471) { //dim_R = number of bytes of decimated signal (4 bytes (int32_t) ) //data.flag_Res.number_samples = samples of the decimated signal //dim_R_ = number of bytes of the reconstructed signal (4 bytes (int32_t) ) //number_samples_ = samples of the reconstructed signal data.flag_Res.number_samples=number_samples_; //number of samples per lead number_samples_=dim_R/(sizeof(int32_t)*data.flag_lead.number); dim_R=dim_R_; dim_R_=(dim_R/sizeof(int32_t))*sizeof(float)*2; //dim_R_ = number of bytes of decimated signal (4 bytes (int32_t) ) //number_samples_ = samples of the decimated signal //dim_R = number of bytes of the reconstructed signal (4 bytes (int32_t) ) //data.flag_Res.number_samples = samples of the reconstructed signal if(dim_R_!=0 && (dati_Res_=(int32_t*)mymalloc(dim_R_))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } Interpolate(dati_Res_,data.Residual,data.flag_lead,data.data_lead,data.flag_Res,data.data_protected,number_samples_); DoFilter(data.Residual,dati_Res_,data.flag_Res,data.flag_lead,data.data_lead,data.data_protected,data.data_subtraction); free(dati_Res_); //dim_R modifies } } Multiply(data.Residual,data.flag_Res.number_samples*data.flag_lead.number,data.flag_Res.AVM); /* AS 2007-10-23: for some (unknown) reason, sometimes the memory allocation has the wrong size doing the memory allocation in sopen_scp_read does it correctly. Number of files with SegFaults is reduced by 3. if(dim_R!=0 && (data.Reconstructed=(int32_t*)mymalloc(dim_R))==NULL) { fprintf(stderr,"Not enough memory"); // no, exit // exit(2); } */ unsigned dim_RR=dim_R/sizeof(int32_t); // by E.C. 15.10.2003 This to correct a trivial error for(t=0;t1)){ // by E.C. 25.02.2004 // now that the signal is completely reconstructructed, and if decimation was performed // during the compression phase, do an extra low-pass filter outside protected zones ! // This shows lower RMS values of about 0.5 - 1.0 // If you don't like this extra filtering please uncheck the menu option and reopen for(t=0;tb : may be - the first sample is the first of the first protected zone (a=b+1=1) - empty no-protection zone (a=b+1) - the last sample is the last of the last protected zone (a=b+1) in these situations samples are copied as they are. */ { uint16_t a, b; //interpolation range float v; //interpolation value uint8_t j; //working variable uint16_t dim; //number of samples (to skip) into a protected zone uint16_t mINS, mCOPY; //number of samples to insert, copy int16_t num; //number of samples to interpolate uint32_t pos_in, pos_out; uint16_t nz; //index of protected zones, i.e. index of QRS uint8_t ne; //index of lead pos_in=0; pos_out=0; for(ne=0;ne0) { mINS=num/flag.decimation_factor; //number to interpolate mCOPY=num%flag.decimation_factor; //if, residual number to copy if(mINS) { //store first two samples equal to the first value in the list ... raw_out[pos_out++]=raw_in[pos_in]; raw_out[pos_out++]=raw_in[pos_in]; } // ... then proceed with interpolation dim=mINS; while((dim--)>1) { v=1.0*(raw_in[pos_in+1]-raw_in[pos_in])/flag.decimation_factor; // by E.C. 23.02.2004 (float v) // rounding improves RMS! for(j=0;j=(sample_Huff*(ne+1))) //check overflow break; if(mINS) { raw_out[pos_out++]=raw_in[pos_in]; raw_out[pos_out++]=raw_in[pos_in]; if(pos_in<(sample_Huff*(ne+1))) // by E.C. 19.02.2004 check overflow ++pos_in; } //not normal situation? insert mCOPY samples while((mCOPY--)>0) if(pos_in<(sample_Huff*(ne+1))) // by E.C. 19.02.2004 check overflow raw_out[pos_out++]=raw_in[pos_in++]; else raw_out[pos_out++]=0; }//end if num>0 if (nz0) raw_out[pos_out++]=raw_in[pos_in++]; } }//for nz pos_in=sample_Huff*(ne+1); // by E.C. 19.02.2004 align, never mind!! pos_out=(pos_out+100)/5000*5000; // by E.C. may 2004 for testing purposes only }//for ne }//end Interpolate void ExecFilter(int32_t *raw_in, int32_t *raw_out, uint32_t &pos, uint16_t dim) //filter from pos for dim samples { int32_t v; //value uint16_t i; if (dim>0) { //fist sample = unchanged raw_out[pos]=raw_in[pos]; pos++; if(dim>2) for(i=2;i=0) // as suggested by the standard for rounding v+=1; else v-=1; raw_out[pos++]=v/3; // by E.C. 24.02.2004 in this case, declaring v as float doesn't change results } } //last sample = unchanged if(dim>1) { raw_out[pos]=raw_in[pos]; pos++; } }//end ExecFilter void DoFilter(int32_t *raw_out, int32_t *raw_in, f_Res flag, f_lead flag_L, lead *marker_A, Protected_Area *marker_P, Subtraction_Zone *marker_S) //filter low-pass outside the proteced zones (marker_Z) for each lead (marker_A) // but taking into account transients at the boundaries of the subtraction zones (marker_S) //It's included rounding. { uint16_t a, b=0; //interval int16_t num; uint32_t pos; uint16_t nz; uint8_t ne; //index of lead pos=0; // by E.C. 19.02.2004 function redefined such as Interpolate() for(ne=0;ne0) { raw_out[pos]=raw_in[pos]; pos++; } } }//for nz } // for ne/ng }//end DoFilter void DoAdd(int32_t *raw_out, int32_t *raw_R, f_Res flag_R, int32_t *raw_B, f_BdR0 flag_B, Subtraction_Zone *marker_S, f_lead flag_L, lead *marker_A) //add BdR0 with the rhythm data for all leads { uint16_t pos_B; uint32_t pos_R, pos_out; uint16_t ns, a , b, num; uint8_t ne; //index of leads pos_R=0; // by E.C. 19.02.2004 add reference beat to rhythm for(ne=0;ne0) { raw_out[pos_out]+=raw_B[pos_B]; pos_out++; pos_B++; pos_R++; } }//end for/if }//end DoAdd void Opt_Filter(int32_t *raw_out, int32_t *raw_in, f_Res flag, f_lead flag_L, lead *marker_A, Protected_Area *marker_P) // by E.C. 25.02.2004 // do an extra low-pass filter outside protected zones (marker_P) // in the range of the signal (marker_A) for each lead // this is simpler than DoFilter() { uint16_t a, b=0; //interval for filtering int16_t num; uint32_t pos; uint16_t nz; uint8_t ne; //lead index pos=0; for(ne=0;ne0) { raw_out[pos]=raw_in[pos]; pos++; } } }//for nz } // for ne }//end Opt_Filter stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_igor.c0000664000175000017500000007421314752215315015655 /* Copyright (C) 2013,2014 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define _GNU_SOURCE /* #include #include #include */ #include #include // define macro isnan() #include #include #include "../biosig-dev.h" #include "../igor/IgorBin.h" #define IGOROLD 1 // will be used for testing and migrating to new version #ifdef __cplusplus extern "C" { #endif #define ITX_MAXLINELENGTH 400 char *IgorChanLabel(char *inLabel, HDRTYPE *hdr, size_t *ngroup, size_t *nseries, size_t *nsweep, size_t *ns) { /* extract Channel Label of IGOR ITX data format */ *ns = 0; // static char Label[ITX_MAXLINELENGTH+1]; int k, s = 0, pos4=0, pos1=0; for (k = strlen(inLabel); inLabel[k] < ' '; k--); inLabel[k+1] = 0; while (inLabel[k] >= ' ') { while ( inLabel[k] >= '0' && inLabel[k] <= '9' ) k--; if (inLabel[k]=='_') { s++; if (s==1) pos4 = k; if (s==4) pos1 = k; k--; } if ( inLabel[k] < '0' || inLabel[k] > '9' ) break; } if (3 < s) { char nvar = 0; for (k = strlen(inLabel); 0 < k && nvar < 4; k--) { if (inLabel[k] == '_') { inLabel[k] = 0; char *v = inLabel+k+1; size_t n = atol(v); switch (nvar) { case 0: *ns = n; nvar++; break; case 1: *nsweep = n; nvar++; break; case 2: *nseries = n; nvar++; break; case 3: *ngroup = n; nvar++; break; } inLabel[k] = 0; } } for (k=1; inLabel[pos4+k-1]; k++) { inLabel[pos1+k] = inLabel[pos4+k]; } } if ((*ns)+1 > hdr->NS) { // another channel hdr->NS = (*ns)+1; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); } return(inLabel); } /* compute igor checksum */ int ibwChecksum(int16_t *data, int flag_swap, int oldcksum, int numbytes) { numbytes >>= 1; // 2 bytes to a short -- ignore trailing odd byte. if (flag_swap) { while(numbytes-- > 0) oldcksum += bswap_16(*(data++)); } else { while(numbytes-- > 0) oldcksum += *(data++); } return oldcksum&0xffff; } /* void ReorderBytes(void *p, int bytesPerPoint, long numValues) // Reverses byte order. { unsigned char ch, *p1, *p2, *pEnd; pEnd = (unsigned char *)p + numValues*bytesPerPoint; while (p < (void *)pEnd) { p1 = p; p2 = (unsigned char *)p + bytesPerPoint-1; while (p1 < p2) { ch = *p1; *p1++ = *p2; *p2-- = ch; } p = (unsigned char *)p + bytesPerPoint; } } */ void ReorderShort(void* sp) { *(uint16_t*)sp = bswap_16(*(uint16_t*)sp); } void ReorderLong(void* lp) { *(uint32_t*)lp = bswap_32(*(uint32_t*)lp); } void ReorderDouble(void* dp) { *(uint64_t*)dp = bswap_64(*(uint64_t*)dp); } void ReorderBinHeader1(BinHeader1* p) { ReorderShort(&p->version); ReorderLong(&p->wfmSize); ReorderShort(&p->checksum); } void ReorderBinHeader2(BinHeader2* p) { ReorderShort(&p->version); ReorderLong(&p->wfmSize); ReorderLong(&p->noteSize); // ReorderLong(&p->pictSize); ReorderShort(&p->checksum); } void ReorderBinHeader3(BinHeader3* p) { ReorderShort(&p->version); ReorderLong(&p->wfmSize); ReorderLong(&p->noteSize); ReorderLong(&p->formulaSize); // ReorderLong(&p->pictSize); ReorderShort(&p->checksum); } void ReorderBinHeader5(BinHeader5* p) { ReorderShort(&p->version); ReorderShort(&p->checksum); ReorderLong(&p->wfmSize); ReorderLong(&p->formulaSize); ReorderLong(&p->noteSize); ReorderLong(&p->dataEUnitsSize); // ReorderBytes(&p->dimEUnitsSize, 4, 4); ReorderLong(&p->dimEUnitsSize[0]); ReorderLong(&p->dimEUnitsSize[1]); ReorderLong(&p->dimEUnitsSize[2]); ReorderLong(&p->dimEUnitsSize[3]); // ReorderBytes(&p->dimLabelsSize, 4, 4); ReorderLong(&p->dimLabelsSize[0]); ReorderLong(&p->dimLabelsSize[1]); ReorderLong(&p->dimLabelsSize[2]); ReorderLong(&p->dimLabelsSize[3]); ReorderLong(&p->sIndicesSize); // ReorderLong(&p->optionsSize1); // ReorderLong(&p->optionsSize2); } void ReorderWaveHeader2(WaveHeader2* p) { ReorderShort(&p->type); // ReorderLong(&p->next); // char bname does not need to be reordered. // ReorderShort(&p->whVersion); // ReorderShort(&p->srcFldr); // ReorderLong(&p->fileName); // char dataUnits does not need to be reordered. // char xUnits does not need to be reordered. ReorderLong(&p->npnts); // ReorderShort(&p->aModified); ReorderDouble(&p->hsA); ReorderDouble(&p->hsB); // ReorderShort(&p->wModified); // ReorderShort(&p->swModified); ReorderShort(&p->fsValid); ReorderDouble(&p->topFullScale); ReorderDouble(&p->botFullScale); // char useBits does not need to be reordered. // char kindBits does not need to be reordered. // ReorderLong(&p->formula); // ReorderLong(&p->depID); ReorderLong(&p->creationDate); // char wUnused does not need to be reordered. ReorderLong(&p->modDate); // ReorderLong(&p->waveNoteH); // The wData field marks the start of the wave data which will be reordered separately. } void ReorderWaveHeader5(WaveHeader5* p) { // ReorderLong(&p->next); ReorderLong(&p->creationDate); ReorderLong(&p->modDate); ReorderLong(&p->npnts); ReorderShort(&p->type); // ReorderShort(&p->dLock); // char whpad1 does not need to be reordered. // ReorderShort(&p->whVersion); // char bname does not need to be reordered. // ReorderLong(&p->whpad2); // ReorderLong(&p->dFolder); // ReorderBytes(&p->nDim, 4, 4); ReorderLong(&p->nDim[0]); ReorderLong(&p->nDim[1]); ReorderLong(&p->nDim[2]); ReorderLong(&p->nDim[3]); // ReorderBytes(&p->sfA, 8, 4); ReorderDouble(&p->sfA[0]); ReorderDouble(&p->sfA[1]); ReorderDouble(&p->sfA[2]); ReorderDouble(&p->sfA[3]); // ReorderBytes(&p->sfB, 8, 4); ReorderDouble(&p->sfB[0]); ReorderDouble(&p->sfB[1]); ReorderDouble(&p->sfB[2]); ReorderDouble(&p->sfB[3]); // char dataUnits does not need to be reordered. // char dimUnits does not need to be reordered. ReorderShort(&p->fsValid); // ReorderShort(&p->whpad3); ReorderDouble(&p->topFullScale); ReorderDouble(&p->botFullScale); /* // according to IgorBin.h, the following stuff can be ignored for reading IBW files // ReorderLong(&p->dataEUnits); // ReorderBytes(&p->dimEUnits, 4, 4); ReorderLong(&p->dimEUnits[0]); ReorderLong(&p->dimEUnits[1]); ReorderLong(&p->dimEUnits[2]); ReorderLong(&p->dimEUnits[3]); // ReorderBytes(&p->dimLabels, 4, 4); ReorderLong(&p->dimLabels[0]); ReorderLong(&p->dimLabels[1]); ReorderLong(&p->dimLabels[2]); ReorderLong(&p->dimLabels[3]); ReorderLong(&p->waveNoteH); // ReorderBytes(&p->whUnused, 4, 16); ReorderShort(&p->aModified); ReorderShort(&p->wModified); ReorderShort(&p->swModified); // char useBits does not need to be reordered. // char kindBits does not need to be reordered. ReorderLong(&p->formula); ReorderLong(&p->depID); ReorderShort(&p->whpad4); ReorderShort(&p->srcFldr); ReorderLong(&p->fileName); ReorderLong(&p->sIndices); // The wData field marks the start of the wave data which will be reordered separately. */ } void sopen_ibw_read (HDRTYPE* hdr) { /* this function will be called by the function SOPEN in "biosig.c" Input: char* Header // contains the file content Output: HDRTYPE *hdr // defines the HDR structure accoring to "biosig.h" */ fprintf(stdout,"Warning: support for IBW is very experimental\n"); uint16_t version = *(uint16_t*)hdr->AS.Header; char flag_swap = (version & 0xFF) == 0; if (flag_swap) version = bswap_16(version); unsigned count=0; int binHeaderSize; int waveHeaderSize; switch (version) { case 1: binHeaderSize=sizeof(BinHeader1); waveHeaderSize=sizeof(WaveHeader2); break; case 2: binHeaderSize=sizeof(BinHeader2); waveHeaderSize=sizeof(WaveHeader2); break; case 3: binHeaderSize=sizeof(BinHeader3); waveHeaderSize=sizeof(WaveHeader2); break; case 5: binHeaderSize=sizeof(BinHeader5); waveHeaderSize=sizeof(WaveHeader5); break; default: if (VERBOSE_LEVEL>7) fprintf(stderr,"ver=%x \n",version); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Igor/IBW: unsupported version number"); return; } count = binHeaderSize+waveHeaderSize; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i): IBW v%i %i %i %i\n",__FILE__,__LINE__,version, binHeaderSize,waveHeaderSize, (int)count); if (hdr->HeadLen < count) { hdr->AS.Header = realloc(hdr->AS.Header, count+1); hdr->HeadLen += ifread(hdr->AS.Header + hdr->HeadLen, 1, count-hdr->HeadLen, hdr); } // compute check sum if ((int)hdr->VERSION == 5) count -= 4; void *buffer = hdr->AS.Header; // Check the checksum. int crc; if ((ibwChecksum((int16_t*)buffer, flag_swap, 0, count))) { if (VERBOSE_LEVEL>7) fprintf(stderr,"ver=%x crc = %x %i %i \n",version, crc, binHeaderSize, waveHeaderSize); biosigERROR(hdr, B4C_CRC_ERROR, "Igor/IBW: checksum error"); return; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i): sizeof BinHeaders %i %i %i %i\n",__FILE__,__LINE__, (int)sizeof(BinHeader1),(int)sizeof(BinHeader2),(int)sizeof(BinHeader3),(int)sizeof(BinHeader5)); // Do byte reordering if the file is from another platform. if (flag_swap) { version = bswap_16(version); switch(version) { case 1: ReorderBinHeader1((BinHeader1*)hdr->AS.Header); break; case 2: ReorderBinHeader2((BinHeader2*)hdr->AS.Header); break; case 3: ReorderBinHeader3((BinHeader3*)hdr->AS.Header); break; case 5: ReorderBinHeader5((BinHeader5*)hdr->AS.Header); break; } switch(version) { case 1: // Version 1 and 2 files use WaveHeader2. case 2: case 3: ReorderWaveHeader2((WaveHeader2*)(hdr->AS.Header+binHeaderSize)); break; case 5: ReorderWaveHeader5((WaveHeader5*)(hdr->AS.Header+binHeaderSize)); break; } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i): sizeof WaveHeaders %i %i %i v%i\n",__FILE__,__LINE__, (int)sizeof(WaveHeader2), (int)sizeof(WaveHeader5), (int)iftell(hdr),version); // Read some of the BinHeader fields. int16_t type = 0; // See types (e.g. NT_FP64) above. Zero for text waves. hdr->NS = 1; hdr->SampleRate = 1.0; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); // Read some of the WaveHeader fields. switch(version) { case 1: case 2: case 3: { WaveHeader2* w2; w2 = (WaveHeader2*)(buffer+binHeaderSize); type = w2->type; strncpy(hdr->CHANNEL[0].Label, w2->bname, MAX_LENGTH_LABEL); hdr->CHANNEL[0].PhysDimCode = PhysDimCode(w2->dataUnits); hdr->CHANNEL[0].SPR = hdr->SPR = 1; hdr->NRec = w2->npnts; #ifdef IGOROLD hdr->CHANNEL[0].Cal = w2->hsA; hdr->CHANNEL[0].Off = w2->hsB; /* hdr->CHANNEL[0].DigMax = (w2->topFullScale-w2->hsB) / w2->hsA; hdr->CHANNEL[0].DigMin = (w2->botFullScale-w2->hsB) / w2->hsA; */ #else uint16_t pdc = PhysDimCode(w5->dimUnits[0]); hdr->SampleRate /= w2->hsA * (pdc==0 ? 0.001 : PhysDimScale(pdc)); // if physical units unspecified, assume millisecond hdr->CHANNEL[0].PhysMax = w2->topFullScale; hdr->CHANNEL[0].PhysMin = w2->botFullScale; #endif hdr->FLAG.OVERFLOWDETECTION = !w2->fsValid; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i): %f %f <%s> <%s>\n",__FILE__,__LINE__,w2->hsA,w2->hsB,w2->xUnits,w2->dataUnits); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i): %f %f\n",__FILE__,__LINE__,w2->topFullScale,w2->botFullScale); hdr->HeadLen = binHeaderSize+waveHeaderSize-16; // 16 = size of wData field in WaveHeader2 structure. } break; case 5: { WaveHeader5* w5; w5 = (WaveHeader5*)(buffer+binHeaderSize); type = w5->type; int k; size_t nTraces=1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s(line %i): %i %i %i %i\n", __FILE__, __LINE__, w5->nDim[0], w5->nDim[1], w5->nDim[2], w5->nDim[3]); for (k=1; (w5->nDim[k]!=0) && (k<4); k++) { // count number of traces nTraces *= w5->nDim[k]; } if (nTraces > 1) { // set break marker between traces hdr->EVENT.N = nTraces-1; if (reallocEventTable(hdr, hdr->EVENT.N) == SIZE_MAX) { biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed."); return; }; size_t n; for (n = 0; n < hdr->EVENT.N; n++) { hdr->EVENT.TYP[n] = 0x7ffe; hdr->EVENT.POS[n] = (n+1)*w5->nDim[0]; hdr->EVENT.DUR[n] = 0; hdr->EVENT.CHN[n] = 0; } } if (VERBOSE_LEVEL>7) { for (k=0; k<4; k++) fprintf(stdout,"%i\t%f\t%f\n",w5->nDim[k],w5->sfA[k],w5->sfB[k]); } strncpy(hdr->CHANNEL[0].Label, w5->bname, MAX_LENGTH_LABEL); hdr->CHANNEL[0].PhysDimCode = PhysDimCode(w5->dataUnits); hdr->CHANNEL[0].SPR = hdr->SPR = 1; hdr->NRec = w5->npnts; uint16_t pdc = PhysDimCode(w5->dimUnits[0]); hdr->SampleRate /= w5->sfA[0] * (pdc==0 ? 0.001 : PhysDimScale(pdc)); // if physical units unspecified, assume millisecond if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %g.x+%g \n",__FILE__,__LINE__,w5->sfA[0],w5->sfB[0]); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): |%s|%s|%s|%s|\n",__FILE__,__LINE__,w5->dimUnits[0],w5->dimUnits[1],w5->dimUnits[2],w5->dimUnits[3]); #ifdef IGOROLD hdr->CHANNEL[0].Cal = 1.0; hdr->CHANNEL[0].Off = 0.0; #else hdr->CHANNEL[0].PhysMax = w5->topFullScale; hdr->CHANNEL[0].PhysMin = w5->botFullScale; #endif if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): %f %f\n",__FILE__,__LINE__,w5->topFullScale,w5->botFullScale); hdr->FLAG.OVERFLOWDETECTION = !w5->fsValid; hdr->HeadLen = binHeaderSize+waveHeaderSize-4; // 4 = size of wData field in WaveHeader5 structure. } break; } if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) Wave name=%s, npnts=%d, type=0x%x.\n", __FILE__, __LINE__, hdr->CHANNEL[0].Label, (int)hdr->NRec, type); uint16_t gdftyp; double digmin=NAN, digmax=NAN; // Consider the number type, not including the complex bit or the unsigned bit. switch(type & ~(NT_CMPLX | NT_UNSIGNED)) { case NT_I8: gdftyp = 1; hdr->AS.bpb = 1; // char break; if (type & NT_UNSIGNED) { gdftyp++; digmin = ldexp(-1,7); digmax = ldexp( 1,7)-1; } else { digmin = 0; digmax = ldexp( 1,8)-1; } break; case NT_I16: gdftyp = 3; hdr->AS.bpb = 2; // short if (type & NT_UNSIGNED) { gdftyp++; digmin = ldexp(-1,15); digmax = ldexp( 1,15)-1; } else { digmin = 0; digmax = ldexp( 1,16)-1; } break; case NT_I32: gdftyp = 5; hdr->AS.bpb = 4; // long if (type & NT_UNSIGNED) { gdftyp++; digmin = ldexp(-1,31); digmax = ldexp( 1,31)-1; } else { digmin = 0; digmax = ldexp( 1,32)-1; } break; case NT_FP32: gdftyp = 16; hdr->AS.bpb = 4; // float digmin = -__FLT_MAX__; digmax = __FLT_MAX__; break; case NT_FP64: gdftyp = 17; hdr->AS.bpb = 8; // double digmin = -__DBL_MAX__; digmax = __DBL_MAX__; break; case 0: // text waves biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Igor/IBW: text waves not supported"); return; default: if (VERBOSE_LEVEL>7) fprintf(stderr,"type=%x \n",version); biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Igor/IBW: unsupported or unknown data type"); return; break; } if (type & NT_CMPLX) { hdr->AS.bpb *= 2; // Complex wave - twice as many points. hdr->NS *= 2; hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); strcpy(hdr->CHANNEL[2].Label,"imag part"); hdr->CHANNEL[1].Cal = 1.0; hdr->CHANNEL[1].Off = 0.0; hdr->CHANNEL[1].SPR = hdr->SPR; } typeof (hdr->NS) k; size_t bpb=0; for (k = 0; k < hdr->NS; k++) { CHANNEL_TYPE *hc = hdr->CHANNEL+k; hc->GDFTYP = gdftyp; hc->OnOff = 1; hc->DigMin = digmin; hc->DigMax = digmax; #ifdef IGOROLD hc->PhysMax = digmax * hc->Cal + hc->Off; hc->PhysMin = digmin * hc->Cal + hc->Off; #else hc->Cal = (hc->PhysMax - hc->PhysMin) / (digmax - digmin); hc->Off = hc->PhysMin - hc->DigMin * hc->Cal; if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) %f %f %f %f.\n", __FILE__, __LINE__, hc->PhysMax, hc->PhysMin, digmax, digmin); #endif hc->LeadIdCode = 0; hc->bi = bpb; hc->Transducer[0] = 0; hc->TOffset = 0; hc->LowPass = NAN; hc->HighPass = NAN; hc->Notch = NAN; hc->Impedance = NAN; hc->XYZ[0] = 0; hc->XYZ[1] = 0; hc->XYZ[2] = 0; bpb += GDFTYP_BITS[gdftyp]/8; } hdr->FILE.POS = 0; hdr->AS.first = 0; hdr->AS.length= 0; hdr->data.block = NULL; hdr->AS.rawdata = NULL; if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) %i %i %i 0x%x\n", __FILE__, __LINE__, (int)hdr->HeadLen, (int)hdr->FILE.size, (int)(hdr->AS.bpb*hdr->NRec), (int)(hdr->HeadLen+hdr->AS.bpb*hdr->NRec)); #ifndef IGOROLD size_t endpos = hdr->HeadLen + hdr->AS.bpb * hdr->NRec; if (endpos < hdr->FILE.size) { /* * If data were recorded with NeuroMatic/NClamp: http://www.neuromatic.thinkrandom.com/ * some additional information like SamplingRate, Scaling, etc. can be obtained from * a text block at the end of a file. */ size_t sz = hdr->FILE.size-endpos; char *tmpstr = malloc(sz+1); ifseek(hdr, endpos, SEEK_SET); ifread(tmpstr, 1, sz, hdr); tmpstr[sz]=0; char *ptr = tmpstr; // skip 0-bytes at the beginning of the block while ((ptr != (tmpstr+sz)) && (*ptr==0)) { ptr++; } if (ptr != tmpstr + sz) { // if block is not empty if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) [%i]<%s>\n", __FILE__, __LINE__, sz, ptr); // parse lines char *line = strtok(ptr,"\n\r\0"); CHANNEL_TYPE *hc = hdr->CHANNEL+0; struct tm t; while (line != NULL) { if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) <%s>\n", __FILE__, __LINE__, line); size_t p = strcspn(line,":"); // search for field delimiter if (!strncmp(line,"ADCname",p)) { strncpy(hc->Label,line+p+1,MAX_LENGTH_LABEL+1); hc->Label[MAX_LENGTH_LABEL]=0; } else if (!strncmp(line,"ADCunits",p)) { hc->PhysDimCode = PhysDimCode(line+p+1); if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) %s<%s>\n", __FILE__, __LINE__, line+p+1, PhysDim3(hc->PhysDimCode)); } else if (!strncmp(line,"ADCunitsX",p)) { if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) Fs=%f %s\n", __FILE__, __LINE__, hdr->SampleRate, line+p+1); if (!strcmp(line+p+1,"msec")) line[p+3]=0; hdr->SampleRate /= PhysDimScale(PhysDimCode(line+p+1)); if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) %f Hz\n", __FILE__, __LINE__, hdr->SampleRate); } else if (!strncmp(line,"ADCscale",p)) { hc->Cal = strtod(line+p+1,NULL); if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) Cal %f %s\n", __FILE__, __LINE__, hc->Cal, line+p+1); hc->PhysMax = hc->DigMax * hc->Cal; hc->PhysMin = hc->DigMin * hc->Cal; hc->Label[MAX_LENGTH_LABEL]=0; } else if (!strncmp(line,"Time",p)) { ptr = line; // replace separator with : while (*ptr) { if (*ptr==',') *ptr=':'; ptr++; } strptime(line+p+1,"%H:%M:%S",&t); if (VERBOSE_LEVEL > 7) fprintf(stdout, "%s (line %i) %s\n", __FILE__, __LINE__, line); if (VERBOSE_LEVEL > 7) { char tmp[30]; strftime(tmp,30,"%F %T",&t); fprintf(stdout, "%s (line %i) %s\n", __FILE__, __LINE__, tmp); } } else if (!strncmp(line,"Date",p)) { strptime(line+p+1,"%d %b %Y",&t); t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; if (VERBOSE_LEVEL > 7) { char tmp[30]; strftime(tmp,30,"%F %T",&t); fprintf(stdout, "%s (line %i) %s\n", __FILE__, __LINE__, tmp); } } else if (!strncmp(line,"Time Stamp",p)) { //hdr->SampleRate *= hdr->SPR*hdr->NRec/strtod(line+p+1,NULL); } line = strtok(NULL, "\n\r\0"); } hdr->T0 = tm_time2gdf_time(&t); } if (tmpstr) free(tmpstr); } #endif // not defined IGOROLD } /* * utility functions for managing List of Sweep names */ struct sweepnames_t { size_t idx; char *name; struct sweepnames_t *next; }; size_t search_sweepnames(struct sweepnames_t* list, const char* name) { /* first element starts with 1 zero is returned in case of empty list */ struct sweepnames_t* next=list; for (next=list; next!=NULL; next=next->next) { if (!strcmp(next->name, name)) return next->idx; } return 0; } struct sweepnames_t* add_sweepnames(struct sweepnames_t* list, const char* name) { struct sweepnames_t* next = (struct sweepnames_t*)malloc(sizeof(struct sweepnames_t)); next->name = strdup(name); next->idx = list==NULL ? 1 : list->idx+1; next->next = list; return next; } size_t count_sweepnames(struct sweepnames_t* list) { size_t count = 0; for (; list!=NULL; list=list->next) count++; return count; } void clear_sweepnames(struct sweepnames_t* list) { if (list==NULL) return; if (list->name) free(list->name); clear_sweepnames(list->next); free(list->next); } void sopen_itx_read (HDRTYPE* hdr) { #define IGOR_MAXLENLINE 400 char line[IGOR_MAXLENLINE+1]; char flagData = 0; char flagSupported = 1; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) start reading %s,v%4.2f format (%i)\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION,ifeof(hdr)); typeof(hdr->SPR) SPR = 0, spr = 0; typeof(hdr->NS) ns = 0; int chanNo=0, sweepNo=0; hdr->SPR = 0; hdr->NRec= 0; struct sweepnames_t* sweepname_list=NULL; /* checks the structure of the file and extracts formating information */ ifseek(hdr,0,SEEK_SET); int c = ifgetc(hdr); // read first character while (!ifeof(hdr)) { if (VERBOSE_LEVEL>8) fprintf(stdout,"%s (line %i) start reading %s,v%4.2f format (%i)\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION,(int)iftell(hdr)); int i = 0; while ( (c != -1) && (c != 10) && (c != 13) && (i < IGOR_MAXLENLINE) ) { // terminate when any line break occurs line[i++] = c; c = ifgetc(hdr); }; line[i] = 0; while (isspace(c)) c = ifgetc(hdr); // keep first non-space character of next line in buffer if (VERBOSE_LEVEL>8) fprintf(stdout,"\t%s (line %i) <%s> (%i)\n",__FILE__,__LINE__,line,(int)iftell(hdr)); if (!strncmp(line,"BEGIN",5)) { flagData = 1; spr = 0; hdr->CHANNEL[ns].bi = SPR*sizeof(double); } else if (!strncmp(line,"END",3)) { flagData = 0; if ((SPR!=0) && (SPR != spr)) { flagSupported = 0; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) ITX (not supported): %i, %i \n",__FILE__,__LINE__, SPR, spr); } else SPR = spr; if (ns==0) hdr->SPR += SPR; } else if (!strncmp(line,"X SetScale/P x",14)) { /* This line seems to have inconsistant formating, some times an comma is following the first 14 bytes, some times no comma is found. here are some examples X SetScale/P x, 0.000000000E+00, 5.000000000E-05,"s", AP101222bp_1_63_1_2 X SetScale/P x 0,5e-05,"s", f0ch1w1_1_0to0_Co_TCh; SetScale y 0,1e-09,"A", f0ch1w1_1_0to0_Co_TCh */ double TOffset = atof(strtok(line+15,",")); if (isnan(hdr->CHANNEL[ns].TOffset)) hdr->CHANNEL[ns].TOffset = TOffset; else if (fabs(hdr->CHANNEL[ns].TOffset - TOffset) > 1e-12) fprintf(stderr,"Warning TOffsets in channel #%i do not match (%f,%f)", ns, hdr->CHANNEL[ns].TOffset, TOffset); double dur = atof(strtok(NULL,",")); char *p = strchr(line,'"'); if (p != NULL) { p++; char *p2 = strchr(p,'"'); if (p2 != NULL) *p2=0; dur *= PhysDimScale(PhysDimCode(p)); } double div = spr / (hdr->SampleRate * dur); if (ns==0) { hdr->SampleRate = 1.0 / dur; } else if (hdr->SampleRate == 1.0 / dur) ; else if (div == floor(div)) { hdr->SampleRate *= div; } } else if (!strncmp(line,"X SetScale y,",13)) { char *p = strchr(line,'"'); if (p!=NULL) { p++; char *p2 = strchr(p,'"'); if (p2!=NULL) *p2=0; if (hdr->CHANNEL[ns].PhysDimCode == 0) hdr->CHANNEL[ns].PhysDimCode = PhysDimCode(p); else if (hdr->CHANNEL[ns].PhysDimCode != PhysDimCode(p)) { flagSupported = 0; // physical units do not match if (VERBOSE_LEVEL>7) fprintf(stdout,"[%s:%i] ITX (not supported): %i, %i,<%s> \n",__FILE__,__LINE__, hdr->CHANNEL[ns].PhysDimCode,PhysDimCode(p),p); } } } else if (!strncmp(line,"WAVES",5)) { if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): <%s>#%i: %i/%i\n",__FILE__,__LINE__,line,(int)ns,(int)spr,(int)hdr->SPR); char *p; p = strrchr(line,'_'); ns = 0; sweepNo = 0; if (p != NULL) { chanNo = strtol(p+1, NULL, 10); if (chanNo > 0) ns = chanNo - 1; // if decoding fails, assume there is only a single channel p[0] = 0; if (search_sweepnames(sweepname_list, line) == 0) { // when sweep not found, add to list sweepname_list = add_sweepnames(sweepname_list, line); } } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) ITX (supported %i): %i, %i, %i, %i, %i\n",__FILE__,__LINE__, flagSupported, (int)ns, (int)spr, (int)hdr->SPR, chanNo, sweepNo); if (ns >= hdr->NS) { hdr->NS = ns+1; hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): <%s>#%i: %i/%i\n",__FILE__,__LINE__,line,(int)ns,(int)spr,(int)hdr->SPR); CHANNEL_TYPE* hc = hdr->CHANNEL + ns; strncpy(hc->Label, line+6, MAX_LENGTH_LABEL); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): <%s>#%i: %i/%i\n",__FILE__,__LINE__,line,(int)ns,(int)spr,(int)hdr->SPR); hc->OnOff = 1; hc->GDFTYP = 17; hc->DigMax = (double)(int16_t)(0x7fff); hc->DigMin = (double)(int16_t)(0x8000); hc->LeadIdCode = 0; hc->Cal = 1.0; hc->Off = 0.0; hc->Transducer[0] = '\0'; hc->LowPass = NAN; hc->HighPass = NAN; hc->TOffset = NAN; hc->PhysMax = hc->Cal * hc->DigMax; hc->PhysMin = hc->Cal * hc->DigMin; hc->PhysDimCode = 0; // decode channel number and sweep number if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): <%s>#%i: %i/%i\n",__FILE__,__LINE__,line,(int)ns,(int)spr,(int)hdr->SPR); } else if (flagData) spr++; } if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): scanning %s,v%4.2f format (supported: %i)\n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION,flagSupported); if (!flagSupported) { clear_sweepnames(sweepname_list); biosigERROR(hdr, hdr->AS.B4C_ERRNUM, "This ITX format is not supported. Possible reasons: not generated by Heka-Patchmaster, corrupted, physical units do not match between sweeps, or do not fulfil some other requirements"); return; } hdr->NRec = count_sweepnames(sweepname_list); if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): [%i,%i,%i] = %i, %i\n",__FILE__,__LINE__,(int)hdr->NS,(int)hdr->SPR,(int)hdr->NRec,(int)hdr->NRec*hdr->SPR*hdr->NS, (int)hdr->AS.bpb); hdr->EVENT.N = hdr->NRec - 1; hdr->EVENT.SampleRate = hdr->SampleRate; hdr->EVENT.POS = (uint32_t*) realloc(hdr->EVENT.POS, hdr->EVENT.N * sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*) realloc(hdr->EVENT.TYP, hdr->EVENT.N * sizeof(*hdr->EVENT.TYP)); hdr->EVENT.CHN = (uint16_t*) realloc(hdr->EVENT.CHN, hdr->EVENT.N * sizeof(*hdr->EVENT.CHN)); hdr->EVENT.DUR = (uint32_t*) realloc(hdr->EVENT.DUR, hdr->EVENT.N * sizeof(*hdr->EVENT.DUR)); #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp = (gdf_time*)realloc(hdr->EVENT.TimeStamp, hdr->EVENT.N*sizeof(gdf_time)); #endif hdr->NRec = hdr->SPR; hdr->SPR = 1; hdr->AS.first = 0; hdr->AS.length = hdr->NRec; hdr->AS.bpb = sizeof(double)*hdr->NS; for (ns=0; ns < hdr->NS; ns++) { hdr->CHANNEL[ns].SPR = hdr->SPR; hdr->CHANNEL[ns].bi = sizeof(double)*ns; } double *data = (double*)realloc(hdr->AS.rawdata,hdr->NRec*hdr->SPR*hdr->NS*sizeof(double)); hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); // no swapping hdr->AS.rawdata = (uint8_t*) data; /* reads and converts data into biosig structure */ spr = 0;SPR = 0; ifseek(hdr, 0, SEEK_SET); c = ifgetc(hdr); // read first character while (!ifeof(hdr)) { int i = 0; while ( (c != -1) && (c != 10) && (c != 13) && (i < IGOR_MAXLENLINE) ) { // terminate when any line break occurs line[i++] = c; c = ifgetc(hdr); }; line[i] = 0; while (isspace(c)) c = ifgetc(hdr); // keep first non-space character of next line in buffer if (!strncmp(line,"BEGIN",5)) { flagData = 1; spr = 0; } else if (!strncmp(line,"END",3)) { flagData = 0; if (chanNo+1 == hdr->NS) SPR += spr; } else if (!strncmp(line,"X SetScale y,",13)) { //ns++; } else if (!strncmp(line,"WAVES",5)) { // decode channel number and sweep number chanNo = 0; sweepNo= 0; char *p; p = strrchr(line,'_'); if (p != NULL) { chanNo = strtol(p+1,NULL,10); if (chanNo > 0) chanNo--; // if decoding fails, assume there is only a single channel. p[0] = 0; sweepNo = search_sweepnames(sweepname_list, line); if (sweepNo > 0) sweepNo--; // if decoding fails, assume there is only a single sweep } spr = 0; if (sweepNo > 0 && chanNo==0) { hdr->EVENT.POS[sweepNo-1] = SPR; hdr->EVENT.TYP[sweepNo-1] = 0x7ffe; hdr->EVENT.DUR[sweepNo-1] = 0; hdr->EVENT.CHN[sweepNo-1] = 0; #if (BIOSIG_VERSION >= 10500) hdr->EVENT.TimeStamp[sweepNo-1] = 0; #endif } } else if (flagData) { double val = atof(line); data[hdr->NS*(SPR + spr) + chanNo] = val; spr++; } } clear_sweepnames(sweepname_list); hdr->EVENT.N = sweepNo; if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): reading %s,v%4.2f format finished \n",__FILE__,__LINE__,GetFileTypeString(hdr->TYPE),hdr->VERSION); hdr->SPR = 1; hdr->NRec *= hdr->SPR; hdr->AS.first = 0; hdr->AS.length = hdr->NRec; hdr->AS.bpb = sizeof(double)*hdr->NS; #undef IGOR_MAXLENLINE } #ifdef __cplusplus } #endif stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_axg_read.c0000664000175000017500000004674214752215315016475 /* sopen_axg_read is a helper function to sopen, reading AXG data. Copyright (C) 2008-2014 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define _GNU_SOURCE #include #include #include #include #include #include #if !defined(__APPLE__) && defined (_LIBICONV_H) #define iconv libiconv #define iconv_open libiconv_open #define iconv_close libiconv_close #endif #include "../biosig-dev.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) void sopen_axg_read(HDRTYPE* hdr) { hdr->FILE.LittleEndian = 0; // read whole file into RAM size_t count = hdr->HeadLen; while (!ifeof(hdr)) { const int minsize = 1024; hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, 2*count+minsize); count += ifread(hdr->AS.Header+count, 1, count+minsize, hdr); } ifclose(hdr); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %p %i\n", __FILE__, __LINE__, hdr->CHANNEL, hdr->NS ); int32_t nCol; switch ((int) hdr->VERSION) { case 1: case 2: nCol = bei16p(hdr->AS.Header+6); hdr->HeadLen = 8; break; case 3: case 4: case 5: case 6: nCol = bei32p(hdr->AS.Header+8); hdr->HeadLen = 12; break; default: biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - unsupported version number"); return; } /* hack: for now each trace (i.e. column) becomes a separate channel - later the traces of the channels will be reorganized */ CHANNEL_TYPE *TEMPCHANNEL = (CHANNEL_TYPE*)malloc(nCol*sizeof(CHANNEL_TYPE)); char **ValLabel = (char**)malloc(nCol*sizeof(char*)); uint32_t *keyLabel = (uint32_t*)malloc(nCol*sizeof(uint32_t)); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %p %i\n", __FILE__, __LINE__, hdr->CHANNEL, hdr->NS ); /******* read all column/traces ******/ int32_t k; uint8_t *pos = hdr->AS.Header+hdr->HeadLen; hdr->SPR = beu32p(pos); switch ((int) hdr->VERSION) { case 1: for (k = 0; k < nCol; k++) { CHANNEL_TYPE *hc = TEMPCHANNEL+k; hc->GDFTYP = 16; //float hc->PhysDimCode = 0; hc->SPR = beu32p(pos); int strlen = pos[4]; // string in Pascal format if (strlen > 79) { biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - invalid title length "); return; } /* Organize channels */ uint32_t i; for (i = 0; i < hdr->NS; i++) { // check if channel with same title already exists if (!memcmp(ValLabel[hdr->NS], pos+4, strlen)) { keyLabel[k] = hdr->NS; break; } } if (i==hdr->NS) { // in case of new title, add another channel ValLabel[hdr->NS] = (char*)pos+4; keyLabel[k] = hdr->NS; hdr->NS++; } // start of data section hc->bufptr = pos+84; pos += 84 + hc->SPR * sizeof(float); } break; case 2: for (k = 0; k < nCol; k++) { CHANNEL_TYPE *hc = TEMPCHANNEL+k; hc->GDFTYP = 3; // int16 hc->PhysDimCode = 0; hc->SPR = beu32p(pos); if (k==0) { hc->Off = bef32p(pos+84); hc->Cal = bef32p(pos+88); hc->bufptr = NULL; hdr->SampleRate = 1.0 / hc->Cal; } else { hc->Cal = bef32p(pos+84); hc->Off = 0.0; hc->bufptr = pos + 88; } int strlen = pos[4]; // string in Pascal format if (strlen > 79) { biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - invalid title length "); return; } biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - version 2 not supported yet "); return; // start of data sectioB pos += (k==0 ? 92 : 88 + hc->SPR * sizeof(int16_t) ); } break; case 6: for (k=0; k < nCol; k++) { if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %p %i\n", __FILE__, __LINE__, hdr->CHANNEL, k ); CHANNEL_TYPE *hc = TEMPCHANNEL+k; hc->SPR = beu32p(pos); uint32_t datatype = beu32p(pos+4); size_t titleLen = beu32p(pos+8); char *inbuf = (char*)pos + 12; hc->bufptr = pos + 12 + titleLen; if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %i %i %i\n", __FILE__, __LINE__, (int)datatype, (int)titleLen, (int)hc->SPR); /* // The only types used for data file columns are... // ShortArrayType = 4 IntArrayType = 5 // FloatArrayType = 6 DoubleArrayType = 7 // SeriesArrayType = 9 ScaledShortArrayType = 10 */ hc->Cal = 1.0; hc->Off = 0.0; hc->GDFTYP = datatype; //TEMPCHANNEL.GDFTYP uses a different encoding than standard GDFTYP hc->OnOff = 1; switch (datatype) { case 4: // int16 hc->GDFTYP=3; break; case 5: // int32 hc->GDFTYP=5; break; case 6: // float32 hc->GDFTYP=16; break; case 7: // double hc->GDFTYP=17; break; case 9: hc->GDFTYP = 17; // series // double firstval = bef64p(hc->bufptr); double increment = bef64p(hc->bufptr+8); hc->bufptr = NULL; hc->OnOff = 0; if (!memcmp(inbuf,"\0T\0i\0m\0e\0 \0(\0s\0)\0",8)) { hdr->SampleRate = 1.0/increment; //hc->OnOff = 2; // time axis } else { biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "AXG: series data not being a Time axis is not supported. "); return; } break; case 10: // scaled short hc->Cal = bef64p(hc->bufptr); hc->Off = bef64p(hc->bufptr+8); break; default: hc->OnOff = 0; } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %p %i\n", __FILE__, __LINE__, hdr->CHANNEL, k ); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): %i %i %i %i\n", __FILE__, __LINE__, (int)hc->SPR, (int)datatype, (int)titleLen, (int)(pos-hdr->AS.Header) ); /* Organize channels find number of channels and setup data structure that assignes each column to a channel ValLabel contains the different Labels - one for each channel keyLabel contains the channel number for the corresponding column */ uint32_t i; for (i = 0; i < hdr->NS; i++) { // check if channel with same title already exists uint32_t prevTitleLen = beu32p((uint8_t*)(ValLabel[i])-4); if ((titleLen == prevTitleLen) && !memcmp(ValLabel[i], pos+12, titleLen)) { keyLabel[k] = i; break; } } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %p %i\n", __FILE__, __LINE__, hdr->CHANNEL, k ); if (i==hdr->NS) { // in case of new title, add another channel ValLabel[hdr->NS] = (char*)pos+12; // pointer to title of channel 'nLabel', length of title is stored in beu32p(pos+8) keyLabel[k] = hdr->NS; hdr->NS++; } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %p %i\n", __FILE__, __LINE__, hdr->CHANNEL, k ); // pointer to data sections hc->bufptr = pos + 12 + titleLen; // move pos to the starting position of the next column pos += 12 + titleLen; // position of next column switch (datatype) { case 4: pos += hc->SPR * sizeof(int16_t); break; case 5: //int32 case 6: //float pos += hc->SPR * 4; break; case 7: pos += hc->SPR * sizeof(double); break; case 9: pos += 2 * sizeof(double); break; case 10: pos += 2 * sizeof(double) + hc->SPR * sizeof(int16_t); break; default: biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"error reading AXG: unsupported data type"); } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): %i %i %i %i\n", __FILE__, __LINE__, (int)hc->SPR, (int)datatype, (int)titleLen, (int)(pos-hdr->AS.Header) ); } break; default: biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG version is not supported"); } if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) %p %p %i %i\n", __FILE__, __LINE__, TEMPCHANNEL, hdr->CHANNEL, (int)hdr->NS , (int)sizeof(CHANNEL_TYPE)); /* convert columns/traces into channels */ hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE)); uint32_t ns; for (ns=0; ns < hdr->NS; ns++) { CHANNEL_TYPE *hc = hdr->CHANNEL + ns; hc->SPR = 0; hc->GDFTYP = 0; hc->OnOff = 1; } size_t EventN = 0; hdr->SPR = 0; if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i) NS=%i nCol=%i\n", __FILE__, __LINE__, hdr->NS, nCol ); int flag_traces_of_first_sweep_done=0; for (k=0; k < nCol; k++) { /* copy essential parameters ´(GDFTYP, OnOff, Cal, Off) from TEMPCHANNEL and keep track of the number of samples SPR for each channel */ // define GDFTYP, Cal, Off ns = keyLabel[k]; // channel number for current column CHANNEL_TYPE *hc = hdr->CHANNEL + ns; hc->SPR += TEMPCHANNEL[k].SPR; switch (TEMPCHANNEL[k].GDFTYP) { case 4: // int16 if (hc->GDFTYP < 3) hc->GDFTYP = 3; break; case 5: // int32 if (hc->GDFTYP < 5) hc->GDFTYP = 5; break; case 6: // float32 if (hc->GDFTYP < 16) hc->GDFTYP = 16; break; case 7: // double if (hc->GDFTYP < 17) hc->GDFTYP = 17; break; case 10: hc->GDFTYP = 3; // scaled short if (hc->GDFTYP < 16) hc->GDFTYP = 16; break; default: hc->OnOff = 0; } if (!flag_traces_of_first_sweep_done) { hc->Cal = TEMPCHANNEL[k].Cal; hc->Off = TEMPCHANNEL[k].Off; } else { if (hc->Cal != TEMPCHANNEL[k].Cal || hc->Off != TEMPCHANNEL[k].Off) { // in case input is scaled short, output shoud be float hc->GDFTYP = max(16, hc->GDFTYP); } } if (hdr->SPR < hc->SPR) hdr->SPR = hc->SPR; if (ns+1 == hdr->NS) { flag_traces_of_first_sweep_done = 1; // if current column corresponds to last channel, ... // check if all traces of the same sweep have the same length, and ... for (ns=0; ns < hdr->NS; ns++) { CHANNEL_TYPE *hc = hdr->CHANNEL + ns; if (hc->OnOff != 1) continue; else if (hdr->SPR != hc->SPR) { if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): SPR=%d #%dspr=%d \n", __FILE__, __LINE__, hdr->SPR, ns, hc->SPR ); biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - SPR differs between channel"); } } // ... add segment break in event table. if ( hdr->EVENT.N + 1 >= EventN ) { EventN += max(EventN, 16); hdr->EVENT.POS = (uint32_t*)realloc(hdr->EVENT.POS, EventN * sizeof(*hdr->EVENT.POS)); hdr->EVENT.TYP = (uint16_t*)realloc(hdr->EVENT.TYP, EventN * sizeof(*hdr->EVENT.TYP)); } hdr->EVENT.TYP[hdr->EVENT.N] = 0x7ffe; hdr->EVENT.POS[hdr->EVENT.N] = hdr->SPR; hdr->EVENT.N++; } } hdr->EVENT.N--; // ignore last separator event hdr->NRec = hdr->SPR; hdr->SPR = 1; uint32_t bi8 = 0; for (ns=0; ns < hdr->NS; ns++) { CHANNEL_TYPE *hc = hdr->CHANNEL+ns; hc->bi8 = bi8; hc->bi = bi8/8; if (hc->OnOff != 1) hc->SPR = 0; else bi8 += GDFTYP_BITS[hc->GDFTYP]; } hdr->AS.bpb = bi8/8; for (ns=0; ns < hdr->NS; ns++) { CHANNEL_TYPE *hc = hdr->CHANNEL+ns; // define hdr->channel[.].Label, hdr->channel[.].PhysDim if (hdr->Version <= 2) { // PascalToCString(ValLabel[ns]); // shift by 1 byte and terminate 0 char int strlen = min(ValLabel[ns][0],MAX_LENGTH_LABEL); strncpy(hc->Label, (ValLabel[ns])+1, strlen); char *u1 = strrchr(ValLabel[ns],'('); char *u2 = strrchr(ValLabel[ns],')'); if (u1 != NULL && u2 != NULL && u1 < u2) { *u1 = 0; *u2 = 0; hc->PhysDimCode = PhysDimCode(u1+1); } } else if (hdr->Version <= 6) { char *inbuf = ValLabel[ns]; size_t inlen = beu32p((uint8_t*)(ValLabel[ns])-4); char *outbuf = hc->Label; size_t outlen = MAX_LENGTH_LABEL+1; #if defined(_ICONV_H) || defined (_LIBICONV_H) || defined(_ICONV_H_) iconv_t ICONV = iconv_open("UTF-8","UCS-2BE"); size_t reticonv = iconv(ICONV, &inbuf, &inlen, &outbuf, &outlen); iconv_close(ICONV); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i): %i %i %i %"PRIiPTR"\n", __FILE__, __LINE__, (int)hc->SPR, (int)inlen, (int)(pos-hdr->AS.Header), reticonv ); if (reticonv == (size_t)(-1) ) { perror("AXG - conversion of title failed!!!"); biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - conversion of title failed"); return; } *outbuf=0; #else ++inbuf; int i = min(MAX_LENGTH_LABEL, titleLen/2); for (; i>0 ; i-- ) { *outbuf= *inbuf; inbuf += 2; outbuf++; } outbuf = 0; #endif char *u1 = strrchr(hc->Label,'('); char *u2 = strrchr(hc->Label,')'); if (u1 != NULL && u2 != NULL && u1 < u2) { *u1 = 0; *u2 = 0; hc->PhysDimCode = PhysDimCode(u1+1); } } // these might be reorganized below hc->DigMax = 1e9; hc->DigMin = -1e9; hc->PhysMax = hc->DigMax; hc->PhysMin = hc->DigMin; hc->LeadIdCode = 0; hc->Transducer[0] = 0; hc->Cal = 1.0; hc->Off = 0.0; hc->TOffset = 0; hc->HighPass = NAN; hc->LowPass = NAN; hc->Notch = NAN; hc->Impedance = INFINITY; hc->fZ = NAN; hc->XYZ[0] = 0.0; hc->XYZ[1] = 0.0; hc->XYZ[2] = 0.0; } hdr->AS.rawdata = (uint8_t*)realloc( hdr->AS.rawdata, hdr->AS.bpb*hdr->SPR*hdr->NRec); for (ns=0; ns < hdr->NS; ns++) { CHANNEL_TYPE *hc = hdr->CHANNEL + ns; hc->SPR = 0; } for (k=0; k < nCol; k++) { ns = keyLabel[k]; CHANNEL_TYPE *hc = hdr->CHANNEL + ns; if (hc->OnOff != 1) continue; uint32_t i; switch (hc->GDFTYP) { case 3: assert(TEMPCHANNEL[k].GDFTYP==4); for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(int16_t*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = bei16p(TEMPCHANNEL[k].bufptr + i*2); } break; case 5: switch (TEMPCHANNEL[k].GDFTYP) { case 4: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(int32_t*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = bei16p(TEMPCHANNEL[k].bufptr + i*2); } break; case 5: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(int32_t*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = bei32p(TEMPCHANNEL[k].bufptr + i*4); } break; default: biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - data conversion not supported "); return; } break; case 16: switch (TEMPCHANNEL[k].GDFTYP) { case 4: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(float*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = (float)bei16p(TEMPCHANNEL[k].bufptr + i*2); } break; case 5: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(float*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = (float)bei32p(TEMPCHANNEL[k].bufptr + i*4); } break; case 6: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(float*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = bef32p(TEMPCHANNEL[k].bufptr + i*4); } break; case 10: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(float*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = bei16p(TEMPCHANNEL[k].bufptr + i*2) * TEMPCHANNEL[k].Cal + TEMPCHANNEL[k].Off; } break; default: biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - data conversion not supported "); return; } break; case 17: switch (TEMPCHANNEL[k].GDFTYP) { case 4: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(double*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = (double)bei16p(TEMPCHANNEL[k].bufptr + i*2); } break; case 5: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(double*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = (double)bei32p(TEMPCHANNEL[k].bufptr + i*4); } break; case 6: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(double*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = (double)bef32p(TEMPCHANNEL[k].bufptr + i*4); } break; case 7: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(double*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = bef64p(TEMPCHANNEL[k].bufptr + i*8); } break; case 10: for (i=0; i < TEMPCHANNEL[k].SPR; i++) { *(double*)(hdr->AS.rawdata + hc->bi + (hc->SPR + i) * hdr->AS.bpb) = bei16p(TEMPCHANNEL[k].bufptr + i*2) * TEMPCHANNEL[k].Cal + TEMPCHANNEL[k].Off; } break; default: biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - data conversion not supported "); return; } break; default: biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - unsupported target data type"); return; } hc->SPR += TEMPCHANNEL[k].SPR; } for (ns=0; ns < hdr->NS; ns++) { CHANNEL_TYPE *hc = hdr->CHANNEL + ns; hc->SPR = hdr->SPR; } // free intermediate data structure to reorganized column/trace to channels if(TEMPCHANNEL) free(TEMPCHANNEL); if(keyLabel) free(keyLabel); if(ValLabel) free(ValLabel); // data is stored on hdr->AS.rawdata in such a way that swapping must not be applied hdr->FILE.LittleEndian = (__BYTE_ORDER == __LITTLE_ENDIAN); hdr->AS.first = 0; hdr->AS.length = (size_t)hdr->NRec; // read Comments size_t szComments = beu32p(pos); char *inbuf = (char*)pos+4; char *Comments = malloc(szComments+1); char *outbuf = Comments; size_t outlen = szComments+1; size_t inlen = szComments; iconv_t ICONV = iconv_open("UTF-8","UCS-2BE"); size_t reticonv = iconv(ICONV, &inbuf, &inlen, &outbuf, &outlen); iconv_close(ICONV); if (reticonv == (size_t)(-1) ) { perror("AXG - conversion of comments failed!!!"); biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - conversion of comments failed"); return; } Comments[outlen]=0; if (VERBOSE_LEVEL >7) fprintf(stdout,"\n=== COMMENT === \n %s\n",Comments); pos += 4+szComments; // read Notes size_t szNotes = beu32p(pos); inbuf = (char*)pos+4; char *Notes = malloc(szNotes+1); outbuf = Notes; outlen = szNotes+1; inlen = szNotes; ICONV = iconv_open("UTF-8","UCS-2BE"); reticonv = iconv(ICONV, &inbuf, &inlen, &outbuf, &outlen); iconv_close(ICONV); if ( reticonv == (size_t)(-1) ) { biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"AXG - conversion of Notes failed"); return; } Notes[outlen]=0; if (VERBOSE_LEVEL >7) fprintf(stdout,"=== NOTES === \n %s\n",Notes); pos += 4+szNotes; /****** parse Date and Time ********/ struct tm T; #ifdef __GLIBC__ strptime(strstr(Notes,"Created on ")+11, "%a %b %d %Y", &T); strptime(strstr(Notes,"acquisition at ")+15, "%T", &T); hdr->T0 = tm_time2gdf_time(&T); #else char DATE[30]; strncpy(DATE, strstr(Notes,"Created on ")+11, 30); DATE[29] = 0; strtok(DATE, "\n\r"); // cut at newline char *tmp = strtok(DATE, " "); // day of week - skip tmp = strtok(NULL, " "); // abreviated month name T.tm_mon = month_string2int(tmp); tmp = strtok(NULL, " "); // day of month T.tm_mday = atoi(tmp); tmp = strtok(NULL , " "); // year T.tm_year = atoi(tmp) - 1900; strncpy(DATE, strstr(Notes,"acquisition at ")+15, 9); DATE[9] = 0; tmp = strtok(DATE, " :"); T.tm_hour = atoi(tmp); tmp = strtok(NULL, " :"); T.tm_min = atoi(tmp); tmp = strtok(NULL, " :"); T.tm_sec = atoi(tmp); hdr->T0 = tm_time2gdf_time(&T); #endif hdr->AS.fpulse = Notes; free(Comments); if (VERBOSE_LEVEL > 7) fprintf(stdout,"%s (line %i)\n", __FILE__, __LINE__ ); } stimfit-0.16.7/src/biosig/biosig4c++/t210/sopen_hdf5.c0000664000175000017500000000332614752215315015540 /* Copyright (C) 2021 Alois Schloegl This file is part of the "BioSig for C/C++" repository (biosig4c++) at http://biosig.sf.net/ BioSig 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 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #ifdef WITH_HDF5 #include #include #endif #include "../biosig.h" int sopen_hdf5(HDRTYPE* hdr) { #ifdef WITH_HDF5 /* file hdr->FileName is already opened and hdr->HeadLen bytes are read These are available from hdr->AS.Header. ToDo: populate hdr */ size_t count = hdr->HeadLen; fprintf(stdout,"Trying to read HDF data using \"%s\"\n",H5_VERS_INFO); // identify which type/origin of HDF5 biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Error reading HDF5 file"); ifclose(hdr); return(-1); #else // WITH_MATIO biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "SOPEN(HDF5): - HDF5 format not supported - libbiosig need to be recompiled with libhdf5 support."); return(-1); #endif // WITH_MATIO } stimfit-0.16.7/src/libstfnum/0000775000175000017500000000000014764352501011630 5stimfit-0.16.7/src/libstfnum/spline.h0000775000175000017500000000302314750344764013223 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file spline.h * \author John Burkardt, Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Cubic spline interpolation. * * * Based on algorithms by John Burkardt: * http://www.scs.fsu.edu/~burkardt/index.html */ #ifndef _SPLINE_H #define _SPLINE_H namespace stfnum { Vector_double d3_np_fs(Vector_double& a, const Vector_double& b); void dvec_bracket3 (const Vector_double& t, double tval, int& left ); Vector_double spline_cubic_set ( const Vector_double& t, const Vector_double& y, int ibcbeg, double ybcbeg, int ibcend, double ybcend ); double spline_cubic_val (const Vector_double& t, double tval, const Vector_double& y, const Vector_double& ypp, double& ypval, double& yppval ); } #endif stimfit-0.16.7/src/libstfnum/measure.cpp0000664000175000017500000004042714750344764013733 // Routines for measuring basic event properties // last revision: 24-Jan-2011 // C. Schmidt-Hieber, christsc@gmx.de // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file measlib.cpp * \author Christoph Schmidt-Hieber, Peter Jonas * \date 2011-01-24 * \brief Functions for measuring kinetics of events within waveforms. * * * For an example how to use these functions, see Recording::Measure(). */ #include #ifdef _OPENMP #include #endif #include "./stfnum.h" #include "./measure.h" int compareDouble(const void *a, const void *b) { return ( ( *(double*)a > *(double*)b ) - ( *(double*)a < *(double*)b ) ); } double stfnum::base(enum stfnum::baseline_method base_method, double& var, const std::vector& data, std::size_t llb, std::size_t ulb) { if (data.size()==0) return 0; if (llb>ulb || ulb>=data.size()) { return NAN; } size_t n = ulb - llb + 1; double base; assert(n > 0); assert(n <= data.size()); if (base_method == stfnum::median_iqr) { // make copy of the data for sorting double *a = (double*)malloc(n * sizeof(double)); for (size_t i = 0; i < n; ++i) { a[i] = data[i + llb]; } qsort(a,n,sizeof(double),&compareDouble); // get the median if (n % 2) base = a[(n-1)/2]; else { n /=2; base = (a[n-1] + a[n]) / 2; } /* * compute inter-quartile range (IQR) and return in "var" * interpolate as average of upper and lower bound * and make sure that indices are within [0,n-1] interval */ double Q32 = a[std::min((long)(n-1), (long)ceil(3*n/4.0-1))] + a[std::max(0l, (long)floor(3*n/4.0-1))]; double Q12 = a[std::min((long)(n-1), (long)ceil( n/4.0-1))] + a[std::max(0l, (long)floor( n/4.0-1))]; var = (Q32 - Q12) / 2; free(a); return base; } // else if (method == mean_baseline) double sumY=0.0; //according to the pascal version, every value //within the window shall be summed up: #ifdef _OPENMP #pragma omp parallel for reduction(+:sumY) #endif for (int i=(int)llb; i<=(int)ulb;++i) { sumY+=data[i]; } base=sumY/n; // second pass to calculate the variance: double varS=0.0; double corr=0.0; #ifdef _OPENMP #pragma omp parallel for reduction(+:varS,corr) #endif for (int i=(int)llb; i<=(int)ulb;++i) { double diff=data[i]-base; varS+=diff*diff; // correct for floating point inaccuracies: corr+=diff; } corr=(corr*corr)/n; var = (varS-corr)/(n-1); return base; } double stfnum::peak(const std::vector& data, double base, std::size_t llp, std::size_t ulp, int pM, stfnum::direction dir, double& maxT) { if (llp>ulp || ulp>=data.size()) { maxT = NAN; return NAN; } double max=data[llp]; maxT=(double)llp; double peak=0.0; if (pM > 0) { for (std::size_t i=llp+1; i <=ulp; i++) { //Calculate peak as the average over pM points around the point i peak=0.0; div_t Div1=div((int)pM-1, 2); int counter = 0; int start = i-Div1.quot; if (start < 0) start = 0; for (counter=start; counter <= start+pM-1 && counter < (int)data.size(); counter++) peak+=data[counter]; peak /= (counter-start); //Set peak for BOTH if (dir == stfnum::both && fabs(peak-base) > fabs (max-base)) { max = peak; maxT = (double)i; } //Set peak for UP if (dir == stfnum::up && peak-base > max-base) { max = peak; maxT = (double)i; } //Set peak for DOWN if (dir == stfnum::down && peak-base < max-base) { max = peak; maxT = (double)i; } } //End loop: data points peak = max; //End peak and base calculation //------------------------------- } else { if (pM==-1) { // calculate the average within the peak window double sumY=0; #ifdef _OPENMP #pragma omp parallel for reduction(+:sumY) #endif for (int i=(int)llp; i<=(int)ulp;++i) { sumY+=data[i]; } int n=(int)(ulp-llp+1); peak=sumY/n; maxT=(double)((llp+ulp)/2.0); } else { maxT = NAN; peak = NAN; } } return peak; } double stfnum::threshold( const std::vector& data, std::size_t llp, std::size_t ulp, double slope, double& thrT, std::size_t windowLength ) { thrT = -1; if (data.size()==0) return 0.0; // lower limit peak (ulb) has to be zero at least // upper limit peak (ulb) has to be < data.size()-windowLength (data[i+windowLength] will be used) if (llp > ulp || ulp >= data.size()) { thrT = NAN; return NAN; } if (ulp + windowLength > data.size()) { thrT = NAN; return NAN; } double threshold = 0.0; // find Slope within peak window: for (std::size_t i=llp; i < ulp; ++i) { double diff = data[i + windowLength] - data[i]; if (diff > slope * windowLength) { threshold=(data[i+windowLength] + data[i]) / 2.0; thrT = i + windowLength/2.0; break; } } return threshold; } double stfnum::risetime(const std::vector& data, double base, double ampl, double left, double right, double frac, std::size_t& tLoId, std::size_t& tHiId, double& tLoReal) { if (frac <= 0 || frac >=0.5) { tLoReal = NAN; return NAN; } double lo = frac; double hi = 1.0-frac; //Lo%of peak if (right<0 || left<0 || right>=data.size()) { tLoReal = NAN; return NAN; } tLoId=(int)right>=1? (int)right:1; do { --tLoId; } while (fabs(data[tLoId]-base)>fabs(lo*ampl) && tLoId>left); //Hi%of peak tHiId=tLoId; do { ++tHiId; } while (fabs(data[tHiId]-base)& data, double base, double ampl, double left, double right, double frac, double& innerTLoReal, double& innerTHiReal, double& outerTLoReal, double& outerTHiReal ) { if (frac <= 0 || frac >=0.5) { innerTLoReal = NAN; innerTHiReal = NAN; outerTLoReal = NAN; outerTHiReal = NAN; return NAN; } #define NDEBUG #ifndef NDEBUG fprintf(stdout,"%s %i:RISETIME2\n",__FILE__,__LINE__); #endif double lo = frac; double hi = 1.0-frac; /* outer_tLoId first index from left which is above lo*ampl outer_tHiId last index from left which is below hi*ampl inner_tLoId last index from left which is below lo*ampl inner_tHiId first index from left which is above hi*ampl Note: in noise free case (outer_tHiId==inner_tHiId-1) and (outer_tLoId==inner_tLoId+1) are true. */ long outer_tLoId=-1, outer_tHiId=-1, inner_tLoId=-1, inner_tHiId=-1; long k; //Lo%of peak if (right<0 || left<0 || right>=data.size()) { innerTLoReal = NAN; innerTHiReal = NAN; outerTLoReal = NAN; outerTHiReal = NAN; return NAN; } #ifndef NDEBUG fprintf(stdout,"%s %i:RISETIME2\n",__FILE__,__LINE__); #endif for (k=(long)left; k<=(long)right; k++) { double v = fabs(data[k]-base); if (v < fabs(lo*ampl)) inner_tLoId = k; if (v < fabs(hi*ampl)) outer_tHiId = k; } #ifndef NDEBUG fprintf(stdout,"%s %i:RISETIME2 r:%f l:%f \n",__FILE__,__LINE__,right,left); #endif for (k=(long)right; k>=(long)left; k--) { double v = fabs(data[k]-base); if (v > fabs(lo*ampl)) outer_tLoId = k; if (v > fabs(hi*ampl)) inner_tHiId = k; } #ifndef NDEBUG fprintf(stdout,"%s %i:RISETIME2: %i %i %i %i\n",__FILE__,__LINE__,(int)outer_tLoId,(int)inner_tLoId,(int)inner_tHiId,(int)outer_tHiId); #endif //*** Inner Risetime ***/ if (inner_tLoId < 0) innerTLoReal = NAN; else { double yLong2 = data[inner_tLoId+1]; double yLong1 = data[inner_tLoId]; if (yLong2-yLong1 != 0) innerTLoReal = inner_tLoId + fabs((lo*ampl+base-yLong1)/(yLong2-yLong1)); else innerTLoReal=(double)inner_tLoId; } //Hi%of peak if (inner_tHiId < 1) innerTHiReal = NAN; else { double yLong2 = data[inner_tHiId]; double yLong1 = data[inner_tHiId-1]; if (yLong2 - yLong1 != 0) innerTHiReal = inner_tHiId - fabs(((yLong2-base)-hi*ampl)/(yLong2-yLong1)); else innerTHiReal=(double)inner_tHiId; } #ifndef NDEBUG fprintf(stdout,"%s %i:RISETIME2 %f %s\n",__FILE__,__LINE__,innerTHiReal-innerTLoReal,innerTHiReal& data, double base, double ampl, double left, double right, double center, std::size_t& t50LeftId, std::size_t& t50RightId, double& t50LeftReal) { if (center<0 || center>=data.size() || data.size()<=2 || left<-1) { t50LeftReal = NAN; return NAN; } t50LeftId=(int)center>=1? (int)center:1; if (t50LeftId-1 >= data.size()) { #ifndef NDEBUG std::cout << "t50LeftId-1 >= data.size()" << t50LeftId-1 << " " << data.size() << std::endl; #endif return NAN; } do { --t50LeftId; } while (fabs(data[t50LeftId]-base)>fabs(0.5 * ampl) && t50LeftId > left); //Right side half duration if ((std::size_t)center <= data.size()-2) { t50RightId = center; } else { t50RightId = data.size() >= 2? data.size()-2 : 0; } if (right >= data.size() || t50RightId+1 >= data.size()) { #ifndef NDEBUG std::cout << "right, data.size(), t50RightId+1 " << right << " " << data.size() << " " << t50RightId+1 << std::endl; #endif return NAN; } do { ++t50RightId; } while (fabs(data[t50RightId]-base)>fabs(0.5 * ampl) && t50RightId < right); //calculation of real values by linear interpolation: //Left side double yLong2=data[t50LeftId+1]; double yLong1=data[t50LeftId]; if (yLong2-yLong1 !=0) { t50LeftReal=(double)(t50LeftId+ fabs((0.5*ampl-(yLong1-base))/(yLong2-yLong1))); } else { t50LeftReal=(double)t50LeftId; } //Right side yLong2=data[t50RightId]; yLong1=data[t50RightId-1]; double t50RightReal=0.0; if (yLong2-yLong1 !=0) { t50RightReal=(double)(t50RightId- fabs((0.5*ampl-(yLong2-base))/fabs(yLong2-yLong1))); } else { t50RightReal=(double)t50RightId; } return t50RightReal-t50LeftReal; } double stfnum::maxRise(const std::vector& data, double left, double right, double& maxRiseT, double& maxRiseY, std::size_t windowLength) { size_t rightc = lround(right); size_t leftc = lround(left); if (leftc >= data.size()-windowLength) { leftc = data.size()-windowLength-1; } if (rightc >= data.size() || data.size() < windowLength) { maxRiseY = NAN; maxRiseT = NAN; return NAN; } double maxRise = -INFINITY; // -Infinity maxRiseT = NAN; // non-a-number size_t i,j; for (i = leftc, j = leftc + windowLength; j <= rightc; i++, j++) { double diff = fabs( data[i] - data[j] ); if (maxRise& data, double left, double right, double& maxDecayT, double& maxDecayY, std::size_t windowLength) { size_t rightc = lround(right); size_t leftc = lround(left); if (leftc >= data.size()-windowLength) { leftc = data.size()-windowLength-1; } if (rightc >= data.size() || data.size() < windowLength) { maxDecayT = NAN; maxDecayY = NAN; return NAN; } double maxDecay = -INFINITY; // -Infinity maxDecayT = NAN; // non-a-number size_t i,j; for (j = leftc, i = leftc + windowLength; i < rightc; i++, j++) { double diff = fabs( data[i] - data[j] ); if (maxDecay& data, std::size_t left, std::size_t right) { // data testing not zero //if (!data.size()) return 0; if (data.size()==0) return 0; // cursor testing out of bounds if (left>right || right>data.size()) { return NAN; } // use interpolated data double y2 = ( data[right]+data[right+1] )/(double)2.0; double y1 = ( data[left]+data[left+1] )/(double)2.0; double t2 = (double)(right-0.5); double t1 = (double)(left-0.5); double SlopeVal = (y2-y1)/(t2-t1); return SlopeVal; } #endif // WITH_PSLOPE stimfit-0.16.7/src/libstfnum/measure.h0000775000175000017500000002201014750344764013367 // Header file for the stimfit namespace // Routines for measuring basic event properties // last revision: 24-Jan-2011 // C. Schmidt-Hieber, christsc@gmx.de // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file measure.h * \author Christoph Schmidt-Hieber, Peter Jonas * \date 2011-01-24 * \brief Functions for measuring kinetics of events within waveforms. * * * For an example how to use these functions, see Recording::Measure(). */ #ifndef _MEASLIB_H #define _MEASLIB_H #include #include "../libstfio/stfio.h" namespace stfnum { /*! \addtogroup stfgen * @{ */ //! Calculate the average of all sampling points between and including \e llb and \e ulb. /*! \param method: 0: mean and s.d.; 1: median * \param var Will contain the variance on exit (only when method=0). * \param data The data waveform to be analysed. * \param llb Averaging will be started at this index. * \param ulb Index of the last data point included in the average (legacy of the PASCAL version). * \param llp Lower limit of the peak window (see stfnum::peak()). * \param ulp Upper limit of the peak window (see stfnum::peak()). * \return The baseline value - either the mean or the median depending on method. */ StfioDll double base(enum stfnum::baseline_method method, double& var, const std::vector& data, std::size_t llb, std::size_t ulb); //! Find the peak value of \e data between \e llp and \e ulp. /*! Note that peaks will be detected by measuring from \e base, but the return value * is given from 0. Data points at both \e llp and \e ulp will be included in the search * (legacy of Stimfit for PASCAL). * \param data The data waveform to be analysed. * \param base The baseline value. * \param llp Lower limit of the peak window. * \param ulp Upper limit of the peak window. * \param pM If \e pM > 1, a sliding (boxcar) average of width \e pM will be used * to measure the peak. * \param dir Can be \n * stfnum::up for positive-going peaks, \n * stfnum::down for negative-going peaks or \n * stfnum::both for negative- or positive-going peaks, whichever is larger. * \param maxT On exit, the index of the peak value. May be interpolated if \e pM > 1. * \return The peak value, measured from 0. */ StfioDll double peak( const std::vector& data, double base, std::size_t llp, std::size_t ulp, int pM, stfnum::direction, double& maxT); //! Find the value within \e data between \e llp and \e ulp at which \e slope is exceeded. /*! \param data The data waveform to be analysed. * \param llp Lower limit of the peak window. * \param ulp Upper limit of the peak window. * \param thrT On exit, The interpolated time point of the threshold crossing * in units of sampling points, or a negative value if the threshold wasn't found. * \param windowLength is the distance (in number of samples) used to compute the difference, the default value is 1. * \return The interpolated threshold value. */ StfioDll double threshold( const std::vector& data, std::size_t llp, std::size_t ulp, double slope, double& thrT, std::size_t windowLength ); //! Find 20 to 80% rise time of an event in \e data. /*! Although t80real is not explicitly returned, it can be calculated * from t20Real+risetime. * \param data The data waveform to be analysed. * \param base The baseline value. * \param ampl The amplitude of the event (typically, peak-base). * \param left Delimits the search to the left. * \param right Delimits the search to the right. * \param t20Id On exit, the index wich is closest to the 20%-point. * \param t80Id On exit, the index wich is closest to the 80%-point. * \param t20Real the linearly interpolated 20%-timepoint in * units of sampling points. * \return The rise time. */ StfioDll double risetime(const std::vector& data, double base, double ampl, double left, double right, double frac, std::size_t& tLoId, std::size_t& tHiId, double& tLoReal); //! Find 20 to 80% rise time of an event in \e data. /*! Although t80real is not explicitly returned, it can be calculated * from t20Real+risetime. * \param data The data waveform to be analysed. * \param base The baseline value. * \param ampl The amplitude of the event (typically, peak-base). * \param left Delimits the search to the left. * \param right Delimits the search to the right. * \param innerTLoReal interpolated starting point of the inner risetime * \param innerTHiReal interpolated end point of the inner risetime * \param outerTLoReal interpolated starting point of the outer risetime * \param outerTHiReal interpolated end point of the outer risetime the inner rise time is (innerTHiReal-innerTLoReal), the outer rise time is (outerTHiReal-outerTLoReal), in case of noise free data, inner and outer rise time are the same. * \return The inner rise time. */ StfioDll double risetime2(const std::vector& data, double base, double ampl, double left, double right, double frac, double& innerTLoReal, double& innerTHiReal, double& outerTLoReal, double& outerTHiReal ); //! Find the full width at half-maximal amplitude of an event within \e data. /*! Although t50RightReal is not explicitly returned, it can be calculated * from t50LeftReal+t_half. * \param data The data waveform to be analysed. * \param base The baseline value. * \param ampl The amplitude of the event (typically, peak-base). * \param left Delimits the search to the left. * \param right Delimits the search to the right. * \param center The estimated center of an event from which to start * searching to the left and to the right (typically, the index * of the peak). * \param t50LeftId On exit, the index wich is closest to the left 50%-point. * \param t50RightId On exit, the index wich is closest to the right 50%-point. * \param t50LeftReal the linearly interpolated left 50%-timepoint in * units of sampling points. * \return The full width at half-maximal amplitude. */ StfioDll double t_half( const std::vector& data, double base, double ampl, double left, double right, double center, std::size_t& t50LeftId, std::size_t& t50RightId, double& t50LeftReal ); //! Find the maximal slope during the rising phase of an event within \e data. /*! \param data The data waveform to be analysed. * \param left Delimits the search to the left. * \param right Delimits the search to the right. * \param maxRiseT The interpolated time point of the maximal slope of rise * in units of sampling points. * \param maxRiseY The interpolated value of \e data at \e maxRiseT. * \param windowLength is the distance (in number of samples) used to compute the slope, the default value is 1. * \return The maximal slope during the rising phase. */ StfioDll double maxRise( const std::vector& data, double left, double right, double& maxRiseT, double& maxRiseY, std::size_t windowLength); //! Find the maximal slope during the decaying phase of an event within \e data. /*! \param data The data waveform to be analysed. * \param left Delimits the search to the left. * \param right Delimits the search to the right. * \param maxDecayT The interpolated time point of the maximal slope of decay * in units of sampling points. * \param maxDecayY The interpolated value of \e data at \e maxDecayT. * \param windowLength is the distance (in number of samples) used to compute the slope, the default value is 1. * \return The maximal slope during the decaying phase. */ StfioDll double maxDecay( const std::vector& data, double left, double right, double& maxDecayT, double& maxDecayY, std::size_t windowLength); #ifdef WITH_PSLOPE //! Find the slope an event within \e data. /*! \param data The data waveform to be analysed. * \param left delimits the search to the left. * \param right delimits the search to the right. * \return The slope during the limits defined in left and right. */ double pslope( const std::vector& data, std::size_t left, std::size_t right); #endif /*@}*/ } #endif stimfit-0.16.7/src/libstfnum/stfnum.cpp0000775000175000017500000007316514752207205013604 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // core.cpp // Some definitions of functions declared in the stfnum:: namespace // last revision: 07-23-2006 // C. Schmidt-Hieber #include #include #include #include "stfnum.h" #include "fit.h" #include "funclib.h" int isnan(double x) { return x != x; } int isinf(double x) { return !isnan(x) && isnan(x - x); } stfnum::Table::Table(std::size_t nRows,std::size_t nCols) : values(nRows,std::vector(nCols,1.0)), empty(nRows,std::deque(nCols,false)), rowLabels(nRows, "\0"), colLabels(nCols, "\0") {} stfnum::Table::Table(const std::map< std::string, double >& map) : values(map.size(),std::vector(1,1.0)), empty(map.size(),std::deque(1,false)), rowLabels(map.size(), "\0"), colLabels(1, "Results") { std::map< std::string, double >::const_iterator cit; sst_it it1 = rowLabels.begin(); std::vector< std::vector >::iterator it2 = values.begin(); for (cit = map.begin(); cit != map.end() && it1 != rowLabels.end() && it2 != values.end(); cit++) { (*it1) = cit->first; it2->at(0) = cit->second; it1++; it2++; } } double stfnum::Table::at(std::size_t row,std::size_t col) const { try { return values.at(row).at(col); } catch (...) { throw; } } double& stfnum::Table::at(std::size_t row,std::size_t col) { try { return values.at(row).at(col); } catch (...) { throw; } } bool stfnum::Table::IsEmpty(std::size_t row,std::size_t col) const { try { return empty.at(row).at(col); } catch (...) { throw; } } void stfnum::Table::SetEmpty(std::size_t row,std::size_t col,bool value) { try { empty.at(row).at(col)=value; } catch (...) { throw; } } void stfnum::Table::SetRowLabel(std::size_t row,const std::string& label) { try { rowLabels.at(row)=label; } catch (...) { throw; } } void stfnum::Table::SetColLabel(std::size_t col,const std::string& label) { try { colLabels.at(col)=label; } catch (...) { throw; } } const std::string& stfnum::Table::GetRowLabel(std::size_t row) const { try { return rowLabels.at(row); } catch (...) { throw; } } const std::string& stfnum::Table::GetColLabel(std::size_t col) const { try { return colLabels.at(col); } catch (...) { throw; } } void stfnum::Table::AppendRows(std::size_t nRows_) { std::size_t oldRows=nRows(); rowLabels.resize(oldRows+nRows_); values.resize(oldRows+nRows_); empty.resize(oldRows+nRows_); for (std::size_t nRow = 0; nRow < oldRows + nRows_; ++nRow) { values[nRow].resize(nCols()); empty[nRow].resize(nCols()); } } double stfnum::fboltz(double x, const Vector_double& pars) { double arg=(pars[0]-x)/pars[1]; double ex=exp(arg); return 1/(1+ex); } double stfnum::fbessel(double x, int n) { double sum=0.0; for (int k=0;k<=n;++k) { int fac1=stfnum::fac(2*n-k); int fac2=stfnum::fac(n-k); int fac3=stfnum::fac(k); sum+=fac1/(fac2*fac3)*pow(x,k)/pow2(n-k); } return sum; } double stfnum::fbessel4(double x, const Vector_double& pars) { // normalize so that attenuation is -3dB at cutoff: return fbessel(0,4)/fbessel(x*0.355589/pars[0],4); } double stfnum::fgaussColqu(double x, const Vector_double& pars) { return exp(-0.3466*(x/pars[0])*(x/pars[0])); } int stfnum::fac(int arg) { if (arg<=1) { return 1; } else { return arg*fac(arg-1); } } Vector_double stfnum::filter( const Vector_double& data, std::size_t filter_start, std::size_t filter_end, const Vector_double &a, int SR, stfnum::Func func, bool inverse ) { if (data.size()<=0 || filter_start>=data.size() || filter_end > data.size()) { std::out_of_range e("subscript out of range in stfnum::filter()"); throw e; } std::size_t filter_size=filter_end-filter_start+1; Vector_double data_return(filter_size); double SI=1.0/SR; //the sampling interval double *in; //fftw_complex is a double[2]; hence, out is an array of //double[2] with out[n][0] being the real and out[n][1] being //the imaginary part. fftw_complex *out; fftw_plan p1, p2; //memory allocation as suggested by fftw: in =(double *)fftw_malloc(sizeof(double) * filter_size); out=(fftw_complex *)fftw_malloc(sizeof(fftw_complex) * ((int)(filter_size/2)+1)); // calculate the offset (a straight line between the first and last points): double offset_0=data[filter_start]; double offset_1=data[filter_end]-offset_0; double offset_step=offset_1 / (filter_size-1); //fill the input array with data removing the offset: for (std::size_t n_point=0;n_pointprogCounter) { progDlg.Update( (int)((double)n_data/(double)(data.size()-templ.size())*100.0), "Calculating detection criterion", &skipped ); if (skipped) { detection_criterion.resize(0); return detection_criterion; } progCounter++; } if (n_data!=0) { sum_templ_data=0.0; // The product has to be computed in full length: for (int n_templ=0; n_templ<(int)templ.size();++n_templ) { sum_templ_data+=templ[n_templ]*data[n_data+n_templ]; } // The new value that will be added is: double y_new=data[n_data+templ.size()-1]; double y2_new=data[n_data+templ.size()-1]*data[n_data+templ.size()-1]; sum_data+=y_new-y_old; sum_data_sqr+=y2_new-y2_old; } // The first value that was added (and will have to be subtracted during // the next loop): y_old=data[n_data+0]; y2_old=data[n_data+0]*data[n_data+0]; double scale=(sum_templ_data-sum_templ*sum_data/templ.size())/ (sum_templ_sqr-sum_templ*sum_templ/templ.size()); double offset=(sum_data-scale*sum_templ)/templ.size(); double sse=sum_data_sqr+scale*scale*sum_templ_sqr+templ.size()*offset*offset - 2.0*(scale*sum_templ_data + offset*sum_data-scale*offset*sum_templ); double standard_error=sqrt(sse/(templ.size()-1)); detection_criterion[n_data]=(scale/standard_error); } return detection_criterion; } std::vector stfnum::peakIndices(const Vector_double& data, double threshold, int minDistance) { // to avoid unnecessary copying, we first reserve quite // a bit of space for the vector: std::vector peakInd; peakInd.reserve(data.size()); for (unsigned n_data=0; n_datathreshold) { // ... and if so, find the data point where the threshold // is crossed again in the opposite direction, ... for (;;) { if (n_data>data.size()-2) { ulp=(int)data.size()-1; break; } n_data++; if (data[n_data]minDistance) { // ... making this the upper limit of the peak window: ulp=n_data; break; } } // Now, find the peak within the window: double max=-1e8; int peakIndex=llp; for (int n_p=llp; n_p<=ulp; ++n_p) { if (data[n_p]>max) { max=data[n_p]; peakIndex=n_p; } } peakInd.push_back(peakIndex); } } // Trim peakInd's reserved memory: std::vector(peakInd.begin(),peakInd.end()).swap(peakInd); return peakInd; } Vector_double stfnum::linCorr(const Vector_double& data, const Vector_double& templ, stfio::ProgressInfo& progDlg) { bool skipped = false; // the template has to be smaller than the data waveform: if (data.size()progCounter) { progDlg.Update( (int)((double)n_data/(double)(data.size()-templ.size())*100.0), "Calculating correlation coefficient", &skipped ); if (skipped) { Corr.resize(0); return Corr; } progCounter++; } if (n_data!=0) { sum_templ_data=0.0; // The product has to be computed in full length: for (int n_templ=0; n_templ<(int)templ.size();++n_templ) { sum_templ_data+=templ[n_templ]*data[n_data+n_templ]; } // The new value that will be added is: double y_new=data[n_data+templ.size()-1]; sum_data+=y_new-y_old; } // The first value that was added (and will have to be subtracted during // the next loop): y_old=data[n_data+0]; double scale=(sum_templ_data-sum_templ*sum_data/templ.size())/ (sum_templ_sqr-sum_templ*sum_templ/templ.size()); double offset=(sum_data-scale*sum_templ)/templ.size(); // Now that the optimal template has been found, // compute the correlation between data and optimal template. // The correlation coefficient is computed in a way that avoids // numerical instability; therefore, the sum of squares // computed above can't be re-used. // Get the means: double mean_data=sum_data/templ.size(); double sum_optTempl=sum_templ*scale+offset*templ.size(); double mean_optTempl=sum_optTempl/templ.size(); // Get SDs: double sd_data=0.0; double sd_templ=0.0; for (int i=0;i<(int)templ.size();++i) { sd_data+=SQR(data[i+n_data]-mean_data); sd_templ+=SQR(templ[i]*scale+offset-mean_optTempl); } sd_data=sqrt(sd_data/templ.size()); sd_templ=sqrt(sd_templ/templ.size()); // Get correlation: double r=0.0; for (int i=0;i<(int)templ.size();++i) { r+=(data[i+n_data]-mean_data)*(templ[i]*scale+offset-mean_optTempl); } r/=((templ.size()-1)*sd_data*sd_templ); Corr[n_data]=r; } return Corr; } double stfnum::integrate_simpson( const Vector_double& input, std::size_t i1, std::size_t i2, double x_scale ) { // Use composite Simpson's rule to approximate the definite integral of f from a to b // check for out-of-range: if (i2>=input.size() || i1>=i2) { throw std::out_of_range( "integration interval out of range in stfnum::integrate_simpson" ); } bool even = std::div((int)i2-(int)i1,2).rem==0; // use Simpson's rule for the even part: if (!even) i2--; std::size_t n=i2-i1; double a=i1*x_scale; double b=i2*x_scale; double sum_2=0.0, sum_4=0.0; for (std::size_t j = 1; j <= n/2; ++j) { if (j=input.size() || i1>=i2) { throw std::out_of_range( "integration interval out of range in stfnum::integrate_trapezium" ); } double a = i1 * x_scale; double b = i2 * x_scale; double sum=input[i1]+input[i2]; for (std::size_t n=i1+1; n= 0. * * N (input) INTEGER * The number of columns of the matrix A. N >= 0. * * A (input/output) DOUBLE PRECISION array, dimension (LDA,N) * On entry, the M-by-N matrix to be factored. * On exit, the factors L and U from the factorization * A = P*L*U; the unit diagonal elements of L are not stored. * * LDA (input) INTEGER * The leading dimension of the array A. LDA >= max(1,M). * * IPIV (output) INTEGER array, dimension (min(M,N)) * The pivot indices; for 1 <= i <= min(M,N), row i of the * matrix was interchanged with row IPIV(i). * * INFO (output) INTEGER * = 0: successful exit * < 0: if INFO = -i, the i-th argument had an illegal value * > 0: if INFO = i, U(i,i) is exactly zero. The factorization * has been completed, but the factor U is exactly * singular, and division by zero will occur if it is used * to solve a system of equations. */ int lda_f = m; std::size_t ipiv_size = (m < n) ? m : n; std::vector ipiv(ipiv_size); int info=0; dgetrf_(&m, &n, &A[0], &lda_f, &ipiv[0], &info); if (info<0) { std::ostringstream error_msg; error_msg << "Argument " << -info << " had an illegal value in LAPACK's dgetrf_"; throw std::runtime_error( std::string(error_msg.str())); } if (info>0) { throw std::runtime_error("Singular matrix in LAPACK's dgetrf_; would result in division by zero"); } /* Arguments to dgetrs_ * ==================== * * TRANS (input) CHARACTER*1 * Specifies the form of the system of equations: * = 'N': A * X = B (No transpose) * = 'T': A'* X = B (Transpose) * = 'C': A'* X = B (Conjugate transpose = Transpose) * * N (input) INTEGER * The order of the matrix A. N >= 0. * * NRHS (input) INTEGER * The number of right hand sides, i.e., the number of columns * of the matrix B. NRHS >= 0. * * A (input) DOUBLE PRECISION array, dimension (LDA,N) * The factors L and U from the factorization A = P*L*U * as computed by DGETRF. * * LDA (input) INTEGER * The leading dimension of the array A. LDA >= max(1,N). * * IPIV (input) INTEGER array, dimension (N) * The pivot indices from DGETRF; for 1<=i<=N, row i of the * matrix was interchanged with row IPIV(i). * * B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) * On entry, the right hand side matrix B. * On exit, the solution matrix X. * * LDB (input) INTEGER * The leading dimension of the array B. LDB >= max(1,N). * * INFO (output) INTEGER * = 0: successful exit * < 0: if INFO = -i, the i-th argument had an illegal value */ char trans='N'; dgetrs_(&trans, &m, &nrhs, &A[0], &m, &ipiv[0], &B[0], &m, &info); if (info<0) { std::ostringstream error_msg; error_msg << "Argument " << -info << " had an illegal value in LAPACK's dgetrs_"; throw std::runtime_error(error_msg.str()); } #endif return 0; } Vector_double stfnum::quad(const Vector_double& data, std::size_t begin, std::size_t end) { // Solve quadratic equations relating 3 sample points a time int n_intervals=std::div((int)end-(int)begin,2).quot; Vector_double quad_p(n_intervals*3); int n_q=0; if (begin-end>1) { for (int n=begin; n<(int)end-1; n+=2) { Vector_double A(9); Vector_double B(3); // solve linear equation system: // use column-major order (Fortran) A[0]=(double)n*(double)n; A[1]=((double)n+1.0)*((double)n+1.0); A[2]=((double)n+2.0)*((double)n+2.0); A[3]=(double)n; A[4]=(double)n+1.0; A[5]=(double)n+2.0; A[6]=1.0; A[7]=1.0; A[8]=1.0; B[0]=data[n]; B[1]=data[n+1]; B[2]=data[n+2]; try { stfnum::linsolv(3,3,1,A,B); } catch (...) { throw; } quad_p[n_q++]=B[0]; quad_p[n_q++]=B[1]; quad_p[n_q++]=B[2]; } } return quad_p; } Vector_double stfnum::nojac(double x, const Vector_double& p) { return Vector_double(0); } double stfnum::noscale(double param, double xscale, double oldx, double yscale, double yoff) { return param; } stfnum::Table stfnum::defaultOutput( const Vector_double& pars, const std::vector& parsInfo, double chisqr ) { if (pars.size()!=parsInfo.size()) { throw std::out_of_range("index out of range in stfnum::defaultOutput"); } stfnum::Table output(pars.size()+1,1); try { output.SetColLabel(0,"Best-fit value"); for (std::size_t n_p=0;n_p stfnum::histogram(const Vector_double& data, int nbins) { if (nbins==-1) { nbins = int(data.size()/100.0); } double fmax = *std::max_element(data.begin(), data.end()); double fmin = *std::min_element(data.begin(), data.end()); fmax += (fmax-fmin)*1e-9; double bin = (fmax-fmin)/nbins; std::map histo; for (int nbin=0; fmin + nbin*bin < fmax; ++nbin) { histo[fmin + nbin*bin] = 0; } for (std::size_t npoint=0; npoint < data.size(); ++npoint) { int nbin = int((data[npoint]-fmin) / bin); histo[fmin + nbin*bin]++; } return histo; } Vector_double stfnum::deconvolve(const Vector_double& dataIn, const Vector_double& templ, int SR, double hipass, double lopass, stfio::ProgressInfo& progDlg) { // Normalize data double fmax = *std::max_element(dataIn.begin(), dataIn.end()); double fmin = *std::min_element(dataIn.begin(), dataIn.end()); Vector_double data = stfio::vec_scal_minus(dataIn, fmin); data = stfio::vec_scal_div(data, fmax-fmin); bool skipped = false; progDlg.Update( 0, "Starting deconvolution...", &skipped ); if (data.size()<=0 || templ.size() <=0 || templ.size() > data.size()) { std::out_of_range e("subscript out of range in stfnum::filter()"); throw e; } /* pad templ */ double* in_templ_padded =(double *)fftw_malloc(sizeof(double) * data.size()); std::copy(templ.begin(), templ.end(), in_templ_padded); if (templ.size() < data.size()) { for (size_t kp=templ.size(); kp 0) { f_c[0] = hipass; rslt_hi = 1.0-fgaussColqu(f, f_c); } /* lowpass filter */ double rslt_lo = 1.0; if (lopass > 0) { f_c[0] = lopass; rslt_lo= fgaussColqu(f, f_c); } /* do the division in place */ double a = out_data[n_point][0]; double b = out_data[n_point][1]; double c = out_templ_padded[n_point][0]; double d = out_templ_padded[n_point][1]; double mag2 = c*c + d*d; out_data[n_point][0] = rslt_hi * rslt_lo * (a*c + b*d)/mag2; out_data[n_point][1] = rslt_hi * rslt_lo * (b*c - a*d)/mag2; } //do the reverse fft: p_inv = fftw_plan_dft_c2r_1d((int)data.size(),out_data, in_data, FFTW_ESTIMATE); fftw_execute(p_inv); //fill the return array, adding the offset, and scaling by data.size() //(because fftw computes an unnormalized transform): for (std::size_t n_point=0; n_point < data.size(); ++n_point) { data_return[n_point]= in_data[n_point]/data.size(); } fftw_destroy_plan(p_data); fftw_destroy_plan(p_templ); fftw_destroy_plan(p_inv); fftw_free(in_data); fftw_free(out_data); fftw_free(in_templ_padded); fftw_free(out_templ_padded); progDlg.Update( 50, "Computing data histogram...", &skipped ); if (skipped) { data_return.resize(0); return data_return; } int nbins = 500; //int(data_return.size()/500.0); std::map histo = histogram(data_return, nbins); double max_value = -1; double max_time = 0; double maxhalf_time = 0; Vector_double histo_fit(0); for (std::map::const_iterator it=histo.begin(); it != histo.end(); ++it) { if (it->second > max_value) { max_value = it->second; max_time = it->first; } histo_fit.push_back(it->second); #ifdef _STFDEBUG std::cout << it->first << "\t" << it->second << std::endl; #endif } for (std::map::const_iterator it=histo.begin(); it != histo.end(); ++it) { if (it->second > 0.5*max_value) { maxhalf_time = it->first; break; } } maxhalf_time = fabs(max_time-maxhalf_time); progDlg.Update( 75, "Fitting Gaussian...", &skipped ); if (skipped) { data_return.resize(0); return data_return; } /* Fit Gaussian to histogram */ double interval = (++histo.begin())->first-histo.begin()->first; if (maxhalf_time==0) { maxhalf_time = interval; } /* Initial parameter guesses */ Vector_double pars(3); pars[0] = max_value; pars[1] = (max_time - histo.begin()->first); pars[2] = maxhalf_time *sqrt(2.0)/2.35482; #ifdef _STFDEBUG std::cout << "nbins: " << nbins << std::endl; std::cout << "initial values:" << std::endl; for (std::size_t np=0; np funcLib = stfnum::GetFuncLib(); std::string info; int warning; #ifdef _STFDEBUG double chisqr = #endif lmFit(histo_fit, interval, funcLib[funcLib.size()-2], opts, true, pars, info, warning ); #ifdef _STFDEBUG std::cout << chisqr << "\t" << interval << std::endl; std::cout << "final values:" << std::endl; for (std::size_t np=0; npn+1, where \n * \e n is the number of exponential terms, \n * \e p[2i] is the amplitude term, \n * \e p[2i+1] is the time constant, \n * \e p[2n], the last element, contains the offset and \n * \e i denotes the i -th exponential term (running from 0 to n-1). * \return The evaluated function. */ double fexp(double x, const Vector_double& p); //! Computes the Jacobian of stfnum::fexp(). /*! \f{eqnarray*} * j_{2i}(x) &=& \frac{\partial f(x)}{\partial p_{2i}} = \mathrm{e}^{\left(\frac{-x}{p_{2i+1}}\right)} \\ * j_{2i+1}(x) &=& \frac{\partial f(x)}{\partial p_{2i+1}} = \frac{p_{2i}}{p_{2i+1}^2} x \mathrm{e}^{\left( \frac{-x}{p_{2i+1}}\right)} \\ * j_n(x) &=& \frac{\partial f(x)}{\partial p_{n}} = 1 * \f} * \param x Function argument. * \param p A valarray of parameters of size 2n+1, where \n * \e n is the number of exponential terms, \n * \e p[2i] is the amplitude term, \n * \e p[2i+1] is the time constant, \n * \e p[2n], the last element, contains the offset and \n * \e i denotes the i -th exponential term (running from 0 to n-1). * \return A valarray \e j of size 2n+1 with the evaluated Jacobian, where \n * \e j[2i] contains the derivative with respect to \e p[2i], \n * \e j[2i+1] contains the derivative with respect to \e p[2i+1] and \n * \e j[2n], the last element, contains the derivative with respect to \e p[2n]. */ Vector_double fexp_jac(double x, const Vector_double& p); //! Initialises parameters for fitting stfnum::fexp() to \e data. /*! This needs to be made more robust. * \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 2n+1, where \e n is the * number of exponential functions. On exit, will contain initial parameter * estimates. */ void fexp_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! Yet another initialiser for fitting stfnum::fexp() to \e data. /*! In this case, one of the amplitude terms will have another sign than the others, making * it more suitable for fitting PSCs or PSPs. However, this often fails to work in practice. * \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 2n+1, where \e n is the * number of exponential functions. On exit, will contain initial parameter * estimates. */ void fexp_init2(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! Monoexponential function with delay. /*! \f{eqnarray*} * f(x)= * \begin{cases} * p_0, & \mbox{if }x < p_3 \\ * \left( p_0 - p_2 \right) \mathrm{e}^{\left (\frac{p_3 - x}{p_1}\right )} + p_2, & \mbox{if }x \geq p_3 * \end{cases} * \f} * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the baseline, \n * \e p[1] is the time constant, \n * \e p[2] is the amplitude and \n * \e p[3] is the delay. * \return The evaluated function. */ double fexpde(double x, const Vector_double& p); #if 0 //! Computes the Jacobian of stfnum::fexpde(). /*! \f{eqnarray*} * j_0(x)&=& \frac{df(x)}{dp_0} = * \begin{cases} * 1, & \mbox{if }x < p_3 \\ * \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} \\ * j_1(x)&=& \frac{df(x)}{dp_1} = * \begin{cases} * 0, & \mbox{if }x < p_3 \\ * \left( p_0-p_2 \right) \left( p_3-x \right) \frac{-1}{p_1^2} \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} \\ * j_2(x)&=& \frac{df(x)}{dp_2} = * \begin{cases} * 0, & \mbox{if }x < p_3 \\ * 1 - \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} \\ * j_3(x)&=& \frac{df(x)}{dp_3} = * \begin{cases} * 0, & \mbox{if }x < p_3 \\ * \left( p_0-p_2 \right) \frac{1}{p_1} \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} * \f} * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the baseline, \n * \e p[1] is the time constant, \n * \e p[2] is the amplitude and \n * \e p[3] is the delay. * \return A valarray \e j with the evaluated Jacobian, where \n * \e j[0] contains the derivative with respect to \e p[0], \n * \e j[1] contains the derivative with respect to \e p[1], \n * \e j[2] contains the derivative with respect to \e p[2] and \n * \e j[3] contains the derivative with respect to \e p[3]. */ Vector_double fexpde_jac(double x, const Vector_double& p); #endif //! Initialises parameters for fitting stfnum::fexpde() to \e data. /*! \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 4. * On exit, will contain initial parameter estimates. */ void fexpde_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! Biexponential function with delay. /*! \f{eqnarray*} * f(x)= * \begin{cases} * p_0 & \mbox{if }x < p_1 \\ * p_3 \left( \mathrm{e}^{\frac{p_1 - x}{p_2}} - \mathrm{e}^{\frac{p_1 - x}{p_4}} \right) + p_0 & \mbox{if }x \geq p_1 * \end{cases} * \f} * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the baseline, \n * \e p[1] is the delay, \n * \e p[2] is the later (slower) time constant, \n * \e p[3] is the amplitude and \n * \e p[4] is the earlier (faster) time constant, \n * \return The evaluated function. */ double fexpbde(double x, const Vector_double& p); //! Triexponential function with delay. /*! \f{eqnarray*} * f(x)= * \begin{cases} * p_0 & \mbox{if }x < p_1 \\ * p_3 \left( p_6\mathrm{e}^{\frac{p_1 - x}{p_2}} + (1-p_6)\mathrm{e}^{\frac{p_1 - x}{p_5}} - \mathrm{e}^{\frac{p_1 - x}{p_4}} \right) + p_0 & \mbox{if }x \geq p_1 * \end{cases} * \f} * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the baseline, \n * \e p[1] is the delay, \n * \e p[2] is the first later (slower) time constant, \n * \e p[3] is the amplitude and \n * \e p[4] is the earlier (faster) time constant, \n * \e p[5] is the second later (slower) time constant, \n * \e p[6] is the relative weight of p[2], \n * \return The evaluated function. */ double fexptde(double x, const Vector_double& p); #if 0 //! Computes the Jacobian of stfnum::fexpde(). /*! \f{eqnarray*} * j_0(x)&=& \frac{df(x)}{dp_0} = * \begin{cases} * 1, & \mbox{if }x < p_3 \\ * \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} \\ * j_1(x)&=& \frac{df(x)}{dp_1} = * \begin{cases} * 0, & \mbox{if }x < p_3 \\ * \left( p_0-p_2 \right) \left( p_3-x \right) \frac{-1}{p_1^2} \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} \\ * j_2(x)&=& \frac{df(x)}{dp_2} = * \begin{cases} * 0, & \mbox{if }x < p_3 \\ * 1 - \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} \\ * j_3(x)&=& \frac{df(x)}{dp_3} = * \begin{cases} * 0, & \mbox{if }x < p_3 \\ * \left( p_0-p_2 \right) \frac{1}{p_1} \mathrm{e}^{\frac{p_3 - x}{p_1}}, & \mbox{if }x \geq p_3 * \end{cases} * \f} * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the baseline, \n * \e p[1] is the time constant, \n * \e p[2] is the amplitude and \n * \e p[3] is the delay. * \return A valarray \e j with the evaluated Jacobian, where \n * \e j[0] contains the derivative with respect to \e p[0], \n * \e j[1] contains the derivative with respect to \e p[1], \n * \e j[2] contains the derivative with respect to \e p[2] and \n * \e j[3] contains the derivative with respect to \e p[3]. */ Vector_double fexpbde_jac(double x, const Vector_double& p); #endif //! Initialises parameters for fitting stfnum::fexpde() to \e data. /*! \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 4. * On exit, will contain initial parameter estimates. */ void fexpbde_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! Initialises parameters for fitting stfnum::fexpde() to \e data. /*! \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 4. * On exit, will contain initial parameter estimates. */ void fexptde_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! Alpha function. /*! \f[f(x)=p_0 \frac{x}{p_1} \mathrm{e}^{\left(1 - \frac{x}{p_1} \right)} + p_2\f] * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the amplitude, \n * \e p[1] is the rate and \n * \e p[2] is the offset. * \return The evaluated function. */ double falpha(double x, const Vector_double& p); //! Computes the Jacobian of stfnum::falpha(). /*! \f{eqnarray*} * j_0(x) &=& \frac{\partial f(x)}{\partial p_0} = \frac{x \mathrm{e}^{\left(1 - \frac{x}{p_1} \right)}}{p_1} \\ * j_1(x) &=& \frac{\partial f(x)}{\partial p_1} = \frac{x \mathrm{e}^{\left(1 - \frac{x}{p_1} \right)}}{p_1} \left(\frac{p_0 x}{p_1^2} - \frac{p_0}{p_1} \right) \\ * j_2(x) &=& \frac{\partial f(x)}{\partial p_2} = 1 * \f} * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the amplitude, \n * \e p[1] is the rate and \n * \e p[2] is the offset. * \return A valarray \e j with the evaluated Jacobian, where \n * \e j[0] contains the derivative with respect to \e p[0], \n * \e j[1] contains the derivative with respect to \e p[1] and \n * \e j[2] contains the derivative with respect to \e p[2]. */ Vector_double falpha_jac(double x, const Vector_double& p); //! Hodgkin-Huxley sodium conductance function. /*! \f[f(x)=p_0\left(1-\mathrm{e}^{\frac{-x}{p_1}}\right)^3\mathrm{e}^{\frac{-x}{p_2}} + p_3\f] * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the amplitude \f$g'_{Na}\f$, \n * \e p[1] is \f$\tau_m\f$, \n * \e p[2] is \f$\tau_h\f$ and \n * \e p[3] is the offset. \n * \return The evaluated function. */ double fHH(double x, const Vector_double& p); //! Computes the sum of an arbitrary number of Gaussians. /*! \f[ * f(x) = \sum_{i=0}^{n-1}p_{3i}\mathrm{e}^{- \left( \frac{x-p_{3i+1}}{p_{3i+2}} \right) ^2} * \f] * \param x Argument of the function. * \param p A valarray of function parameters of size 3\e n, where \n * \e p[3i] is the amplitude of the Gaussian \n * \e p[3i+1] is the position of the center of the peak, \n * \e p[3i+2] is the width of the Gaussian, \n * \e n is the number of Gaussian functions and \n * \e i is the 0-based index of the i-th Gaussian. * \return The evaluated function. */ StfioDll double fgauss(double x, const Vector_double& p); //! Computes the Jacobian of a sum of Gaussians. Vector_double fgauss_jac(double x, const Vector_double& p); //! power of 1 sodium conductance function. /*! \f[f(x)=p_0\left(1-\mathrm{e}^{\frac{-x}{p_1}}\right)\mathrm{e}^{\frac{-x}{p_2}} + p_3\f] * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the amplitude \f$g'_{Na}\f$, \n * \e p[1] is \f$\tau_m\f$, \n * \e p[2] is \f$\tau_h\f$ and \n * \e p[3] is the offset. \n * \return The evaluated function. */ double fgnabiexp(double x, const Vector_double& p); //! Computes the Jacobian of stfnum::fgnabiexp(). /*! \f{eqnarray*} * j_0(x) &=& \frac{\partial f(x)}{\partial p_0} = \left(1 -\mathrm{e}^{\frac{-x}{p_1}}\right) \mathrm{e}^{\frac{-x}{p_2}} \\ * j_1(x) &=& \frac{\partial f(x)}{\partial p_1} = p_0 \frac{ -x \mathrm{e}^{\left(-\frac{x}{p_1} - \frac{x}{p_2} \right)}}{p_1^2} \\ * j_2(x) &=& \frac{\partial f(x)}{\partial p_2} = p_0 \frac{ x \left(1 -\mathrm{e}^{\frac{-x}{p_1}}\right) \mathrm{e}^{\frac{-x}{p_2}}} {p_2^2}\\ * j_3(x) &=& \frac{\partial f(x)}{\partial p_3} = 1 * \f} * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the amplitude \f$g'_{Na}\f$, \n * \e p[1] is \f$\tau_m\f$, \n * \e p[2] is \f$\tau_h\f$ and \n * \e p[3] is the offset. \n * \return A valarray \e j with the evaluated Jacobian, where \n * \e j[0] contains the derivative with respect to \e p[0], \n * \e j[1] contains the derivative with respect to \e p[1], \n * \e j[2] contains the derivative with respect to \e p[2] and \n * \e j[3] contains the derivative with respect to \e p[3]. */ Vector_double fgnabiexp_jac(double x, const Vector_double& p); //! Initialises parameters for fitting stfnum::falpha() to \e data. /*! \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 3. On exit, will contain initial parameter * estimates. */ void falpha_init(const Vector_double& data, double base, double peak, double RTLoHI, double HalfWidth, double dt, Vector_double& pInit ); //! Initialises parameters for fitting stfnum::fgauss() to \e data. /*! \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 3. On exit, will contain initial parameter * estimates. */ void fgauss_init(const Vector_double& data, double base, double peak, double RTLoHI, double HalfWidth, double dt, Vector_double& pInit ); //! Initialises parameters for fitting stfnum::falpha() to \e data. /*! \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 4. On exit, will contain initial parameter * estimates. */ void fHH_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! Initialises parameters for fitting stfnum::falpha() to \e data. /*! \param data The waveform of the data for the fit. * \param base Baseline of \e data. * \param peak Peak value of \e data. * \param dt The sampling interval. * \param pInit On entry, pass a valarray of size 4. On exit, will contain initial parameter * estimates. */ void fgnabiexp_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! Scales a parameter that linearly depends on x /*! \param The parameter to scale * \param xscale x scaling factor * \param xoff x offset * \param yscale y scaling factor * \param yoff y offset * \return Scaled parameter */ double xscale(double param, double xscale, double xoff, double yscale, double yoff); //! Unscales a parameter that linearly depends on x /*! \param The parameter to scale * \param xscale x scaling factor * \param xoff x offset * \param yscale y scaling factor * \param yoff y offset * \return Unscaled parameter */ double xunscale(double param, double xscale, double xoff, double yscale, double yoff); //! Scales a parameter that linearly depends on y /*! \param The parameter to scale * \param xscale x scaling factor * \param xoff x offset * \param yscale y scaling factor * \param yoff y offset */ double yscale(double param, double xscale, double xoff, double yscale, double yoff); //! Scales a parameter that linearly depends on y and adds an offset /*! \param The parameter to scale * \param xscale x scaling factor * \param xoff x offset * \param yscale y scaling factor * \param yoff y offset */ double yscaleoffset(double param, double xscale, double xoff, double yscale, double yoff); //! Unscales a parameter that linearly depends on y /*! \param The parameter to scale * \param xscale x scaling factor * \param xoff x offset * \param yscale y scaling factor * \param yoff y offset * \return Unscaled parameter */ double yunscale(double param, double xscale, double xoff, double yscale, double yoff); //! Unscales a parameter that linearly depends on y and removes the offset /*! \param The parameter to scale * \param xscale x scaling factor * \param xoff x offset * \param yscale y scaling factor * \param yoff y offset * \return Unscaled parameter */ double yunscaleoffset(double param, double xscale, double xoff, double yscale, double yoff); //! Creates stfnum::parInfo structs for n-exponential functions. /*! \param n_exp Number of exponential terms. * \return A vector of parameter information structs. */ std::vector getParInfoExp(int n_exp); //! Calculates a weighted time constant. /*! \param p Parameters of an exponential function (see stfnum::fexp()). * \param parsInfo Information about the parameters \e p. * \param chisqr The sum of squared errors, as returned from a least-squares fit. * \return A formatted table of results. */ stfnum::Table outputWTau(const Vector_double& p, const std::vector& parsInfo, double chisqr); //! Finds the index of \e data where \e value is encountered for the first time. /*! \param data The waveform to be searched. * \param value The value to be found. * \return The index of \e data right after \e value has been crossed. */ std::size_t whereis(const Vector_double& data, double value); //! Returns the library of functions for non-linear regression. /*! \return A vector of non-linear regression functions. */ StfioDll std::vector GetFuncLib(); /*@}*/ } #endif stimfit-0.16.7/src/libstfnum/fit.cpp0000775000175000017500000004016614750344764013057 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "./fit.h" #include "./levmar/levmar.h" #include #include namespace stfnum { // C-style functions for Lourakis' routines: void c_func_lour(double *p, double* hx, int m, int n, void *adata); void c_jac_lour(double *p, double *j, int m, int n, void *adata); // Helper functions for lmFit to store the function at global scope: void saveFunc(stfnum::Func func); void saveJac(stfnum::Jac jac); // A struct that will be passed as a pointer to // Lourakis' C-functions. It is used to: // (1) specify which parameters are to be fitted, and // (2) pass the constant parameters // (3) the sampling interval struct fitInfo { fitInfo(const std::deque& fit_p_arg, const Vector_double& const_p_arg, double dt_arg) : fit_p(fit_p_arg), const_p(const_p_arg), dt(dt_arg) {} // Specifies for each parameter whether the client // wants to fit it (true) or to keep it constant (false) std::deque fit_p; // A valarray containing the parameters that // will be kept constant: Vector_double const_p; // sampling interval double dt; }; } // Functions stored at global scope to be called by c_func_lour // and c_jac_lour stfnum::Func func_lour; stfnum::Jac jac_lour; void stfnum::saveFunc(stfnum::Func func) { func_lour=func; } void stfnum::saveJac(stfnum::Jac jac) { jac_lour=jac; } void stfnum::c_func_lour(double *p, double* hx, int m, int n, void *adata) { // m: the number of parameters that are to be fitted // adata: pointer to a struct that (1) specifies which parameters are to be fitted // and (2) contains the constant parameters fitInfo *fInfo=static_cast(adata); // total number of parameters, including constants: int tot_p=(int)fInfo->fit_p.size(); // all parameters, including constants: Vector_double p_f(tot_p); for (int n_tp=0, n_p=0, n_f=0;n_tpfit_p[n_tp]) { // ... take it from *p, ... p_f[n_tp] = p[n_p++]; } else { // ... otherwise, take it from the fInfo struct: p_f[n_tp] = fInfo->const_p[n_f++]; } } for (int n_x=0;n_xdt, p_f); } } void stfnum::c_jac_lour(double *p, double *jac, int m, int n, void *adata) { // m: the number of parameters that are to be fitted // adata: pointer to a struct that (1) specifies which parameters are to be fitted // and (2) contains the constant parameters fitInfo *fInfo=static_cast(adata); // total number of parameters, including constants: int tot_p=(int)fInfo->fit_p.size(); // all parameters, including constants: Vector_double p_f(tot_p); for (int n_tp=0,n_p=0,n_f=0;n_tpfit_p[n_tp]) { // ... take it from *p, ... p_f[n_tp] = p[n_p++]; } else { // ... otherwise, take it from the fInfo struct: p_f[n_tp] = fInfo->const_p[n_f++]; } } for (int n_x=0,n_j=0;n_xdt,p_f)); // ... but we only need the derivatives of the non-constants... for (int n_tp=0;n_tpfit_p[n_tp]) { jac[n_j++]=jac_f[n_tp]; } } } } Vector_double stfnum::get_scale(Vector_double& data, double oldx) { Vector_double xyscale(4); if (data.size() == 0) { xyscale[0] = 1.0/oldx; xyscale[1] = 0.0; xyscale[2] = 1.0; xyscale[3] = 0.0; return xyscale; } double ymin,ymax,amp,off; ymin = *data.begin(); ymax = ymin; for (Vector_double::iterator it = data.begin(); it != data.end(); ++it) { double v = *it; if (v < ymin) ymin = v; else if (ymax < v) ymax = v; } amp = ymax - ymin; off = ymin / amp; data = stfio::vec_scal_mul(data, 1.0 / amp); data = stfio::vec_scal_minus(data, off); xyscale[0] = 1.0/(data.size()*oldx); xyscale[1] = 0; xyscale[2] = 1.0/amp; xyscale[3] = off; return xyscale; } double stfnum::lmFit( const Vector_double& data, double dt, const stfnum::storedFunc& fitFunc, const Vector_double& opts, bool use_scaling, Vector_double& p, std::string& info, int& warning ) { // Basic range checking: if (fitFunc.pInfo.size()!=p.size()) { std::string msg("Error in stfnum::lmFit()\n" "function parameters (p_fit) and parameters entered (p) have different sizes"); throw std::runtime_error(msg); } if ( opts.size() != 6 ) { std::string msg("Error in stfnum::lmFit()\n" "wrong number of options"); throw std::runtime_error(msg); } bool constrained = false; std::vector< double > constrains_lm_lb( fitFunc.pInfo.size() ); std::vector< double > constrains_lm_ub( fitFunc.pInfo.size() ); bool can_scale = use_scaling; for ( unsigned n_p=0; n_p < fitFunc.pInfo.size(); ++n_p ) { if ( fitFunc.pInfo[n_p].constrained ) { constrained = true; constrains_lm_lb[n_p] = fitFunc.pInfo[n_p].constr_lb; constrains_lm_ub[n_p] = fitFunc.pInfo[n_p].constr_ub; } else { constrains_lm_lb[n_p] = -DBL_MAX; constrains_lm_ub[n_p] = DBL_MAX; } if ( can_scale ) { if (!fitFunc.pInfo[n_p].scale) { can_scale = false; } } } // Store the functions at global scope: saveFunc(fitFunc.func); saveJac(fitFunc.jac); double info_id[LM_INFO_SZ]; Vector_double data_ptr(data); Vector_double xyscale(4); if (can_scale) { xyscale = get_scale(data_ptr, dt); } // The parameters need to be separated into two parts: // Those that are to be fitted and those that the client wants // to keep constant. Since there is no native support to // do so in Lourakis' routines, the workaround is a little // tricky, making (ab)use of the *void pointer: // number of parameters that need to be fitted: int n_fitted=0; for ( unsigned n_p=0; n_p < fitFunc.pInfo.size(); ++n_p ) { n_fitted += fitFunc.pInfo[n_p].toFit; } // parameters that need to be fitted: Vector_double p_toFit(n_fitted); std::deque p_fit_bool( fitFunc.pInfo.size() ); // parameters that are held constant: Vector_double p_const( fitFunc.pInfo.size()-n_fitted ); for ( unsigned n_p=0, n_c=0, n_f=0; n_p < fitFunc.pInfo.size(); ++n_p ) { if (fitFunc.pInfo[n_p].toFit) { p_toFit[n_f++] = p[n_p]; if (can_scale) { p_toFit[n_f-1] = fitFunc.pInfo[n_p].scale(p_toFit[n_f-1], xyscale[0], xyscale[1], xyscale[2], xyscale[3]); } } else { p_const[n_c++] = p[n_p]; if (can_scale) { p_const[n_c-1] = fitFunc.pInfo[n_p].scale(p_const[n_c-1], xyscale[0], xyscale[1], xyscale[2], xyscale[3]); } } p_fit_bool[n_p] = fitFunc.pInfo[n_p].toFit; } // size * dt_new = 1 -> dt_new = 1.0/size double dt_finfo = dt; if (can_scale) dt_finfo = 1.0/data_ptr.size(); fitInfo fInfo( p_fit_bool, p_const, dt_finfo ); // make l-value of opts: Vector_double opts_l(5); for (std::size_t n=0; n < 4; ++n) opts_l[n] = opts[n]; opts_l[4] = -1e-6; int it = 0; if (p_toFit.size()!=0 && data_ptr.size()!=0) { double old_info_id[LM_INFO_SZ]; // initialize with initial parameter guess: Vector_double old_p_toFit(p_toFit); #ifdef _DEBUG std::ostringstream optsMsg; optsMsg << "\nopts: "; for (std::size_t n_p=0; n_p < opts.size(); ++n_p) optsMsg << opts[n_p] << "\t"; optsMsg << "\n" << "data_ptr[" << data_ptr.size()-1 << "]=" << data_ptr[data_ptr.size()-1] << "\n"; optsMsg << "constrains_lm_lb: "; for (std::size_t n_p=0; n_p < constrains_lm_lb.size(); ++n_p) optsMsg << constrains_lm_lb[n_p] << "\t"; optsMsg << "\n" << "constrains_lm_ub: "; for (std::size_t n_p=0; n_p < constrains_lm_ub.size(); ++n_p) optsMsg << constrains_lm_ub[n_p] << "\t"; optsMsg << "\n\n"; std::cout << optsMsg; #endif while ( 1 ) { #ifdef _DEBUG std::ostringstream paramMsg; paramMsg << "Pass: " << it << "\t"; paramMsg << "p_toFit: "; for (std::size_t n_p=0; n_p < p_toFit.size(); ++n_p) paramMsg << p_toFit[n_p] << "\t"; paramMsg << "\n"; std::cout << paramMsg.str().c_str(); #endif if ( !fitFunc.hasJac ) { if ( !constrained ) { dlevmar_dif( c_func_lour, &p_toFit[0], &data_ptr[0], n_fitted, (int)data.size(), (int)opts[4], &opts_l[0], info_id, NULL, NULL, &fInfo ); } else { dlevmar_bc_dif( c_func_lour, &p_toFit[0], &data_ptr[0], n_fitted, (int)data.size(), &constrains_lm_lb[0], &constrains_lm_ub[0], NULL, (int)opts[4], &opts_l[0], info_id, NULL, NULL, &fInfo ); } } else { if ( !constrained ) { dlevmar_der( c_func_lour, c_jac_lour, &p_toFit[0], &data_ptr[0], n_fitted, (int)data.size(), (int)opts[4], &opts_l[0], info_id, NULL, NULL, &fInfo ); } else { dlevmar_bc_der( c_func_lour, c_jac_lour, &p_toFit[0], &data_ptr[0], n_fitted, (int)data.size(), &constrains_lm_lb[0], &constrains_lm_ub[0], NULL, (int)opts[4], &opts_l[0], info_id, NULL, NULL, &fInfo ); } } it++; if ( info_id[1] != info_id[1] ) { // restore previous parameters if new chisqr is NaN: p_toFit = old_p_toFit; } else { double dchisqr = (info_id[0] - info_id[1]) / info_id[1]; // (old chisqr - new chisqr) / new_chisqr if ( dchisqr < 0 ) { // restore previous results and exit if new chisqr is larger: for ( int n_i = 0; n_i < LM_INFO_SZ; ++n_i ) info_id[n_i] = old_info_id[n_i]; p_toFit = old_p_toFit; break; } if ( dchisqr < 1e-5 ) { // Keep current results and exit if change in chisqr is below threshold break; } // otherwise, store results and continue iterating: for ( int n_i = 0; n_i < LM_INFO_SZ; ++n_i ) old_info_id[n_i] = info_id[n_i]; old_p_toFit = p_toFit; } if ( it >= opts[5] ) // Exit if maximal number of iterations is reached break; // decrease initial step size for next iteration: opts_l[0] *= 1e-4; } } else { std::runtime_error e("Array of size zero in lmFit"); throw e; } // copy back the fitted parameters to p: for ( unsigned n_p=0, n_f=0, n_c=0; n_p linParInfo(2); linParInfo[0] = stfnum::parInfo("Slope", true); linParInfo[1] = stfnum::parInfo("Y intersect", true); return stfnum::storedFunc("Linear function", linParInfo, stfnum::flin, stfnum::flin_init, stfnum::nojac, false, stfnum::defaultOutput); } /* options for the implementation of the LM algorithm */ Vector_double stfnum::LM_default_opts() { Vector_double opts(6); //opts[0]=5*1E-3; // initial \mu, default: 1E-03; opts[0]=1E-3; // initial \mu, default: 1E-03; opts[1]=1E-17; // stopping thr for ||J^T e||_inf, default: 1E-17; opts[2]=1E-17; // stopping trh for ||Dp||_2, default: 1E-17; opts[3]=1E-32; // stopping thr for ||e||_2, default: 1E-17; opts[4]=64; // maximal number of iterations/pass, default: 64; opts[5]=16; // maximal number of passes; return opts; } stimfit-0.16.7/src/libstfnum/Makefile.am0000664000175000017500000000124314750344764013613 if BUILD_MODULE if ISDARWIN PYTHON_TARGET_DIR=${PYTHON_DIST_PKG} else PYTHON_TARGET_DIR=${PYTHON_PRE_DIST_PKG} # PYTHON_TARGET_DIR=${PYTHON_DIST_PKG} endif PYTHON_DEST_DIR=${DESTDIR}${PYTHON_TARGET_DIR} pkglibdir = ${PYTHON_TARGET_DIR}/stfio endif pkglib_LTLIBRARIES = libstfnum.la libstfnum_la_SOURCES = ./fit.cpp \ ./levmar/lm.c ./levmar/Axb.c ./levmar/misc.c ./levmar/lmlec.c ./levmar/lmbc.c \ ./funclib.cpp ./stfnum.cpp ./measure.cpp libstfnum_la_LDFLAGS = $(LIBLAPACK_LDFLAGS) libstfnum_la_LIBADD = $(LIBSTF_LDFLAGS) -lfftw3 if ISDARWIN # don't install anything because it has to go into the app bundle if !BUILD_MODULE install: endif endif stimfit-0.16.7/src/libstfnum/fit.h0000775000175000017500000001054514750344764012522 // Header file for the stimfit namespace // Routines for fitting functions to data // last revision: 08-08-2006 // C. Schmidt-Hieber, christsc@gmx.de // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file fit.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Functions for linear and non-linear regression. */ #ifndef _FITLIB_H #define _FITLIB_H #include "./stfnum.h" #include namespace stfnum { /*! \addtogroup stfgen * @{ */ //! Performs a linear fit. /*! \param x The x- values of the data that are to be fitted. * \param y The y- values of the data that are to be fitted. * \param m On exit, the slope of the regression line. * \param c On exit, the y-intercept of the regression line. * \return A valarray containing the waveform of the fitted function. */ template T linFit( const std::vector& x, const std::vector& y, T& m, T& c ); //! Uses the Levenberg-Marquardt algorithm to perform a non-linear least-squares fit. /*! \param data A valarray containing the data. * \param dt The sampling interval of \e data. * \param fitFunc An stfnum::storedFunc to be fitted to \e data. * \param opts Options controlling Lourakis' implementation of the algorithm. * \param use_scaling Whether to scale x and y-amplitudes to 1.0 * \param p \e func's parameters. Should be set to an initial guess * on entry. Will contain the best-fit values on exit. * \param info Information about why the fit stopped iterating * \param warning A warning code on return. * \return The sum of squred errors between \e data and the best-fit function. */ double StfioDll lmFit(const Vector_double& data, double dt, const stfnum::storedFunc& fitFunc, const Vector_double& opts, bool use_scaling, Vector_double& p, std::string& info, int& warning ); //! Linear function. /*! \f[f(x)=p_0 x + p_1\f] * \param x Function argument. * \param p A valarray of parameters, where \n * \e p[0] is the slope and \n * \e p[1] is the y intersection. * \return The evaluated function. */ double flin(double x, const Vector_double& p); //! Dummy function to be passed to stfnum::storedFunc for linear functions. void flin_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ); //! initializes a linear function /*! \return An stfnum::storedFunc that can be used to store a linear function after a fit */ StfioDll stfnum::storedFunc initLinFunc(); //! Compute and perform normalisation /*! \param data Data vector; will be scaled upon return * \param oldx original x interval * \return A vector with \n * [0] x scale * [1] x offset * [2] y scale * [3] y offset */ Vector_double get_scale(Vector_double& data, double oldx); //! Return default LM options /*! \return Default LM options */ Vector_double LM_default_opts(); } template T stfnum::linFit(const std::vector& x, const std::vector& y, T& m, T& c) { double sum_x=0.0; double sum_y=0.0; double sum_xx=0.0; double sum_xy=0.0; for (unsigned n=0;n&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@ subdir = src/libstfnum ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acsite.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/stfconf.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)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = libstfnum_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libstfnum_la_OBJECTS = fit.lo lm.lo Axb.lo misc.lo lmlec.lo lmbc.lo \ funclib.lo stfnum.lo measure.lo libstfnum_la_OBJECTS = $(am_libstfnum_la_OBJECTS) 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 = libstfnum_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libstfnum_la_LDFLAGS) $(LDFLAGS) -o $@ 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@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/Axb.Plo ./$(DEPDIR)/fit.Plo \ ./$(DEPDIR)/funclib.Plo ./$(DEPDIR)/lm.Plo \ ./$(DEPDIR)/lmbc.Plo ./$(DEPDIR)/lmlec.Plo \ ./$(DEPDIR)/measure.Plo ./$(DEPDIR)/misc.Plo \ ./$(DEPDIR)/stfnum.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 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 = $(libstfnum_la_SOURCES) DIST_SOURCES = $(libstfnum_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) # 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)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @BUILD_MODULE_TRUE@pkglibdir = ${PYTHON_TARGET_DIR}/stfio ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ GT_CPPFLAGS = @GT_CPPFLAGS@ GT_CXXFLAGS = @GT_CXXFLAGS@ GT_LDFLAGS = @GT_LDFLAGS@ GT_LIBS = @GT_LIBS@ HDF5_CFLAGS = @HDF5_CFLAGS@ HDF5_LIBS = @HDF5_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBIOSIG_LDFLAGS = @LIBBIOSIG_LDFLAGS@ LIBHDF5_LDFLAGS = @LIBHDF5_LDFLAGS@ LIBLAPACK_LDFLAGS = @LIBLAPACK_LDFLAGS@ LIBNUMPY_INCLUDES = @LIBNUMPY_INCLUDES@ LIBOBJS = @LIBOBJS@ LIBPYTHON_INCLUDES = @LIBPYTHON_INCLUDES@ LIBPYTHON_LDFLAGS = @LIBPYTHON_LDFLAGS@ LIBS = @LIBS@ LIBSTF_LDFLAGS = @LIBSTF_LDFLAGS@ LIBTOOL = @LIBTOOL@ LIBWXPYTHON_INCLUDES = @LIBWXPYTHON_INCLUDES@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MACSETFILE = @MACSETFILE@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ 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@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSTLINK_COMMAND = @POSTLINK_COMMAND@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIST_PKG = @PYTHON_DIST_PKG@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ PYTHON_NUMPY_INCLUDE = @PYTHON_NUMPY_INCLUDE@ PYTHON_PRE_DIST_PKG = @PYTHON_PRE_DIST_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ PYTHON_WXPYTHON_INCLUDE = @PYTHON_WXPYTHON_INCLUDE@ PY_AC_VERSION = @PY_AC_VERSION@ RANLIB = @RANLIB@ REZ = @REZ@ SED = @SED@ SETFILE = @SETFILE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STFIO_PYTHON_LIBNAME = @STFIO_PYTHON_LIBNAME@ STF_PYTHON_LIBNAME = @STF_PYTHON_LIBNAME@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ VERSION = @VERSION@ WX_CPPFLAGS = @WX_CPPFLAGS@ WX_CXXFLAGS = @WX_CXXFLAGS@ WX_LIBS = @WX_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ 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@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ 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@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @BUILD_MODULE_TRUE@@ISDARWIN_FALSE@PYTHON_TARGET_DIR = ${PYTHON_PRE_DIST_PKG} @BUILD_MODULE_TRUE@@ISDARWIN_TRUE@PYTHON_TARGET_DIR = ${PYTHON_DIST_PKG} # PYTHON_TARGET_DIR=${PYTHON_DIST_PKG} @BUILD_MODULE_TRUE@PYTHON_DEST_DIR = ${DESTDIR}${PYTHON_TARGET_DIR} pkglib_LTLIBRARIES = libstfnum.la libstfnum_la_SOURCES = ./fit.cpp \ ./levmar/lm.c ./levmar/Axb.c ./levmar/misc.c ./levmar/lmlec.c ./levmar/lmbc.c \ ./funclib.cpp ./stfnum.cpp ./measure.cpp libstfnum_la_LDFLAGS = $(LIBLAPACK_LDFLAGS) libstfnum_la_LIBADD = $(LIBSTF_LDFLAGS) -lfftw3 all: all-am .SUFFIXES: .SUFFIXES: .c .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstfnum/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/libstfnum/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || 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)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_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}; \ } libstfnum.la: $(libstfnum_la_OBJECTS) $(libstfnum_la_DEPENDENCIES) $(EXTRA_libstfnum_la_DEPENDENCIES) $(AM_V_CXXLD)$(libstfnum_la_LINK) -rpath $(pkglibdir) $(libstfnum_la_OBJECTS) $(libstfnum_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Axb.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/funclib.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lm.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmbc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmlec.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measure.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stfnum.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< lm.lo: ./levmar/lm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lm.lo -MD -MP -MF $(DEPDIR)/lm.Tpo -c -o lm.lo `test -f './levmar/lm.c' || echo '$(srcdir)/'`./levmar/lm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lm.Tpo $(DEPDIR)/lm.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='./levmar/lm.c' object='lm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lm.lo `test -f './levmar/lm.c' || echo '$(srcdir)/'`./levmar/lm.c Axb.lo: ./levmar/Axb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT Axb.lo -MD -MP -MF $(DEPDIR)/Axb.Tpo -c -o Axb.lo `test -f './levmar/Axb.c' || echo '$(srcdir)/'`./levmar/Axb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/Axb.Tpo $(DEPDIR)/Axb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='./levmar/Axb.c' object='Axb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o Axb.lo `test -f './levmar/Axb.c' || echo '$(srcdir)/'`./levmar/Axb.c misc.lo: ./levmar/misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT misc.lo -MD -MP -MF $(DEPDIR)/misc.Tpo -c -o misc.lo `test -f './levmar/misc.c' || echo '$(srcdir)/'`./levmar/misc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/misc.Tpo $(DEPDIR)/misc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='./levmar/misc.c' object='misc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o misc.lo `test -f './levmar/misc.c' || echo '$(srcdir)/'`./levmar/misc.c lmlec.lo: ./levmar/lmlec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmlec.lo -MD -MP -MF $(DEPDIR)/lmlec.Tpo -c -o lmlec.lo `test -f './levmar/lmlec.c' || echo '$(srcdir)/'`./levmar/lmlec.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmlec.Tpo $(DEPDIR)/lmlec.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='./levmar/lmlec.c' object='lmlec.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmlec.lo `test -f './levmar/lmlec.c' || echo '$(srcdir)/'`./levmar/lmlec.c lmbc.lo: ./levmar/lmbc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmbc.lo -MD -MP -MF $(DEPDIR)/lmbc.Tpo -c -o lmbc.lo `test -f './levmar/lmbc.c' || echo '$(srcdir)/'`./levmar/lmbc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmbc.Tpo $(DEPDIR)/lmbc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='./levmar/lmbc.c' object='lmbc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmbc.lo `test -f './levmar/lmbc.c' || echo '$(srcdir)/'`./levmar/lmbc.c .cpp.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 $@ $< .cpp.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) '$<'` .cpp.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 $@ $< fit.lo: ./fit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fit.lo -MD -MP -MF $(DEPDIR)/fit.Tpo -c -o fit.lo `test -f './fit.cpp' || echo '$(srcdir)/'`./fit.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fit.Tpo $(DEPDIR)/fit.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./fit.cpp' object='fit.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fit.lo `test -f './fit.cpp' || echo '$(srcdir)/'`./fit.cpp funclib.lo: ./funclib.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT funclib.lo -MD -MP -MF $(DEPDIR)/funclib.Tpo -c -o funclib.lo `test -f './funclib.cpp' || echo '$(srcdir)/'`./funclib.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/funclib.Tpo $(DEPDIR)/funclib.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./funclib.cpp' object='funclib.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o funclib.lo `test -f './funclib.cpp' || echo '$(srcdir)/'`./funclib.cpp stfnum.lo: ./stfnum.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stfnum.lo -MD -MP -MF $(DEPDIR)/stfnum.Tpo -c -o stfnum.lo `test -f './stfnum.cpp' || echo '$(srcdir)/'`./stfnum.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stfnum.Tpo $(DEPDIR)/stfnum.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./stfnum.cpp' object='stfnum.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stfnum.lo `test -f './stfnum.cpp' || echo '$(srcdir)/'`./stfnum.cpp measure.lo: ./measure.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT measure.lo -MD -MP -MF $(DEPDIR)/measure.Tpo -c -o measure.lo `test -f './measure.cpp' || echo '$(srcdir)/'`./measure.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/measure.Tpo $(DEPDIR)/measure.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./measure.cpp' object='measure.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o measure.lo `test -f './measure.cpp' || echo '$(srcdir)/'`./measure.cpp mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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" 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 distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @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 check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done @BUILD_MODULE_TRUE@install: install-am @ISDARWIN_FALSE@install: install-am 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-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/Axb.Plo -rm -f ./$(DEPDIR)/fit.Plo -rm -f ./$(DEPDIR)/funclib.Plo -rm -f ./$(DEPDIR)/lm.Plo -rm -f ./$(DEPDIR)/lmbc.Plo -rm -f ./$(DEPDIR)/lmlec.Plo -rm -f ./$(DEPDIR)/measure.Plo -rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/stfnum.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ 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-pkglibLTLIBRARIES 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 ./$(DEPDIR)/Axb.Plo -rm -f ./$(DEPDIR)/fit.Plo -rm -f ./$(DEPDIR)/funclib.Plo -rm -f ./$(DEPDIR)/lm.Plo -rm -f ./$(DEPDIR)/lmbc.Plo -rm -f ./$(DEPDIR)/lmlec.Plo -rm -f ./$(DEPDIR)/measure.Plo -rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/stfnum.Plo -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-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir 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-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip 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-pkglibLTLIBRARIES .PRECIOUS: Makefile # don't install anything because it has to go into the app bundle @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@install: # 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: stimfit-0.16.7/src/libstfnum/funclib.cpp0000775000175000017500000005726414750344764013726 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include #include "./fit.h" #include "./measure.h" #include "./funclib.h" std::vector< stfnum::storedFunc > stfnum::GetFuncLib() { std::vector< stfnum::storedFunc > funcList; // Monoexponential function, free fit: std::vector parInfoMExp=getParInfoExp(1); funcList.push_back(stfnum::storedFunc("Monoexponential",parInfoMExp,fexp,fexp_init,fexp_jac,true)); // Monoexponential function, offset fixed to baseline: parInfoMExp[2].toFit=false; funcList.push_back(stfnum::storedFunc("Monoexponential, offset fixed to baseline", parInfoMExp,fexp,fexp_init,fexp_jac,true)); // Monoexponential function, starting with a delay, start fixed to baseline: std::vector parInfoMExpDe(4); parInfoMExpDe[0].toFit=false; parInfoMExpDe[0].desc="Baseline"; parInfoMExpDe[0].scale=stfnum::yscaleoffset; parInfoMExpDe[0].unscale=stfnum::yunscaleoffset; parInfoMExpDe[1].toFit=true; parInfoMExpDe[1].desc="Delay"; parInfoMExpDe[0].scale=stfnum::xscale; parInfoMExpDe[0].unscale=stfnum::xunscale; parInfoMExpDe[2].toFit=true; parInfoMExpDe[2].desc="tau"; parInfoMExpDe[0].scale=stfnum::xscale; parInfoMExpDe[0].unscale=stfnum::xunscale; parInfoMExpDe[3].toFit=true; parInfoMExpDe[3].desc="Peak"; parInfoMExpDe[0].scale=stfnum::yscale; parInfoMExpDe[0].unscale=stfnum::yunscale; funcList.push_back(stfnum::storedFunc("Monoexponential with delay, start fixed to baseline", parInfoMExpDe,fexpde,fexpde_init,stfnum::nojac,false)); // Biexponential function, free fit: std::vector parInfoBExp=getParInfoExp(2); funcList.push_back(stfnum::storedFunc( "Biexponential",parInfoBExp,fexp,fexp_init,fexp_jac,true,outputWTau)); // Biexponential function, offset fixed to baseline: parInfoBExp[4].toFit=false; funcList.push_back(stfnum::storedFunc("Biexponential, offset fixed to baseline", parInfoBExp,fexp,fexp_init,fexp_jac,true,outputWTau)); // Biexponential function, starting with a delay, start fixed to baseline: std::vector parInfoBExpDe(5); parInfoBExpDe[0].toFit=false; parInfoBExpDe[0].desc="Baseline"; parInfoBExpDe[0].scale=stfnum::yscaleoffset; parInfoBExpDe[0].unscale=stfnum::yunscaleoffset; parInfoBExpDe[1].toFit=true; parInfoBExpDe[1].desc="Delay"; parInfoBExpDe[1].scale=stfnum::xscale; parInfoBExpDe[1].unscale=stfnum::xunscale; // parInfoBExpDe[1].constrained = true; parInfoBExpDe[1].constr_lb = 0.0; parInfoBExpDe[1].constr_ub = DBL_MAX; parInfoBExpDe[2].toFit=true; parInfoBExpDe[2].desc="tau1"; parInfoBExpDe[2].scale=stfnum::xscale; parInfoBExpDe[2].unscale=stfnum::xunscale; // parInfoBExpDe[2].constrained = true; parInfoBExpDe[2].constr_lb = 1.0e-16; parInfoBExpDe[2].constr_ub = DBL_MAX; parInfoBExpDe[3].toFit=true; parInfoBExpDe[3].desc="Factor"; parInfoBExpDe[3].scale=stfnum::yscale; parInfoBExpDe[3].unscale=stfnum::yunscale; parInfoBExpDe[4].toFit=true; parInfoBExpDe[4].desc="tau2"; parInfoBExpDe[4].scale=stfnum::xscale; parInfoBExpDe[4].unscale=stfnum::xunscale; // parInfoBExpDe[4].constrained = true; parInfoBExpDe[4].constr_lb = 1.0e-16; parInfoBExpDe[4].constr_ub = DBL_MAX; funcList.push_back(stfnum::storedFunc( "Biexponential with delay, start fixed to baseline, delay constrained to > 0", parInfoBExpDe,fexpbde,fexpbde_init,stfnum::nojac,false)); // Triexponential function, free fit: std::vector parInfoTExp=getParInfoExp(3); funcList.push_back(stfnum::storedFunc( "Triexponential",parInfoTExp,fexp,fexp_init,fexp_jac,true,outputWTau)); // Triexponential function, free fit, different initialization: funcList.push_back(stfnum::storedFunc( "Triexponential, initialize for PSCs/PSPs",parInfoTExp,fexp,fexp_init2,fexp_jac,true,outputWTau)); // Triexponential function, offset fixed to baseline: parInfoTExp[6].toFit=false; funcList.push_back(stfnum::storedFunc( "Triexponential, offset fixed to baseline",parInfoTExp,fexp,fexp_init,fexp_jac,true,outputWTau)); // Alpha function: std::vector parInfoAlpha(3); parInfoAlpha[0].toFit=true; parInfoAlpha[0].desc="Amplitude"; parInfoAlpha[1].toFit=true; parInfoAlpha[1].desc="Rate"; parInfoAlpha[2].toFit=true; parInfoAlpha[2].desc="Offset"; funcList.push_back(stfnum::storedFunc( "Alpha function", parInfoAlpha,falpha,falpha_init,falpha_jac,true)); // HH gNa function: std::vector parInfoHH(4); parInfoHH[0].toFit=true; parInfoHH[0].desc="gprime_na"; parInfoHH[1].toFit=true; parInfoHH[1].desc="tau_m"; parInfoHH[2].toFit=true; parInfoHH[2].desc="tau_h"; parInfoHH[3].toFit=false; parInfoHH[3].desc="offset"; funcList.push_back(stfnum::storedFunc( "Hodgkin-Huxley g_Na function, offset fixed to baseline", parInfoHH, fHH, fHH_init, stfnum::nojac, false)); // power of 1 gNa function: funcList.push_back(stfnum::storedFunc( "power of 1 g_Na function, offset fixed to baseline", parInfoHH, fgnabiexp, fgnabiexp_init, fgnabiexp_jac, true)); // Gaussian std::vector parInfoGauss(3); parInfoGauss[0].toFit=true; parInfoGauss[0].desc="amp"; parInfoGauss[0].scale = stfnum::yscale; parInfoGauss[0].unscale = stfnum::yunscale; parInfoGauss[1].toFit=true; parInfoGauss[1].desc="mean"; parInfoGauss[1].scale = stfnum::xscale; parInfoGauss[1].unscale = stfnum::xunscale; parInfoGauss[2].toFit=true; parInfoGauss[2].constrained=true; parInfoGauss[2].constr_lb=0; parInfoGauss[2].constr_ub=DBL_MAX; parInfoGauss[2].desc="width"; parInfoGauss[2].scale = stfnum::xscale; parInfoGauss[2].unscale = stfnum::xunscale; funcList.push_back(stfnum::storedFunc( "Gaussian", parInfoGauss, fgauss, fgauss_init, fgauss_jac, true)); // Triexponential function, starting with a delay, start fixed to baseline: std::vector parInfoTExpDe(7); parInfoTExpDe[0].toFit=false; parInfoTExpDe[0].desc="Baseline"; parInfoTExpDe[0].scale=stfnum::yscaleoffset; parInfoTExpDe[0].unscale=stfnum::yunscaleoffset; parInfoTExpDe[1].toFit=true; parInfoTExpDe[1].desc="Delay"; parInfoTExpDe[1].scale=stfnum::xscale; parInfoTExpDe[1].unscale=stfnum::xunscale; // parInfoTExpDe[1].constrained = true; parInfoTExpDe[1].constr_lb = 0.0; parInfoTExpDe[1].constr_ub = DBL_MAX; parInfoTExpDe[2].toFit=true; parInfoTExpDe[2].desc="tau1a"; parInfoTExpDe[2].scale=stfnum::xscale; parInfoTExpDe[2].unscale=stfnum::xunscale; // parInfoTExpDe[2].constrained = true; parInfoTExpDe[2].constr_lb = 1.0e-16; parInfoTExpDe[2].constr_ub = DBL_MAX; parInfoTExpDe[3].toFit=true; parInfoTExpDe[3].desc="Factor"; parInfoTExpDe[3].scale=stfnum::yscale; parInfoTExpDe[3].unscale=stfnum::yunscale; parInfoTExpDe[4].toFit=true; parInfoTExpDe[4].desc="tau2"; parInfoTExpDe[4].scale=stfnum::xscale; parInfoTExpDe[4].unscale=stfnum::xunscale; parInfoTExpDe[5].toFit=true; parInfoTExpDe[5].desc="tau1b"; parInfoTExpDe[5].scale=stfnum::xscale; parInfoTExpDe[5].unscale=stfnum::xunscale; parInfoTExpDe[6].toFit=true; parInfoTExpDe[6].desc="ptau1b"; parInfoTExpDe[6].scale=stfnum::noscale; parInfoTExpDe[6].unscale=stfnum::noscale; funcList.push_back(stfnum::storedFunc( "Triexponential with delay, start fixed to baseline, delay constrained to > 0", parInfoTExpDe,fexptde,fexptde_init,stfnum::nojac,false)); return funcList; } double stfnum::fexp(double x, const Vector_double& p) { double sum=0.0; for (std::size_t n_p=0;n_p(pars.size()); for (int i=0; i < npars-1; i += 3) { arg=(x-pars[i+1])/pars[i+2]; ex=exp(-arg*arg); /* fac=pars[i]*ex*2.0*arg; */ y += pars[i] * ex; } return y; } Vector_double stfnum::fgauss_jac(double x, const Vector_double& pars) { double ex=0.0, arg=0.0; int npars=static_cast(pars.size()); Vector_double jac(npars); for (int i=0; i < npars-1; i += 3) { arg=(x-pars[i+1])/pars[i+2]; ex=exp(-arg*arg); jac[i] = ex; jac[i+1] = 2.0*ex*pars[i]*(x-pars[i+1]) / (pars[i+2]*pars[i+2]); jac[i+2] = 2.0*ex*pars[i]*(x-pars[i+1])*(x-pars[i+1]) / (pars[i+2]*pars[i+2]*pars[i+2]); } return jac; } void stfnum::fgauss_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ) { // Find the peak position in data: double maxT = stfnum::whereis( data, peak ) * dt; int npars=static_cast(pInit.size()); for (int i=0; i < npars-1; i += 3) { pInit[i] = peak; pInit[i+1] = maxT; pInit[i+2] = HalfWidth/ 1.65; //approximate t50 to one standard deviation } } void stfnum::fHH_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ) { // Find the peak position in data: double maxT = stfnum::whereis( data, peak ); if ( maxT == 0 ) maxT = data.size() * 0.05; // p[0]: gprime_na // p[1]: tau_m // p[2]: tau_h // p[3]: offset pInit[1] = RTLoHi; pInit[2] = HalfWidth; pInit[3] = base; //offset fixed to baseline double norm = (27.0*pow(pInit[2],3)*exp(-(pInit[1]*log((3.0*pInit[2]+pInit[1])/pInit[1]))/pInit[2])) / (27.0*pow(pInit[2],3)+27.0*pInit[1]*pInit[2]*pInit[2]+9.0*pInit[1]*pInit[1]*pInit[2]+pow(pInit[1],3)); pInit[0] = (peak-base)/norm; //pInit[1] = 0.5 * maxT * dt; //pInit[2] = 3 * maxT * dt; } Vector_double stfnum::fgnabiexp_jac(double x, const Vector_double& p) { Vector_double jac(4); jac[0] = ( 1-exp(-x/p[1]) ) * exp(-x/p[2]); jac[1] = -p[0] * x * exp(-x/p[1] - x/p[2]) /(p[1]*p[1]); jac[2] = p[0] * x * ( 1-exp(-x/p[1]) ) * exp(-x/p[2]) / (p[2]*p[2]); jac[3] = 1.0; return jac; } void stfnum::fgnabiexp_init(const Vector_double& data, double base, double peak, double RTLoHi, double HalfWidth, double dt, Vector_double& pInit ) { // Find the peak position in data: double maxT = stfnum::whereis( data, peak ); if ( maxT == 0 ) maxT = data.size() * 0.05; // p[0]: gprime_na // p[1]: tau_m // p[2]: tau_h // p[3]: offset // pInit[1]=0.5 * maxT * dt; // pInit[2]=3 * maxT * dt; pInit[1] = RTLoHi; pInit[2] = HalfWidth; pInit[3] = base; // offset fixed to baseline double tpeak = pInit[1]*log(pInit[2]/pInit[1]+1); double norm = (1-exp(-tpeak/pInit[1]))*exp(-tpeak/pInit[2]); pInit[0] = (peak-base)/norm; } std::vector stfnum::getParInfoExp(int n_exp) { std::vector retParInfo(n_exp*2+1); for (int n_e=0; n_e& parsInfo, double chisqr ) { stfnum::Table output(pars.size()+1,1); // call default version: try { output=defaultOutput(pars,parsInfo,chisqr); } catch (...) { throw; } // add weighted tau: // sum up amplitude terms: double sumAmp=0.0; for (std::size_t n_p=0;n_pvalue) { fromtop=true; } for (std::size_t n=0;n= value) { return n; } } } return 0; } stimfit-0.16.7/src/libstfnum/stfnum.h0000775000175000017500000004736114750344764013262 // Header file for the stimfit namespace // General-purpose routines // last revision: 08-08-2006 // C. Schmidt-Hieber, christsc@gmx.de // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file stfnum.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Math functions. */ #ifndef _STFNUM_H #define _STFNUM_H #ifdef _WINDOWS #pragma warning( disable : 4251 ) // Disable warning messages #endif #include #include #include #if (__cplusplus < 201103) # include #else # include # include # include #endif #ifdef _OPENMP #include #endif #include #ifdef _MSC_VER #define INFINITY (DBL_MAX+DBL_MAX) #ifndef NAN static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; #define NAN (*(const float *) __nan) #endif #endif #include "../libstfio/stfio.h" #include "./spline.h" namespace stfnum { /*! \addtogroup stfgen * @{ */ //! A function taking a double and a vector and returning a double. /*! Type definition for a function (or, to be precise, any 'callable entity') * that takes a double (the x-value) and a vector of parameters and returns * the function's result (the y-value). */ #if (__cplusplus < 201103) typedef boost::function Func; //! The jacobian of a stfnum::Func. typedef boost::function Jac; //! Scaling function for fit parameters typedef boost::function Scale; #else typedef std::function Func; //! The jacobian of a stfnum::Func. typedef std::function Jac; //! Scaling function for fit parameters typedef std::function Scale; #endif //! Dummy function, serves as a placeholder to initialize functions without a Jacobian. Vector_double nojac( double x, const Vector_double& p); //! Dummy function, serves as a placeholder to initialize parameters without a scaling function. double noscale(double param, double xscale, double xoff, double yscale, double yoff); //! Information about parameters used in storedFunc /*! Contains information about a function's parameters used * in storedFunc (see below). The client supplies a description * (desc) and determines whether the parameter is to be * fitted (toFit==true) or to be kept constant (toFit==false). */ struct parInfo { //! Default constructor parInfo() : desc(""),toFit(true), constrained(false), constr_lb(0), constr_ub(0), scale(noscale), unscale(noscale) {} //! Constructor /*! \param desc_ Parameter description string * \param toFit_ true if this parameter should be fitted, false if * it should be kept fixed. * \param constrained_ true if this is a constrained fit * \param constr_lb_ lower bound for constrained fit * \param constr_ub_ upper bound for constrained fit * \param scale_ scaling function * \param unscale_ unscaling function */ parInfo( const std::string& desc_, bool toFit_, bool constrained_ = false, double constr_lb_ = 0, double constr_ub_ = 0, Scale scale_ = noscale, Scale unscale_ = noscale) : desc(desc_),toFit(toFit_), constrained(false), constr_lb(constr_lb_), constr_ub(constr_ub_), scale(scale_), unscale(unscale_) {} std::string desc; /*!< Parameter description string */ bool toFit; /*!< true if this parameter should be fitted, false if it should be kept fixed. */ bool constrained; /*!< true if this parameter should be constrained */ double constr_lb; /*!< Lower boundary for box-constrained fits */ double constr_ub; /*!< Upper boundary for box-constrained fits */ Scale scale; /*!< Scaling function for this parameter */ Scale unscale; /*!< Unscaling function for this parameter */ }; //! A table used for printing information. /*! Members will throw std::out_of_range if out of range. */ class StfioDll Table { public: //! Constructor /*! \param nRows Initial number of rows. * \param nCols Initial number of columns. */ Table(std::size_t nRows,std::size_t nCols); //! Constructor /*! \param map A map used to initialise the table. */ Table(const std::map< std::string, double >& map); //! Range-checked access. Returns a copy. Throws std::out_of_range if out of range. /*! \param row 0-based row index. * \param col 0-based column index. * \return A copy of the double at row, col. */ double at(std::size_t row,std::size_t col) const; //! Range-checked access. Returns a reference. Throws std::out_of_range if out of range. /*! \param row 0-based row index. * \param col 0-based column index. * \return A reference to the double at row, col. */ double& at(std::size_t row,std::size_t col); //! Check whether a cell is empty. /*! \param row 0-based row index. * \param col 0-based column index. * \return true if empty, false otherwise. */ bool IsEmpty(std::size_t row,std::size_t col) const; //! Empties or un-empties a cell. /*! \param row 0-based row index. * \param col 0-based column index. * \param value true if the cell should be empty, false otherwise. */ void SetEmpty(std::size_t row,std::size_t col,bool value=true); //! Sets the label of a row. /*! \param row 0-based row index. * \param label Row label string. */ void SetRowLabel(std::size_t row,const std::string& label); //! Sets the label of a column. /*! \param col 0-based column index. * \param label Column label string. */ void SetColLabel(std::size_t col,const std::string& label); //! Retrieves the label of a row. /*! \param row 0-based row index. * \return Row label string. */ const std::string& GetRowLabel(std::size_t row) const; //! Retrieves the label of a column. /*! \param col 0-based column index. * \return Column label string. */ const std::string& GetColLabel(std::size_t col) const; //! Retrieves the number of rows. /*! \return The number of rows. */ std::size_t nRows() const { return rowLabels.size(); } //! Retrieves the number of columns. /*! \return The number of columns. */ std::size_t nCols() const { return colLabels.size(); } //! Appends rows to the table. /*! \param nRows The number of rows to be appended. */ void AppendRows(std::size_t nRows); private: // row major order: std::vector< std::vector > values; std::vector< std::deque< bool > > empty; std::vector< std::string > rowLabels; std::vector< std::string > colLabels; }; #if (__cplusplus < 201103) //! Print the output of a fit into a stfnum::Table. typedef boost::function,double)> Output; //! Default fit output function, constructing a stfnum::Table from the parameters, their description and chisqr. Table defaultOutput(const Vector_double& pars, const std::vector& parsInfo, double chisqr); //! Initialising function for the parameters in stfnum::Func to start a fit. typedef boost::function Init; #else //! Print the output of a fit into a stfnum::Table. typedef std::function,double)> Output; //! Default fit output function, constructing a stfnum::Table from the parameters, their description and chisqr. Table defaultOutput(const Vector_double& pars, const std::vector& parsInfo, double chisqr); //! Initialising function for the parameters in stfnum::Func to start a fit. typedef std::function Init; #endif //! Function used for least-squares fitting. /*! Objects of this class are used for fitting functions * to data. The client supplies a function (func), its * jacobian (jac), information about the function's parameters * (pInfo) and a function to initialize the parameters (init). */ struct StfioDll storedFunc { //! Constructor /*! \param name_ Plain function name. * \param pInfo_ A vector containing information about the function parameters. * \param func_ The function that will be fitted to the data. * \param jac_ Jacobian of func_. * \param hasJac_ true if a Jacobian is available. * \param init_ A function for initialising the parameters. * \param output_ Output of the fit. */ storedFunc( const std::string& name_, const std::vector& pInfo_, const Func& func_, const Init& init_, const Jac& jac_, bool hasJac_ = true, const Output& output_ = defaultOutput /*, bool hasId_ = true*/ ) : name(name_),pInfo(pInfo_),func(func_),init(init_),jac(jac_),hasJac(hasJac_),output(output_) /*, hasId(hasId_)*/ { /* if (hasId) { id = NextId(); std::string new_name; new_name << id << ": " << name; name = new_name; } else id = 0; */ } //! Destructor ~storedFunc() { } // static int n_funcs; /*!< Static function counter */ // int id; /*!< Function id; set automatically upon construction, so don't touch. */ std::string name; /*!< Function name. */ std::vector pInfo; /*!< A vector containing information about the function parameters. */ Func func; /*!< The function that will be fitted to the data. */ Init init; /*!< A function for initialising the parameters. */ Jac jac; /*!< Jacobian of func. */ bool hasJac; /*!< True if the function has an analytic Jacobian. */ Output output; /*!< Output of the fit. */ // bool hasId; /*!< Determines whether a function should have an id. */ }; //! Calculates the square of a number. /*! \param a Argument of the function. * \return \e a ^2 */ template T SQR (T a); //! Convolves a data set with a filter function. /*! \param toFilter The valarray to be filtered. * \param filter_start The index from which to start filtering. * \param filter_end The index at which to stop filtering. * \param a A valarray of parameters for the filter function. * \param SR The sampling rate. * \param func The filter function in the frequency domain. * \param inverse true if (1- \e func) should be used as the filter function, false otherwise * \return The convolved data set. */ StfioDll Vector_double filter( const Vector_double& toFilter, std::size_t filter_start, std::size_t filter_end, const Vector_double &a, int SR, stfnum::Func func, bool inverse = false ); //! Computes a histogram /*! \param data The signal * \param nbins Number of bins in the histogram. * \return A map with lower bin limits as keys, number of observations as values. */ std::map histogram(const Vector_double& data, int nbins=-1); //! Deconvolves a template from a signal /*! \param data The input signal * \param templ The template * \param SR The sampling rate in kHz. * \param hipass Highpass filter cutoff frequency in kHz * \param lopass Lowpass filter cutoff frequency in kHz * \return The result of the deconvolution */ StfioDll Vector_double deconvolve(const Vector_double& data, const Vector_double& templ, int SR, double hipass, double lopass, stfio::ProgressInfo& progDlg); //! Interpolates a dataset using cubic splines. /*! \param y The valarray to be interpolated. * \param oldF The original sampling frequency. * \param newF The new frequency of the interpolated array. * \return The interpolated data set. */ template std::vector cubicSpline( const std::vector& y, T oldF, T newF ); //! Differentiate data. /* \param input The valarray to be differentiated. * \param x_scale The sampling interval. * \return The result of the differentiation. */ template std::vector diff(const std::vector& input, T x_scale); //! Integration using Simpson's rule. /*! \param input The valarray to be integrated. * \param a Start of the integration interval. * \param b End of the integration interval. * \param x_scale Sampling interval. * \return The integral of \e input between \e a and \e b. */ StfioDll double integrate_simpson( const Vector_double& input, std::size_t a, std::size_t b, double x_scale ); //! Integration using the trapezium rule. /*! \param input The valarray to be integrated. * \param a Start of the integration interval. * \param b End of the integration interval. * \param x_scale Sampling interval. * \return The integral of \e input between \e a and \e b. */ StfioDll double integrate_trapezium( const Vector_double& input, std::size_t a, std::size_t b, double x_scale ); //! Solves a linear equation system using LAPACK. /*! Uses column-major order for matrices. For an example, see * Section::SetIsIntegrated() * \param m Number of rows of the matrix \e A. * \param n Number of columns of the matrix \e A. * \param nrhs Number of columns of the matrix \e B. * \param A On entry, the left-hand-side matrix. On exit, * the factors L and U from the factorization * A = P*L*U; the unit diagonal elements of L are not stored. * \param B On entry, the right-hand-side matrix. On exit, the * solution to the linear equation system. * \return At present, always returns 0. */ int linsolv( int m, int n, int nrhs, Vector_double& A, Vector_double& B ); //! Solve quadratic equations for 3 adjacent sampling points /*! \param data The data vector * \param begin Start of interval to be used * \param end End of interval to be used * \return Parameters of quadratic equation */ StfioDll Vector_double quad(const Vector_double& data, std::size_t begin, std::size_t end); //! Computes the event detection criterion according to Clements & Bekkers (1997). /*! \param data The valarray from which to extract events. * \param templ A template waveform that is used for event detection. * \return The detection criterion for every value of \e data. */ StfioDll Vector_double detectionCriterion( const Vector_double& data, const Vector_double& templ, stfio::ProgressInfo& progDlg ); // TODO: Add negative-going peaks. //! Searches for positive-going peaks. /*! \param data The valarray to be searched for peaks. * \param threshold Minimal amplitude of a peak. * \param minDistance Minimal distance between subsequent peaks. * \return A vector of indices where peaks have occurred in \e data. */ StfioDll std::vector peakIndices(const Vector_double& data, double threshold, int minDistance); //! Computes the linear correlation between two arrays. /*! \param va1 First array. * \param va2 Second array. * \return The linear correlation between the two arrays for each data point of \e va1. */ StfioDll Vector_double linCorr(const Vector_double& va1, const Vector_double& va2, stfio::ProgressInfo& progDlg); //! Computes a Gaussian that can be used as a filter kernel. /*! \f[ * f(x) = \mathrm{e}^{-0.3466 \left( \frac{x}{p_{0}} \right) ^2} * \f] * \param x Argument of the function. * \param p Function parameters, where \n * \e p[0] is the corner frequency (-3 dB according to Colquhoun) * \return The evaluated function. */ StfioDll double fgaussColqu(double x, const Vector_double& p); //! Computes a Boltzmann function. /*! \f[f(x)=\frac{1}{1+\mathrm{e}^{\frac{p_0-x}{p_1}}}\f] * \param x Argument of the function. * \param p Function parameters, where \n * \e p[0] is the midpoint and \n * \e p[1] is the slope of the function. \n * \return The evaluated function. */ double fboltz(double x, const Vector_double& p); //! Computes a Bessel polynomial. /*! \f[ * f(x, n) = \sum_{k=0}^n \frac{ \left( 2n - k \right) ! }{ \left( n - k \right) ! k! } \frac{x^k}{ 2^{n-k} } * \f] * \param x Argument of the function. * \param n Order of the polynomial. \n * \return The evaluated function. */ double fbessel(double x, int n); //! Computes a 4th-order Bessel polynomial that can be used as a filter kernel. /*! \f[ * f(x) = \frac{b(0,4)}{b(\frac{0.355589x}{p_0},4)} * \f] * where \f$ b(a,n) \f$ is the bessel polynomial stfnum::fbessel(). * \param x Argument of the function. * \param p Function parameters, where \n * \e p[0] is the corner frequency (-3 dB attenuation) * \return The evaluated function. */ StfioDll double fbessel4(double x, const Vector_double& p); //! Computes the faculty of an integer. /*! \param arg Argument of the function. * \return The faculty of \e arg. */ int fac(int arg); //! Computes \f$ 2^{arg} \f$. Uses the bitwise-shift operator (<<). /*! \param arg Argument of the function. * \return \f$ 2^{arg} \f$. */ int pow2(int arg); //! The direction of peak calculations enum direction { up, /*!< Find positive-going peaks. */ down, /*!< Find negative-going peaks. */ both, /*!< Find negative- or positive-going peaks, whichever is larger. */ undefined_direction /*!< Undefined direction. */ }; //! Methods for Baseline computation enum baseline_method { mean_sd = 0, /*!< Compute mean and s.d. for Baseline and Base SD. */ median_iqr = 1 /*!< Compute median and IQR for Baseline and Base SD. */ }; /*@}*/ } typedef std::vector< stfnum::storedFunc >::const_iterator c_stfunc_it; /*!< constant stfnum::storedFunc iterator */ inline int stfnum::pow2(int arg) {return 1< void SWAP(T s1, T s2) { T aux=s1; s1=s2; s2=aux; } template std::vector stfnum::cubicSpline(const std::vector& y, T oldF, T newF) { double factor_i=newF/oldF; int size=(int)y.size(); // size of interpolated data: int size_i=(int)(size*factor_i); Vector_double x(size); Vector_double y_d(size); for (int n_p=0; n_p < size; ++n_p) { x[n_p]=n_p; y_d[n_p]=y[n_p]; } Vector_double y_i(stfnum::spline_cubic_set(x,y_d,0,0,0,0)); std::vector y_if(size_i); Vector_double x_i(size_i); //Cubic spline interpolation: for (int n_i=0; n_i < size_i; ++n_i) { x_i[n_i]=(double)n_i * (double)size/(double)size_i; double yp, ypp; y_if[n_i]=(T)stfnum::spline_cubic_val(x,x_i[n_i],y_d,y_i,yp,ypp); } return y_if; } template std::vector stfnum::diff(const std::vector& input, T x_scale) { std::vector diffVA(input.size()-1); for (unsigned n=0;n inline T stfnum::SQR(T a) {return a*a;} #endif stimfit-0.16.7/src/libstfnum/levmar/0000775000175000017500000000000014764352501013116 5stimfit-0.16.7/src/libstfnum/levmar/lmlec_core.c0000664000175000017500000005732214750344764015326 ///////////////////////////////////////////////////////////////////////////////// // // Levenberg - Marquardt non-linear minimization algorithm // Copyright (C) 2004-05 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// #ifndef LM_REAL // not included by lmlec.c #error This file should not be compiled directly! #endif /* precision-specific definitions */ #define LMLEC_DATA LM_ADD_PREFIX(lmlec_data) #define LMLEC_ELIM LM_ADD_PREFIX(lmlec_elim) #define LMLEC_FUNC LM_ADD_PREFIX(lmlec_func) #define LMLEC_JACF LM_ADD_PREFIX(lmlec_jacf) #define LEVMAR_LEC_DER LM_ADD_PREFIX(levmar_lec_der) #define LEVMAR_LEC_DIF LM_ADD_PREFIX(levmar_lec_dif) #define LEVMAR_DER LM_ADD_PREFIX(levmar_der) #define LEVMAR_DIF LM_ADD_PREFIX(levmar_dif) #define LEVMAR_TRANS_MAT_MAT_MULT LM_ADD_PREFIX(levmar_trans_mat_mat_mult) #define LEVMAR_COVAR LM_ADD_PREFIX(levmar_covar) #define LEVMAR_FDIF_FORW_JAC_APPROX LM_ADD_PREFIX(levmar_fdif_forw_jac_approx) #define GEQP3 LM_MK_LAPACK_NAME(geqp3) #define ORGQR LM_MK_LAPACK_NAME(orgqr) #define TRTRI LM_MK_LAPACK_NAME(trtri) struct LMLEC_DATA{ LM_REAL *c, *Z, *p, *jac; int ncnstr; void (*func)(LM_REAL *p, LM_REAL *hx, int m, int n, void *adata); void (*jacf)(LM_REAL *p, LM_REAL *jac, int m, int n, void *adata); void *adata; }; /* prototypes for LAPACK routines */ #ifdef __cplusplus extern "C" { #endif extern int GEQP3(int *m, int *n, LM_REAL *a, int *lda, int *jpvt, LM_REAL *tau, LM_REAL *work, int *lwork, int *info); extern int ORGQR(int *m, int *n, int *k, LM_REAL *a, int *lda, LM_REAL *tau, LM_REAL *work, int *lwork, int *info); extern int TRTRI(char *uplo, char *diag, int *n, LM_REAL *a, int *lda, int *info); #ifdef __cplusplus } #endif /* * This function implements an elimination strategy for linearly constrained * optimization problems. The strategy relies on QR decomposition to transform * an optimization problem constrained by Ax=b to an equivalent, unconstrained * one. Also referred to as "null space" or "reduced Hessian" method. * See pp. 430-433 (chap. 15) of "Numerical Optimization" by Nocedal-Wright * for details. * * A is mxn with m<=n and rank(A)=m * Two matrices Y and Z of dimensions nxm and nx(n-m) are computed from A^T so that * their columns are orthonormal and every x can be written as x=Y*b + Z*x_z= * c + Z*x_z, where c=Y*b is a fixed vector of dimension n and x_z is an * arbitrary vector of dimension n-m. Then, the problem of minimizing f(x) * subject to Ax=b is equivalent to minimizing f(c + Z*x_z) with no constraints. * The computed Y and Z are such that any solution of Ax=b can be written as * x=Y*x_y + Z*x_z for some x_y, x_z. Furthermore, A*Y is nonsingular, A*Z=0 * and Z spans the null space of A. * * The function accepts A, b and computes c, Y, Z. If b or c is NULL, c is not * computed. Also, Y can be NULL in which case it is not referenced. * The function returns LM_ERROR in case of error, A's computed rank if successful * */ static int LMLEC_ELIM(LM_REAL *A, LM_REAL *b, LM_REAL *c, LM_REAL *Y, LM_REAL *Z, int m, int n) { static LM_REAL eps=LM_CNST(-1.0); LM_REAL *buf=NULL; LM_REAL *a, *tau, *work, *r, aux; register LM_REAL tmp; int a_sz, jpvt_sz, tau_sz, r_sz, Y_sz, worksz; int info, rank, *jpvt, tot_sz, mintmn, tm, tn; register int i, j, k; if(m>n){ fprintf(stderr, RCAT("matrix of constraints cannot have more rows than columns in", LMLEC_ELIM) "()!\n"); return LM_ERROR; } tm=n; tn=m; // transpose dimensions mintmn=m; /* calculate required memory size */ worksz=-1; // workspace query. Optimal work size is returned in aux //ORGQR((int *)&tm, (int *)&tm, (int *)&mintmn, NULL, (int *)&tm, NULL, (LM_REAL *)&aux, &worksz, &info); GEQP3((int *)&tm, (int *)&tn, NULL, (int *)&tm, NULL, NULL, (LM_REAL *)&aux, (int *)&worksz, &info); worksz=(int)aux; a_sz=tm*tm; // tm*tn is enough for xgeqp3() jpvt_sz=tn; tau_sz=mintmn; r_sz=mintmn*mintmn; // actually smaller if a is not of full row rank Y_sz=(Y)? 0 : tm*tn; tot_sz=(a_sz + tau_sz + r_sz + worksz + Y_sz)*sizeof(LM_REAL) + jpvt_sz*sizeof(int); /* should be arranged in that order for proper doubles alignment */ buf=(LM_REAL *)malloc(tot_sz); /* allocate a "big" memory chunk at once */ if(!buf){ fprintf(stderr, RCAT("Memory allocation request failed in ", LMLEC_ELIM) "()\n"); return LM_ERROR; } a=buf; tau=a+a_sz; r=tau+tau_sz; work=r+r_sz; if(!Y){ Y=work+worksz; jpvt=(int *)(Y+Y_sz); } else jpvt=(int *)(work+worksz); /* copy input array so that LAPACK won't destroy it. Note that copying is * done in row-major order, which equals A^T in column-major */ for(i=0; i0){ fprintf(stderr, RCAT(RCAT("unknown LAPACK error (%d) for ", GEQP3) " in ", LMLEC_ELIM) "()\n", info); } free(buf); return LM_ERROR; } /* the upper triangular part of a now contains the upper triangle of the unpermuted R */ if(eps<0.0){ LM_REAL aux; /* compute machine epsilon. DBL_EPSILON should do also */ for(eps=LM_CNST(1.0); aux=eps+LM_CNST(1.0), aux-LM_CNST(1.0)>0.0; eps*=LM_CNST(0.5)) ; eps*=LM_CNST(2.0); } tmp=tm*LM_CNST(10.0)*eps*FABS(a[0]); // threshold. tm is max(tm, tn) tmp=(tmp>LM_CNST(1E-12))? tmp : LM_CNST(1E-12); // ensure that threshold is not too small /* compute A^T's numerical rank by counting the non-zeros in R's diagonal */ for(i=rank=0; itmp || a[i*(tm+1)]<-tmp) ++rank; /* loop across R's diagonal elements */ else break; /* diagonal is arranged in absolute decreasing order */ if(rank0){ fprintf(stderr, RCAT(RCAT("A(%d, %d) is exactly zero for ", TRTRI) " (singular matrix) in ", LMLEC_ELIM) "()\n", info, info); } free(buf); return LM_ERROR; } /* finally, permute R^-T using Y as intermediate storage */ for(j=0; j0){ fprintf(stderr, RCAT(RCAT("unknown LAPACK error (%d) for ", ORGQR) " in ", LMLEC_ELIM) "()\n", info); } free(buf); return LM_ERROR; } /* compute Y=Q_1*R^-T*P^T. Y is tm x rank */ for(i=0; incnstr; c=data->c; Z=data->Z; p=data->p; /* p=c + Z*pp */ for(i=0; ifunc))(p, hx, m, n, data->adata); } /* constrained Jacobian: given pp, compute the Jacobian at c + Z*pp * Using the chain rule, the Jacobian with respect to pp equals the * product of the Jacobian with respect to p (at c + Z*pp) times Z */ static void LMLEC_JACF(LM_REAL *pp, LM_REAL *jacjac, int mm, int n, void *adata) { struct LMLEC_DATA *data=(struct LMLEC_DATA *)adata; int m; register int i, j, l; register LM_REAL sum, *aux1, *aux2; LM_REAL *c, *Z, *p, *jac; m=mm+data->ncnstr; c=data->c; Z=data->Z; p=data->p; jac=data->jac; /* p=c + Z*pp */ for(i=0; ijacf))(p, jac, m, n, data->adata); /* compute jac*Z in jacjac */ if(n*m<=__BLOCKSZ__SQ){ // this is a small problem /* This is the straightforward way to compute jac*Z. However, due to * its noncontinuous memory access pattern, it incures many cache misses when * applied to large minimization problems (i.e. problems involving a large * number of free variables and measurements), in which jac is too large to * fit in the L1 cache. For such problems, a cache-efficient blocking scheme * is preferable. On the other hand, the straightforward algorithm is faster * on small problems since in this case it avoids the overheads of blocking. */ for(i=0; iLM_CNST(1E-03)) fprintf(stderr, RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_LEC_DER) "()! [%.10g reset to %.10g]\n", i, p0[i], tmp); } if(!info) info=locinfo; /* make sure that LEVMAR_DER() is called with non-null info */ /* note that covariance computation is not requested from LEVMAR_DER() */ ret=LEVMAR_DER(LMLEC_FUNC, LMLEC_JACF, pp, x, mm, n, itmax, opts, info, work, NULL, (void *)&data); /* p=c + Z*pp */ for(i=0; iLM_CNST(1E-03)) fprintf(stderr, RCAT("Warning: component %d of starting point not feasible in ", LEVMAR_LEC_DIF) "()! [%.10g reset to %.10g]\n", i, p0[i], tmp); } if(!info) info=locinfo; /* make sure that LEVMAR_DIF() is called with non-null info */ /* note that covariance computation is not requested from LEVMAR_DIF() */ ret=LEVMAR_DIF(LMLEC_FUNC, pp, x, mm, n, itmax, opts, info, work, NULL, (void *)&data); /* p=c + Z*pp */ for(i=0; i= (b))?\ ( ((c) >= (a))? (a) : ( ((c) <= (b))? (b) : (c) ) ) : \ ( ((c) >= (b))? (b) : ( ((c) <= (a))? (a) : (c) ) ) ) /* Projections to feasible set \Omega: P_{\Omega}(y) := arg min { ||x - y|| : x \in \Omega}, y \in R^m */ /* project vector p to a box shaped feasible set. p is a mx1 vector. * Either lb, ub can be NULL. If not NULL, they are mx1 vectors */ static void BOXPROJECT(LM_REAL *p, LM_REAL *lb, LM_REAL *ub, int m) { register int i; if(!lb){ /* no lower bounds */ if(!ub) /* no upper bounds */ return; else{ /* upper bounds only */ for(i=m; i-->0; ) if(p[i]>ub[i]) p[i]=ub[i]; } } else if(!ub){ /* lower bounds only */ for(i=m; i-->0; ) if(p[i]0; ) p[i]=__MEDIAN3(lb[i], p[i], ub[i]); } #undef __MEDIAN3 /* pointwise scaling of bounds with the mx1 vector scl. If div=1 scaling is by 1./scl. * Either lb, ub can be NULL. If not NULL, they are mx1 vectors */ static void BOXSCALE(LM_REAL *lb, LM_REAL *ub, LM_REAL *scl, int m, int div) { register int i; if(!lb){ /* no lower bounds */ if(!ub) /* no upper bounds */ return; else{ /* upper bounds only */ if(div){ for(i=m; i-->0; ) if(ub[i]!=LM_REAL_MAX) ub[i]=ub[i]/scl[i]; }else{ for(i=m; i-->0; ) if(ub[i]!=LM_REAL_MAX) ub[i]=ub[i]*scl[i]; } } } else if(!ub){ /* lower bounds only */ if(div){ for(i=m; i-->0; ) if(lb[i]!=LM_REAL_MIN) lb[i]=lb[i]/scl[i]; }else{ for(i=m; i-->0; ) if(lb[i]!=LM_REAL_MIN) lb[i]=lb[i]*scl[i]; } } else{ /* box bounds */ if(div){ for(i=m; i-->0; ){ if(ub[i]!=LM_REAL_MAX) ub[i]=ub[i]/scl[i]; if(lb[i]!=LM_REAL_MIN) lb[i]=lb[i]/scl[i]; } }else{ for(i=m; i-->0; ){ if(ub[i]!=LM_REAL_MAX) ub[i]=ub[i]*scl[i]; if(lb[i]!=LM_REAL_MIN) lb[i]=lb[i]*scl[i]; } } } } /* compute the norm of a vector in a manner that avoids overflows */ static LM_REAL VECNORM(LM_REAL *x, int n) { #ifdef HAVE_LAPACK #define NRM2 LM_MK_BLAS_NAME(nrm2) extern LM_REAL NRM2(int *n, LM_REAL *dx, int *incx); int one=1; return NRM2(&n, x, &one); #undef NRM2 #else // no LAPACK, use the simple method described by Blue in TOMS78 register int i; LM_REAL max, sum, tmp; for(i=n, max=0.0; i-->0; ) if(x[i]>max) max=x[i]; else if(x[i]<-max) max=-x[i]; for(i=n, sum=0.0; i-->0; ){ tmp=x[i]/max; sum+=tmp*tmp; } return max*(LM_REAL)sqrt(sum); #endif /* HAVE_LAPACK */ } struct FUNC_STATE{ int n, *nfev; LM_REAL *hx, *x; LM_REAL *lb, *ub; void *adata; }; static void LNSRCH(int m, LM_REAL *x, LM_REAL f, LM_REAL *g, LM_REAL *p, LM_REAL alpha, LM_REAL *xpls, LM_REAL *ffpls, void (*func)(LM_REAL *p, LM_REAL *hx, int m, int n, void *adata), struct FUNC_STATE *state, int *mxtake, int *iretcd, LM_REAL stepmx, LM_REAL steptl, LM_REAL *sx) { /* Find a next newton iterate by backtracking line search. * Specifically, finds a \lambda such that for a fixed alpha<0.5 (usually 1e-4), * f(x + \lambda*p) <= f(x) + alpha * \lambda * g^T*p * * Translated (with a few changes) from Schnabel, Koontz & Weiss uncmin.f, v1.3 * Main changes include the addition of box projection and modification of the scaling * logic since uncmin.f operates in the original (unscaled) variable space. * PARAMETERS : * m --> dimension of problem (i.e. number of variables) * x(m) --> old iterate: x[k-1] * f --> function value at old iterate, f(x) * g(m) --> gradient at old iterate, g(x), or approximate * p(m) --> non-zero newton step * alpha --> fixed constant < 0.5 for line search (see above) * xpls(m) <-- new iterate x[k] * ffpls <-- function value at new iterate, f(xpls) * func --> name of subroutine to evaluate function * state <--> information other than x and m that func requires. * state is not modified in xlnsrch (but can be modified by func). * iretcd <-- return code * mxtake <-- boolean flag indicating step of maximum length used * stepmx --> maximum allowable step size * steptl --> relative step size at which successive iterates * considered close enough to terminate algorithm * sx(m) --> diagonal scaling matrix for x, can be NULL * internal variables * sln newton length * rln relative length of newton step */ register int i, j; int firstback = 1; LM_REAL disc; LM_REAL a3, b; LM_REAL t1, t2, t3, lambda, tlmbda, rmnlmb; LM_REAL scl, rln, sln, slp; LM_REAL tmp1, tmp2; LM_REAL fpls, pfpls = 0., plmbda = 0.; /* -Wall */ f*=LM_CNST(0.5); *mxtake = 0; *iretcd = 2; tmp1 = 0.; for (i = m; i-- > 0; ) tmp1 += p[i] * p[i]; sln = (LM_REAL)sqrt(tmp1); if (sln > stepmx) { /* newton step longer than maximum allowed */ scl = stepmx / sln; for (i = m; i-- > 0; ) /* p * scl */ p[i]*=scl; sln = stepmx; } for (i = m, slp = rln = 0.; i-- > 0; ){ slp+=g[i]*p[i]; /* g^T * p */ tmp1 = (FABS(x[i])>=LM_CNST(1.))? FABS(x[i]) : LM_CNST(1.); tmp2 = FABS(p[i])/tmp1; if(rln < tmp2) rln = tmp2; } rmnlmb = steptl / rln; lambda = LM_CNST(1.0); /* check if new iterate satisfactory. generate new lambda if necessary. */ for(j = _LSITMAX_; j-- > 0; ) { for (i = m; i-- > 0; ) xpls[i] = x[i] + lambda * p[i]; BOXPROJECT(xpls, state->lb, state->ub, m); /* project to feasible set */ /* evaluate function at new point */ if(!sx){ (*func)(xpls, state->hx, m, state->n, state->adata); ++(*(state->nfev)); } else{ for (i = m; i-- > 0; ) xpls[i] *= sx[i]; (*func)(xpls, state->hx, m, state->n, state->adata); ++(*(state->nfev)); for (i = m; i-- > 0; ) xpls[i] /= sx[i]; } /* ### state->hx=state->x-state->hx, tmp1=||state->hx|| */ #if 1 tmp1=LEVMAR_L2NRMXMY(state->hx, state->x, state->hx, state->n); #else for(i=0, tmp1=0.0; in; ++i){ state->hx[i]=tmp2=state->x[i]-state->hx[i]; tmp1+=tmp2*tmp2; } #endif fpls=LM_CNST(0.5)*tmp1; *ffpls=tmp1; if (fpls <= f + slp * alpha * lambda) { /* solution found */ *iretcd = 0; if (lambda == LM_CNST(1.) && sln > stepmx * LM_CNST(.99)) *mxtake = 1; return; } /* else : solution not (yet) found */ /* First find a point with a finite value */ if (lambda < rmnlmb) { /* no satisfactory xpls found sufficiently distinct from x */ *iretcd = 1; return; } else { /* calculate new lambda */ /* modifications to cover non-finite values */ if (!LM_FINITE(fpls)) { lambda *= LM_CNST(0.1); firstback = 1; } else { if (firstback) { /* first backtrack: quadratic fit */ tlmbda = -lambda * slp / ((fpls - f - slp) * LM_CNST(2.)); firstback = 0; } else { /* all subsequent backtracks: cubic fit */ t1 = fpls - f - lambda * slp; t2 = pfpls - f - plmbda * slp; t3 = LM_CNST(1.) / (lambda - plmbda); a3 = LM_CNST(3.) * t3 * (t1 / (lambda * lambda) - t2 / (plmbda * plmbda)); b = t3 * (t2 * lambda / (plmbda * plmbda) - t1 * plmbda / (lambda * lambda)); disc = b * b - a3 * slp; if (disc > b * b) /* only one positive critical point, must be minimum */ tlmbda = (-b + ((a3 < 0)? -(LM_REAL)sqrt(disc): (LM_REAL)sqrt(disc))) /a3; else /* both critical points positive, first is minimum */ tlmbda = (-b + ((a3 < 0)? (LM_REAL)sqrt(disc): -(LM_REAL)sqrt(disc))) /a3; if (tlmbda > lambda * LM_CNST(.5)) tlmbda = lambda * LM_CNST(.5); } plmbda = lambda; pfpls = fpls; if (tlmbda < lambda * LM_CNST(.1)) lambda *= LM_CNST(.1); else lambda = tlmbda; } } } /* this point is reached when the iterations limit is exceeded */ *iretcd = 1; /* failed */ return; } /* LNSRCH */ /* * This function seeks the parameter vector p that best describes the measurements * vector x under box constraints. * More precisely, given a vector function func : R^m --> R^n with n>=m, * it finds p s.t. func(p) ~= x, i.e. the squared second order (i.e. L2) norm of * e=x-func(p) is minimized under the constraints lb[i]<=p[i]<=ub[i]. * If no lower bound constraint applies for p[i], use -DBL_MAX/-FLT_MAX for lb[i]; * If no upper bound constraint applies for p[i], use DBL_MAX/FLT_MAX for ub[i]. * * This function requires an analytic Jacobian. In case the latter is unavailable, * use LEVMAR_BC_DIF() bellow * * Returns the number of iterations (>=0) if successful, LM_ERROR if failed * * For details, see C. Kanzow, N. Yamashita and M. Fukushima: "Levenberg-Marquardt * methods for constrained nonlinear equations with strong local convergence properties", * Journal of Computational and Applied Mathematics 172, 2004, pp. 375-397. * Also, see K. Madsen, H.B. Nielsen and O. Tingleff's lecture notes on * unconstrained Levenberg-Marquardt at http://www.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf * * The algorithm implemented by this function employs projected gradient steps. Since steepest descent * is very sensitive to poor scaling, diagonal scaling has been implemented through the dscl argument: * Instead of minimizing f(p) for p, f(D*q) is minimized for q=D^-1*p, D being a diagonal scaling * matrix whose diagonal equals dscl (see Nocedal-Wright p.27). dscl should contain "typical" magnitudes * for the parameters p. A NULL value for dscl implies no scaling. i.e. D=I. * To account for scaling, the code divides the starting point and box bounds pointwise by dscl. Moreover, * before calling func and jacf the scaling has to be undone (by multiplying), as should be done with * the final point. Note also that jac_q=jac_p*D, where jac_q, jac_p are the jacobians w.r.t. q & p, resp. */ int LEVMAR_BC_DER( void (*func)(LM_REAL *p, LM_REAL *hx, int m, int n, void *adata), /* functional relation describing measurements. A p \in R^m yields a \hat{x} \in R^n */ void (*jacf)(LM_REAL *p, LM_REAL *j, int m, int n, void *adata), /* function to evaluate the Jacobian \part x / \part p */ LM_REAL *p, /* I/O: initial parameter estimates. On output has the estimated solution */ LM_REAL *x, /* I: measurement vector. NULL implies a zero vector */ int m, /* I: parameter vector dimension (i.e. #unknowns) */ int n, /* I: measurement vector dimension */ LM_REAL *lb, /* I: vector of lower bounds. If NULL, no lower bounds apply */ LM_REAL *ub, /* I: vector of upper bounds. If NULL, no upper bounds apply */ LM_REAL *dscl, /* I: diagonal scaling constants. NULL implies no scaling */ int itmax, /* I: maximum number of iterations */ LM_REAL opts[4], /* I: minim. options [\mu, \epsilon1, \epsilon2, \epsilon3]. Respectively the scale factor for initial \mu, * stopping thresholds for ||J^T e||_inf, ||Dp||_2 and ||e||_2. Set to NULL for defaults to be used. * Note that ||J^T e||_inf is computed on free (not equal to lb[i] or ub[i]) variables only. */ LM_REAL info[LM_INFO_SZ], /* O: information regarding the minimization. Set to NULL if don't care * info[0]= ||e||_2 at initial p. * info[1-4]=[ ||e||_2, ||J^T e||_inf, ||Dp||_2, mu/max[J^T J]_ii ], all computed at estimated p. * info[5]= # iterations, * info[6]=reason for terminating: 1 - stopped by small gradient J^T e * 2 - stopped by small Dp * 3 - stopped by itmax * 4 - singular matrix. Restart from current p with increased mu * 5 - no further error reduction is possible. Restart with increased mu * 6 - stopped by small ||e||_2 * 7 - stopped by invalid (i.e. NaN or Inf) "func" values. This is a user error * info[7]= # function evaluations * info[8]= # Jacobian evaluations * info[9]= # linear systems solved, i.e. # attempts for reducing error */ LM_REAL *work, /* working memory at least LM_BC_DER_WORKSZ() reals large, allocated if NULL */ LM_REAL *covar, /* O: Covariance matrix corresponding to LS solution; mxm. Set to NULL if not needed. */ void *adata) /* pointer to possibly additional data, passed uninterpreted to func & jacf. * Set to NULL if not needed */ { register int i, j, k, l; int worksz, freework=0, issolved; /* temp work arrays */ LM_REAL *e, /* nx1 */ *hx, /* \hat{x}_i, nx1 */ *jacTe, /* J^T e_i mx1 */ *jac, /* nxm */ *jacTjac, /* mxm */ *Dp, /* mx1 */ *diag_jacTjac, /* diagonal of J^T J, mx1 */ *pDp, /* p + Dp, mx1 */ *sp_pDp=NULL; /* dscl*p or dscl*pDp, mx1 */ register LM_REAL mu, /* damping constant */ tmp; /* mainly used in matrix & vector multiplications */ LM_REAL p_eL2, jacTe_inf, pDp_eL2; /* ||e(p)||_2, ||J^T e||_inf, ||e(p+Dp)||_2 */ LM_REAL p_L2, Dp_L2=LM_REAL_MAX, dF, dL; LM_REAL tau, eps1, eps2, eps2_sq, eps3; LM_REAL init_p_eL2; int nu=2, nu2, stop=0, nfev, njev=0, nlss=0; const int nm=n*m; /* variables for constrained LM */ struct FUNC_STATE fstate; LM_REAL alpha=LM_CNST(1e-4), beta=LM_CNST(0.9), gamma=LM_CNST(0.99995), rho=LM_CNST(1e-8); LM_REAL t, t0, jacTeDp; LM_REAL tmin=LM_CNST(1e-12), tming=LM_CNST(1e-18); /* minimum step length for LS and PG steps */ const LM_REAL tini=LM_CNST(1.0); /* initial step length for LS and PG steps */ int nLMsteps=0, nLSsteps=0, nPGsteps=0, gprevtaken=0; int numactive; int (*linsolver)(LM_REAL *A, LM_REAL *B, LM_REAL *x, int m)=NULL; mu=jacTe_inf=t=0.0; tmin=tmin; /* -Wall */ if(n0; ) if(dscl[i]<=0.0){ fprintf(stderr, LCAT(LEVMAR_BC_DER, "(): scaling constants should be positive (scale %d: %g <= 0)\n"), i, dscl[i]); return LM_ERROR; } sp_pDp=(LM_REAL *)malloc(m*sizeof(LM_REAL)); if(!sp_pDp){ fprintf(stderr, LCAT(LEVMAR_BC_DER, "(): memory allocation request failed\n")); return LM_ERROR; } } if(opts){ tau=opts[0]; eps1=opts[1]; eps2=opts[2]; eps2_sq=opts[2]*opts[2]; eps3=opts[3]; } else{ // use default values tau=LM_CNST(LM_INIT_MU); eps1=LM_CNST(LM_STOP_THRESH); eps2=LM_CNST(LM_STOP_THRESH); eps2_sq=LM_CNST(LM_STOP_THRESH)*LM_CNST(LM_STOP_THRESH); eps3=LM_CNST(LM_STOP_THRESH); } if(!work){ worksz=LM_BC_DER_WORKSZ(m, n); //2*n+4*m + n*m + m*m; work=(LM_REAL *)malloc(worksz*sizeof(LM_REAL)); /* allocate a big chunk in one step */ if(!work){ fprintf(stderr, LCAT(LEVMAR_BC_DER, "(): memory allocation request failed\n")); return LM_ERROR; } freework=1; } /* set up work arrays */ e=work; hx=e + n; jacTe=hx + n; jac=jacTe + m; jacTjac=jac + nm; Dp=jacTjac + m*m; diag_jacTjac=Dp + m; pDp=diag_jacTjac + m; fstate.n=n; fstate.hx=hx; fstate.x=x; fstate.lb=lb; fstate.ub=ub; fstate.adata=adata; fstate.nfev=&nfev; /* see if starting point is within the feasible set */ for(i=0; i0; ) p[i]/=dscl[i]; BOXSCALE(lb, ub, dscl, m, 1); } for(k=0; k0; ) sp_pDp[i]=p[i]*dscl[i]; (*jacf)(sp_pDp, jac, m, n, adata); ++njev; /* compute jac*D */ for(i=n; i-->0; ){ register LM_REAL *jacim; jacim=jac+i*m; for(j=m; j-->0; ) jacim[j]*=dscl[j]; // jac[i*m+j]*=dscl[j]; } } /* J^T J, J^T e */ if(nm<__BLOCKSZ__SQ){ // this is a small problem /* J^T*J_ij = \sum_l J^T_il * J_lj = \sum_l J_li * J_lj. * Thus, the product J^T J can be computed using an outer loop for * l that adds J_li*J_lj to each element ij of the result. Note that * with this scheme, the accesses to J and JtJ are always along rows, * therefore induces less cache misses compared to the straightforward * algorithm for computing the product (i.e., l loop is innermost one). * A similar scheme applies to the computation of J^T e. * However, for large minimization problems (i.e., involving a large number * of unknowns and measurements) for which J/J^T J rows are too large to * fit in the L1 cache, even this scheme incures many cache misses. In * such cases, a cache-efficient blocking scheme is preferable. * * Thanks to John Nitao of Lawrence Livermore Lab for pointing out this * performance problem. * * Note that the non-blocking algorithm is faster on small * problems since in this case it avoids the overheads of blocking. */ register LM_REAL alpha, *jaclm, *jacTjacim; /* looping downwards saves a few computations */ for(i=m*m; i-->0; ) jacTjac[i]=0.0; for(i=m; i-->0; ) jacTe[i]=0.0; for(l=n; l-->0; ){ jaclm=jac+l*m; for(i=m; i-->0; ){ jacTjacim=jacTjac+i*m; alpha=jaclm[i]; //jac[l*m+i]; for(j=i+1; j-->0; ) /* j<=i computes lower triangular part only */ jacTjacim[j]+=jaclm[j]*alpha; //jacTjac[i*m+j]+=jac[l*m+j]*alpha /* J^T e */ jacTe[i]+=alpha*e[l]; } } for(i=m; i-->0; ) /* copy to upper part */ for(j=i+1; j0; * if p[i]==lb[i] g[i]<0; otherwise g[i]=0 */ for(i=j=numactive=0, p_L2=jacTe_inf=0.0; i0.0) ++j; } else if(lb && p[i]==lb[i]){ ++numactive; if(jacTe[i]<0.0) ++j; } else if(jacTe_inf < (tmp=FABS(jacTe[i]))) jacTe_inf=tmp; diag_jacTjac[i]=jacTjac[i*m+i]; /* save diagonal entries so that augmentation can be later canceled */ p_L2+=p[i]*p[i]; } //p_L2=sqrt(p_L2); #if 0 if(!(k%100)){ printf("Current estimate: "); for(i=0; itmp) tmp=diag_jacTjac[i]; /* find max diagonal element */ mu=tau*tmp; } else mu=LM_CNST(0.5)*tau*p_eL2; /* use Kanzow's starting mu */ } /* determine increment using a combination of adaptive damping, line search and projected gradient search */ while(1){ /* augment normal equations */ for(i=0; i=(p_L2+eps2)/(LM_CNST(EPSILON)*LM_CNST(EPSILON))){ /* almost singular */ stop=4; break; } if(!dscl){ (*func)(pDp, hx, m, n, adata); ++nfev; /* evaluate function at p + Dp */ } else{ for(i=m; i-->0; ) sp_pDp[i]=pDp[i]*dscl[i]; (*func)(sp_pDp, hx, m, n, adata); ++nfev; /* evaluate function at p + Dp */ } /* ### hx=x-hx, pDp_eL2=||hx|| */ #if 1 pDp_eL2=LEVMAR_L2NRMXMY(hx, x, hx, n); #else for(i=0, pDp_eL2=0.0; i0.0){ dF=p_eL2-pDp_eL2; tmp=(LM_CNST(2.0)*dF/dL-LM_CNST(1.0)); tmp=LM_CNST(1.0)-tmp*tmp*tmp; mu=mu*( (tmp>=LM_CNST(ONE_THIRD))? tmp : LM_CNST(ONE_THIRD) ); } else{ tmp=LM_CNST(0.1)*pDp_eL2; /* pDp_eL2 is the new p_eL2 */ mu=(mu>=tmp)? tmp : mu; } #else tmp=LM_CNST(0.1)*pDp_eL2; /* pDp_eL2 is the new p_eL2 */ mu=(mu>=tmp)? tmp : mu; #endif nu=2; for(i=0 ; i=LM_CNST(1.0))? tmp : LM_CNST(1.0) ); LNSRCH(m, p, p_eL2, jacTe, Dp, alpha, pDp, &pDp_eL2, func, &fstate, &mxtake, &iretcd, stepmx, steptl, dscl); /* NOTE: LNSRCH() updates hx */ if(iretcd!=0 || !LM_FINITE(pDp_eL2)) goto gradproj; /* rather inelegant but effective way to handle LNSRCH() failures... */ } #else /* use the simpler (but slower!) line search described by Kanzow et al */ for(t=tini; t>tmin; t*=beta){ for(i=0; i0; ) sp_pDp[i]=pDp[i]*dscl[i]; (*func)(sp_pDp, hx, m, n, adata); ++nfev; /* evaluate function at p + t*Dp */ } /* compute ||e(pDp)||_2 */ /* ### hx=x-hx, pDp_eL2=||hx|| */ #if 1 pDp_eL2=LEVMAR_L2NRMXMY(hx, x, hx, n); #else for(i=0, pDp_eL2=0.0; itming; t*=beta){ for(i=0; i0; ) sp_pDp[i]=pDp[i]*dscl[i]; (*func)(sp_pDp, hx, m, n, adata); ++nfev; /* evaluate function at p - t*g */ } /* compute ||e(pDp)||_2 */ /* ### hx=x-hx, pDp_eL2=||hx|| */ #if 1 pDp_eL2=LEVMAR_L2NRMXMY(hx, x, hx, n); #else for(i=0, pDp_eL2=0.0; i=itmax) stop=3; for(i=0; i0; ) for(j=m; j-->0; ) covar[i*m+j]*=(dscl[i]*dscl[j]); } } if(freework) free(work); #ifdef LINSOLVERS_RETAIN_MEMORY if(linsolver) (*linsolver)(NULL, NULL, NULL, 0); #endif #if 0 printf("%d LM steps, %d line search, %d projected gradient\n", nLMsteps, nLSsteps, nPGsteps); #endif if(dscl){ /* scale final point and constraints */ for(i=0; ifunc))(p, hx, m, n, dta->adata); } static void LMBC_DIF_JACF(LM_REAL *p, LM_REAL *jac, int m, int n, void *data) { struct LMBC_DIF_DATA *dta=(struct LMBC_DIF_DATA *)data; if(dta->ffdif){ /* evaluate user-supplied function at p */ (*(dta->func))(p, dta->hx, m, n, dta->adata); LEVMAR_FDIF_FORW_JAC_APPROX(dta->func, p, dta->hx, dta->hxx, dta->delta, jac, m, n, dta->adata); } else LEVMAR_FDIF_CENT_JAC_APPROX(dta->func, p, dta->hx, dta->hxx, dta->delta, jac, m, n, dta->adata); } /* No Jacobian version of the LEVMAR_BC_DER() function above: the Jacobian is approximated with * the aid of finite differences (forward or central, see the comment for the opts argument) * Ideally, this function should be implemented with a secant approach. Currently, it just calls * LEVMAR_BC_DER() */ int LEVMAR_BC_DIF( void (*func)(LM_REAL *p, LM_REAL *hx, int m, int n, void *adata), /* functional relation describing measurements. A p \in R^m yields a \hat{x} \in R^n */ LM_REAL *p, /* I/O: initial parameter estimates. On output has the estimated solution */ LM_REAL *x, /* I: measurement vector. NULL implies a zero vector */ int m, /* I: parameter vector dimension (i.e. #unknowns) */ int n, /* I: measurement vector dimension */ LM_REAL *lb, /* I: vector of lower bounds. If NULL, no lower bounds apply */ LM_REAL *ub, /* I: vector of upper bounds. If NULL, no upper bounds apply */ LM_REAL *dscl, /* I: diagonal scaling constants. NULL implies no scaling */ int itmax, /* I: maximum number of iterations */ LM_REAL opts[5], /* I: opts[0-4] = minim. options [\mu, \epsilon1, \epsilon2, \epsilon3, \delta]. Respectively the * scale factor for initial \mu, stopping thresholds for ||J^T e||_inf, ||Dp||_2 and ||e||_2 and * the step used in difference approximation to the Jacobian. Set to NULL for defaults to be used. * If \delta<0, the Jacobian is approximated with central differences which are more accurate * (but slower!) compared to the forward differences employed by default. */ LM_REAL info[LM_INFO_SZ], /* O: information regarding the minimization. Set to NULL if don't care * info[0]= ||e||_2 at initial p. * info[1-4]=[ ||e||_2, ||J^T e||_inf, ||Dp||_2, mu/max[J^T J]_ii ], all computed at estimated p. * info[5]= # iterations, * info[6]=reason for terminating: 1 - stopped by small gradient J^T e * 2 - stopped by small Dp * 3 - stopped by itmax * 4 - singular matrix. Restart from current p with increased mu * 5 - no further error reduction is possible. Restart with increased mu * 6 - stopped by small ||e||_2 * 7 - stopped by invalid (i.e. NaN or Inf) "func" values. This is a user error * info[7]= # function evaluations * info[8]= # Jacobian evaluations * info[9]= # linear systems solved, i.e. # attempts for reducing error */ LM_REAL *work, /* working memory at least LM_BC_DIF_WORKSZ() reals large, allocated if NULL */ LM_REAL *covar, /* O: Covariance matrix corresponding to LS solution; mxm. Set to NULL if not needed. */ void *adata) /* pointer to possibly additional data, passed uninterpreted to func. * Set to NULL if not needed */ { struct LMBC_DIF_DATA data; int ret; //fprintf(stderr, RCAT("\nWarning: current implementation of ", LEVMAR_BC_DIF) "() does not use a secant approach!\n\n"); data.ffdif=!opts || opts[4]>=0.0; data.func=func; data.hx=(LM_REAL *)malloc(2*n*sizeof(LM_REAL)); /* allocate a big chunk in one step */ if(!data.hx){ fprintf(stderr, LCAT(LEVMAR_BC_DIF, "(): memory allocation request failed\n")); return LM_ERROR; } data.hxx=data.hx+n; data.adata=adata; data.delta=(opts)? FABS(opts[4]) : (LM_REAL)LM_DIFF_DELTA; ret=LEVMAR_BC_DER(LMBC_DIF_FUNC, LMBC_DIF_JACF, p, x, m, n, lb, ub, dscl, itmax, opts, info, work, covar, (void *)&data); if(info){ /* correct the number of function calls */ if(data.ffdif) info[7]+=info[8]*(m+1); /* each Jacobian evaluation costs m+1 function calls */ else info[7]+=info[8]*(2*m); /* each Jacobian evaluation costs 2*m function calls */ } free(data.hx); return ret; } /* undefine everything. THIS MUST REMAIN AT THE END OF THE FILE */ #undef FUNC_STATE #undef LNSRCH #undef BOXPROJECT #undef BOXSCALE #undef LEVMAR_BOX_CHECK #undef VECNORM #undef LEVMAR_BC_DER #undef LMBC_DIF_DATA #undef LMBC_DIF_FUNC #undef LMBC_DIF_JACF #undef LEVMAR_BC_DIF #undef LEVMAR_FDIF_FORW_JAC_APPROX #undef LEVMAR_FDIF_CENT_JAC_APPROX #undef LEVMAR_COVAR #undef LEVMAR_TRANS_MAT_MAT_MULT #undef LEVMAR_L2NRMXMY #undef AX_EQ_B_LU #undef AX_EQ_B_CHOL #undef AX_EQ_B_PLASMA_CHOL #undef AX_EQ_B_QR #undef AX_EQ_B_QRLS #undef AX_EQ_B_SVD #undef AX_EQ_B_BK stimfit-0.16.7/src/libstfnum/levmar/compiler.h0000664000175000017500000000353014750344764015031 ///////////////////////////////////////////////////////////////////////////////// // // Levenberg - Marquardt non-linear minimization algorithm // Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// #ifndef _COMPILER_H_ #define _COMPILER_H_ /* note: intel's icc defines both __ICC & __INTEL_COMPILER. * Also, some compilers other than gcc define __GNUC__, * therefore gcc should be checked last */ #ifdef _MSC_VER #define inline __inline // MSVC #elif !defined(__ICC) && !defined(__INTEL_COMPILER) && !defined(__GNUC__) #define inline // other than MSVC, ICC, GCC: define empty #endif #ifdef _MSC_VER #define LM_FINITE _finite // MSVC #elif defined(__ICC) || defined(__INTEL_COMPILER) || defined(__GNUC__) #define LM_FINITE isfinite // ICC, GCC #else #define LM_FINITE isfinite // other than MSVC, ICC, GCC, let's hope this will work #endif #ifdef _MSC_VER #define LM_ISINF(x) (!_finite(x) && !_isnan(x)) // MSVC #elif defined(__ICC) || defined(__INTEL_COMPILER) || defined(__GNUC__) #define LM_ISINF(x) isinf(x) // ICC, GCC #else #define LM_ISINF(x) isinf(x) // other than MSVC, ICC, GCC, let's hope this will work #endif #endif /* _COMPILER_H_ */ stimfit-0.16.7/src/libstfnum/levmar/README.txt0000664000175000017500000001012714750344764014544 ************************************************************** LEVMAR version 2.6 By Manolis Lourakis Institute of Computer Science Foundation for Research and Technology - Hellas Heraklion, Crete, Greece ************************************************************** GENERAL This is levmar, a copylefted C/C++ implementation of the Levenberg-Marquardt non-linear least squares algorithm. levmar includes double and single precision LM versions, both with analytic and finite difference approximated Jacobians. levmar also has some support for constrained non-linear least squares, allowing linear equation, box and linear inequality constraints. The following options regarding the solution of the underlying augmented normal equations are offered: 1) Assuming that you have LAPACK (or an equivalent vendor library such as ESSL, MKL, NAG, ...) installed, you can use the included LAPACK-based solvers (default). 2) If you don't have LAPACK or decide not to use it, undefine HAVE_LAPACK in levmar.h and a LAPACK-free, LU-based linear systems solver will by used. Also, the line setting the variable LAPACKLIBS in the Makefile should be commented out. It is strongly recommended that you *do* employ LAPACK; if you don't have it already, I suggest getting clapack from http://www.netlib.org/clapack. However, LAPACK's use is not mandatory and the 2nd option makes levmar totally self-contained. See lmdemo.c for examples of use and http://www.ics.forth.gr/~lourakis/levmar for general comments. An example of using levmar for data fitting is in expfit.c The mathematical theory behind levmar is described in the lecture notes entitled "Methods for Non-Linear Least Squares Problems", by K. Madsen, H.B. Nielsen and O. Tingleff, Technical University of Denmark (http://www.imm.dtu.dk/courses/02611/nllsq.pdf). LICENSE levmar is released under the GNU Public License (GPL), which can be found in the included LICENSE file. Note that under the terms of GPL, commercial use is allowed only if a software employing levmar is also published in source under the GPL. However, if you are interested in using levmar in a proprietary commercial application, a commercial license for levmar can be obtained by contacting the author using the email address at the end of this file. COMPILATION - The preferred way to build levmar is through the CMake cross-platform build system. The included CMakeLists.txt file can be used to generate makefiles for Unix systems or project files for Windows systems. CMakeLists.txt defines some configuration variables that control certain aspects of levmar and can be modified from CMake's user interface. The values of these variables are automatically propagated to levmar.h after CMake runs. More information on how to use CMake can be found at http://www.cmake.org - levmar can also be built using the supplied makefiles. Platform-specific instructions are given below. Before compiling, you might consider setting a few configuration options found at the top of levmar.h. See the accompanying comments for more details. -- On a Linux/Unix system, typing "make" will build both levmar and the demo program using gcc. Alternatively, if Intel's C++ compiler is installed, it can be used by typing "make -f Makefile.icc". -- Under Windows and if Visual C is installed & configured for command line use, type "nmake /f Makefile.vc" in a cmd window to build levmar and the demo program. In case of trouble, read the comments on top of Makefile.vc MATLAB INTERFACE Since version 2.2, the levmar distribution includes a matlab mex interface. See the 'matlab' subdirectory for more information and examples of use. Notice that *_core.c files are not to be compiled directly; For example, Axb_core.c is included by Axb.c, to provide single and double precision routine versions. Send your comments/bug reports to lourakis (at) ics (dot) forth (dot) gr stimfit-0.16.7/src/libstfnum/levmar/Axb.c0000664000175000017500000000435014750344764013725 ///////////////////////////////////////////////////////////////////////////////// // // Solution of linear systems involved in the Levenberg - Marquardt // minimization algorithm // Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// /******************************************************************************** * LAPACK-based implementations for various linear system solvers. The same core * code is used with appropriate #defines to derive single and double precision * solver versions, see also Axb_core.c ********************************************************************************/ #include #include #include #include #include "levmar.h" #include "misc.h" #if !defined(LM_DBL_PREC) && !defined(LM_SNGL_PREC) #error At least one of LM_DBL_PREC, LM_SNGL_PREC should be defined! #endif #ifdef LM_DBL_PREC /* double precision definitions */ #define LM_REAL double #define LM_PREFIX d #define LM_CNST(x) (x) #ifndef HAVE_LAPACK #include #define LM_REAL_EPSILON DBL_EPSILON #endif #include "Axb_core.c" #undef LM_REAL #undef LM_PREFIX #undef LM_CNST #undef LM_REAL_EPSILON #endif /* LM_DBL_PREC */ #ifdef LM_SNGL_PREC /* single precision (float) definitions */ #define LM_REAL float #define LM_PREFIX s #define __SUBCNST(x) x##F #define LM_CNST(x) __SUBCNST(x) // force substitution #ifndef HAVE_LAPACK #define LM_REAL_EPSILON FLT_EPSILON #endif #include "Axb_core.c" #undef LM_REAL #undef LM_PREFIX #undef __SUBCNST #undef LM_CNST #undef LM_REAL_EPSILON #endif /* LM_SNGL_PREC */ stimfit-0.16.7/src/libstfnum/levmar/lm_core.c0000664000175000017500000007475314750344764014651 ///////////////////////////////////////////////////////////////////////////////// // // Levenberg - Marquardt non-linear minimization algorithm // Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// #ifndef LM_REAL // not included by lm.c #error This file should not be compiled directly! #endif /* precision-specific definitions */ #define LEVMAR_DER LM_ADD_PREFIX(levmar_der) #define LEVMAR_DIF LM_ADD_PREFIX(levmar_dif) #define LEVMAR_FDIF_FORW_JAC_APPROX LM_ADD_PREFIX(levmar_fdif_forw_jac_approx) #define LEVMAR_FDIF_CENT_JAC_APPROX LM_ADD_PREFIX(levmar_fdif_cent_jac_approx) #define LEVMAR_TRANS_MAT_MAT_MULT LM_ADD_PREFIX(levmar_trans_mat_mat_mult) #define LEVMAR_L2NRMXMY LM_ADD_PREFIX(levmar_L2nrmxmy) #define LEVMAR_COVAR LM_ADD_PREFIX(levmar_covar) #ifdef HAVE_LAPACK #define AX_EQ_B_LU LM_ADD_PREFIX(Ax_eq_b_LU) #define AX_EQ_B_CHOL LM_ADD_PREFIX(Ax_eq_b_Chol) #define AX_EQ_B_QR LM_ADD_PREFIX(Ax_eq_b_QR) #define AX_EQ_B_QRLS LM_ADD_PREFIX(Ax_eq_b_QRLS) #define AX_EQ_B_SVD LM_ADD_PREFIX(Ax_eq_b_SVD) #define AX_EQ_B_BK LM_ADD_PREFIX(Ax_eq_b_BK) #else #define AX_EQ_B_LU LM_ADD_PREFIX(Ax_eq_b_LU_noLapack) #endif /* HAVE_LAPACK */ #ifdef HAVE_PLASMA #define AX_EQ_B_PLASMA_CHOL LM_ADD_PREFIX(Ax_eq_b_PLASMA_Chol) #endif /* * This function seeks the parameter vector p that best describes the measurements vector x. * More precisely, given a vector function func : R^m --> R^n with n>=m, * it finds p s.t. func(p) ~= x, i.e. the squared second order (i.e. L2) norm of * e=x-func(p) is minimized. * * This function requires an analytic Jacobian. In case the latter is unavailable, * use LEVMAR_DIF() bellow * * Returns the number of iterations (>=0) if successful, LM_ERROR if failed * * For more details, see K. Madsen, H.B. Nielsen and O. Tingleff's lecture notes on * non-linear least squares at http://www.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf */ int LEVMAR_DER( void (*func)(LM_REAL *p, LM_REAL *hx, int m, int n, void *adata), /* functional relation describing measurements. A p \in R^m yields a \hat{x} \in R^n */ void (*jacf)(LM_REAL *p, LM_REAL *j, int m, int n, void *adata), /* function to evaluate the Jacobian \part x / \part p */ LM_REAL *p, /* I/O: initial parameter estimates. On output has the estimated solution */ LM_REAL *x, /* I: measurement vector. NULL implies a zero vector */ int m, /* I: parameter vector dimension (i.e. #unknowns) */ int n, /* I: measurement vector dimension */ int itmax, /* I: maximum number of iterations */ LM_REAL opts[4], /* I: minim. options [\mu, \epsilon1, \epsilon2, \epsilon3]. Respectively the scale factor for initial \mu, * stopping thresholds for ||J^T e||_inf, ||Dp||_2 and ||e||_2. Set to NULL for defaults to be used */ LM_REAL info[LM_INFO_SZ], /* O: information regarding the minimization. Set to NULL if don't care * info[0]= ||e||_2 at initial p. * info[1-4]=[ ||e||_2, ||J^T e||_inf, ||Dp||_2, mu/max[J^T J]_ii ], all computed at estimated p. * info[5]= # iterations, * info[6]=reason for terminating: 1 - stopped by small gradient J^T e * 2 - stopped by small Dp * 3 - stopped by itmax * 4 - singular matrix. Restart from current p with increased mu * 5 - no further error reduction is possible. Restart with increased mu * 6 - stopped by small ||e||_2 * 7 - stopped by invalid (i.e. NaN or Inf) "func" values. This is a user error * info[7]= # function evaluations * info[8]= # Jacobian evaluations * info[9]= # linear systems solved, i.e. # attempts for reducing error */ LM_REAL *work, /* working memory at least LM_DER_WORKSZ() reals large, allocated if NULL */ LM_REAL *covar, /* O: Covariance matrix corresponding to LS solution; mxm. Set to NULL if not needed. */ void *adata) /* pointer to possibly additional data, passed uninterpreted to func & jacf. * Set to NULL if not needed */ { register int i, j, k, l; int worksz, freework=0, issolved; /* temp work arrays */ LM_REAL *e, /* nx1 */ *hx, /* \hat{x}_i, nx1 */ *jacTe, /* J^T e_i mx1 */ *jac, /* nxm */ *jacTjac, /* mxm */ *Dp, /* mx1 */ *diag_jacTjac, /* diagonal of J^T J, mx1 */ *pDp; /* p + Dp, mx1 */ register LM_REAL mu, /* damping constant */ tmp; /* mainly used in matrix & vector multiplications */ LM_REAL p_eL2, jacTe_inf, pDp_eL2; /* ||e(p)||_2, ||J^T e||_inf, ||e(p+Dp)||_2 */ LM_REAL p_L2, Dp_L2=LM_REAL_MAX, dF, dL; LM_REAL tau, eps1, eps2, eps2_sq, eps3; LM_REAL init_p_eL2; int nu=2, nu2, stop=0, nfev, njev=0, nlss=0; const int nm=n*m; int (*linsolver)(LM_REAL *A, LM_REAL *B, LM_REAL *x, int m)=NULL; mu=jacTe_inf=0.0; /* -Wall */ if(n0; ) jacTjac[i]=0.0; for(i=m; i-->0; ) jacTe[i]=0.0; for(l=n; l-->0; ){ jaclm=jac+l*m; for(i=m; i-->0; ){ jacTjacim=jacTjac+i*m; alpha=jaclm[i]; //jac[l*m+i]; for(j=i+1; j-->0; ) /* j<=i computes lower triangular part only */ jacTjacim[j]+=jaclm[j]*alpha; //jacTjac[i*m+j]+=jac[l*m+j]*alpha /* J^T e */ jacTe[i]+=alpha*e[l]; } } for(i=m; i-->0; ) /* copy to upper part */ for(j=i+1; jtmp) tmp=diag_jacTjac[i]; /* find max diagonal element */ mu=tau*tmp; } /* determine increment using adaptive damping */ while(1){ /* augment normal equations */ for(i=0; i=(p_L2+eps2)/(LM_CNST(EPSILON)*LM_CNST(EPSILON))){ /* almost singular */ //if(Dp_L2>=(p_L2+eps2)/LM_CNST(EPSILON)){ /* almost singular */ stop=4; break; } (*func)(pDp, hx, m, n, adata); ++nfev; /* evaluate function at p + Dp */ /* compute ||e(pDp)||_2 */ /* ### hx=x-hx, pDp_eL2=||hx|| */ #if 1 pDp_eL2=LEVMAR_L2NRMXMY(hx, x, hx, n); #else for(i=0, pDp_eL2=0.0; i0.0 && dF>0.0){ /* reduction in error, increment is accepted */ tmp=(LM_CNST(2.0)*dF/dL-LM_CNST(1.0)); tmp=LM_CNST(1.0)-tmp*tmp*tmp; mu=mu*( (tmp>=LM_CNST(ONE_THIRD))? tmp : LM_CNST(ONE_THIRD) ); nu=2; for(i=0 ; i=itmax) stop=3; for(i=0; i=10)? m: 10, updjac, updp=1, newjac; const int nm=n*m; int (*linsolver)(LM_REAL *A, LM_REAL *B, LM_REAL *x, int m)=NULL; mu=jacTe_inf=p_L2=0.0; /* -Wall */ updjac=newjac=0; /* -Wall */ if(n16) || updjac==K){ /* compute difference approximation to J */ if(using_ffdif){ /* use forward differences */ LEVMAR_FDIF_FORW_JAC_APPROX(func, p, hx, wrk, delta, jac, m, n, adata); ++njap; nfev+=m; } else{ /* use central differences */ LEVMAR_FDIF_CENT_JAC_APPROX(func, p, wrk, wrk2, delta, jac, m, n, adata); ++njap; nfev+=2*m; } nu=2; updjac=0; updp=0; newjac=1; } if(newjac){ /* Jacobian has changed, recompute J^T J, J^t e, etc */ newjac=0; /* J^T J, J^T e */ if(nm<=__BLOCKSZ__SQ){ // this is a small problem /* J^T*J_ij = \sum_l J^T_il * J_lj = \sum_l J_li * J_lj. * Thus, the product J^T J can be computed using an outer loop for * l that adds J_li*J_lj to each element ij of the result. Note that * with this scheme, the accesses to J and JtJ are always along rows, * therefore induces less cache misses compared to the straightforward * algorithm for computing the product (i.e., l loop is innermost one). * A similar scheme applies to the computation of J^T e. * However, for large minimization problems (i.e., involving a large number * of unknowns and measurements) for which J/J^T J rows are too large to * fit in the L1 cache, even this scheme incures many cache misses. In * such cases, a cache-efficient blocking scheme is preferable. * * Thanks to John Nitao of Lawrence Livermore Lab for pointing out this * performance problem. * * Note that the non-blocking algorithm is faster on small * problems since in this case it avoids the overheads of blocking. */ register int l; register LM_REAL alpha, *jaclm, *jacTjacim; /* looping downwards saves a few computations */ for(i=m*m; i-->0; ) jacTjac[i]=0.0; for(i=m; i-->0; ) jacTe[i]=0.0; for(l=n; l-->0; ){ jaclm=jac+l*m; for(i=m; i-->0; ){ jacTjacim=jacTjac+i*m; alpha=jaclm[i]; //jac[l*m+i]; for(j=i+1; j-->0; ) /* j<=i computes lower triangular part only */ jacTjacim[j]+=jaclm[j]*alpha; //jacTjac[i*m+j]+=jac[l*m+j]*alpha /* J^T e */ jacTe[i]+=alpha*e[l]; } } for(i=m; i-->0; ) /* copy to upper part */ for(j=i+1; jtmp) tmp=diag_jacTjac[i]; /* find max diagonal element */ mu=tau*tmp; } /* determine increment using adaptive damping */ /* augment normal equations */ for(i=0; i=(p_L2+eps2)/(LM_CNST(EPSILON)*LM_CNST(EPSILON))){ /* almost singular */ //if(Dp_L2>=(p_L2+eps2)/LM_CNST(EPSILON)){ /* almost singular */ stop=4; break; } (*func)(pDp, wrk, m, n, adata); ++nfev; /* evaluate function at p + Dp */ /* compute ||e(pDp)||_2 */ /* ### wrk2=x-wrk, pDp_eL2=||wrk2|| */ #if 1 pDp_eL2=LEVMAR_L2NRMXMY(wrk2, x, wrk, n); #else for(i=0, pDp_eL2=0.0; i0){ /* update jac */ for(i=0; i0.0 && dF>0.0){ /* reduction in error, increment is accepted */ tmp=(LM_CNST(2.0)*dF/dL-LM_CNST(1.0)); tmp=LM_CNST(1.0)-tmp*tmp*tmp; mu=mu*( (tmp>=LM_CNST(ONE_THIRD))? tmp : LM_CNST(ONE_THIRD) ); nu=2; for(i=0 ; i=itmax) stop=3; for(i=0; i=0.0)? (x) : -(x)) #ifdef __cplusplus extern "C" { #endif /* blocking-based matrix multiply */ extern void slevmar_trans_mat_mat_mult(float *a, float *b, int n, int m); extern void dlevmar_trans_mat_mat_mult(double *a, double *b, int n, int m); /* forward finite differences */ extern void slevmar_fdif_forw_jac_approx(void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *hx, float *hxx, float delta, float *jac, int m, int n, void *adata); extern void dlevmar_fdif_forw_jac_approx(void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *hx, double *hxx, double delta, double *jac, int m, int n, void *adata); /* central finite differences */ extern void slevmar_fdif_cent_jac_approx(void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *hxm, float *hxp, float delta, float *jac, int m, int n, void *adata); extern void dlevmar_fdif_cent_jac_approx(void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *hxm, double *hxp, double delta, double *jac, int m, int n, void *adata); /* e=x-y and ||e|| */ extern float slevmar_L2nrmxmy(float *e, float *x, float *y, int n); extern double dlevmar_L2nrmxmy(double *e, double *x, double *y, int n); /* covariance of LS fit */ extern int slevmar_covar(float *JtJ, float *C, float sumsq, int m, int n); extern int dlevmar_covar(double *JtJ, double *C, double sumsq, int m, int n); /* box constraints consistency check */ extern int slevmar_box_check(float *lb, float *ub, int m); extern int dlevmar_box_check(double *lb, double *ub, int m); /* Cholesky */ extern int slevmar_chol(float *C, float *W, int m); extern int dlevmar_chol(double *C, double *W, int m); #ifdef __cplusplus } #endif #endif /* _MISC_H_ */ stimfit-0.16.7/src/libstfnum/levmar/LICENSE0000664000175000017500000004311014750344764014051 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. stimfit-0.16.7/src/libstfnum/levmar/misc_core.c0000664000175000017500000006000514750344764015155 ///////////////////////////////////////////////////////////////////////////////// // // Levenberg - Marquardt non-linear minimization algorithm // Copyright (C) 2004-05 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// #ifndef LM_REAL // not included by misc.c #error This file should not be compiled directly! #endif /* precision-specific definitions */ #define LEVMAR_CHKJAC LM_ADD_PREFIX(levmar_chkjac) #define LEVMAR_FDIF_FORW_JAC_APPROX LM_ADD_PREFIX(levmar_fdif_forw_jac_approx) #define LEVMAR_FDIF_CENT_JAC_APPROX LM_ADD_PREFIX(levmar_fdif_cent_jac_approx) #define LEVMAR_TRANS_MAT_MAT_MULT LM_ADD_PREFIX(levmar_trans_mat_mat_mult) #define LEVMAR_COVAR LM_ADD_PREFIX(levmar_covar) #define LEVMAR_STDDEV LM_ADD_PREFIX(levmar_stddev) #define LEVMAR_CORCOEF LM_ADD_PREFIX(levmar_corcoef) #define LEVMAR_R2 LM_ADD_PREFIX(levmar_R2) #define LEVMAR_BOX_CHECK LM_ADD_PREFIX(levmar_box_check) #define LEVMAR_L2NRMXMY LM_ADD_PREFIX(levmar_L2nrmxmy) #ifdef HAVE_LAPACK #define LEVMAR_PSEUDOINVERSE LM_ADD_PREFIX(levmar_pseudoinverse) static int LEVMAR_PSEUDOINVERSE(LM_REAL *A, LM_REAL *B, int m); #ifdef __cplusplus extern "C" { #endif /* BLAS matrix multiplication, LAPACK SVD & Cholesky routines */ #define GEMM LM_MK_BLAS_NAME(gemm) /* C := alpha*op( A )*op( B ) + beta*C */ extern void GEMM(char *transa, char *transb, int *m, int *n, int *k, LM_REAL *alpha, LM_REAL *a, int *lda, LM_REAL *b, int *ldb, LM_REAL *beta, LM_REAL *c, int *ldc); #define GESVD LM_MK_LAPACK_NAME(gesvd) #define GESDD LM_MK_LAPACK_NAME(gesdd) extern int GESVD(char *jobu, char *jobvt, int *m, int *n, LM_REAL *a, int *lda, LM_REAL *s, LM_REAL *u, int *ldu, LM_REAL *vt, int *ldvt, LM_REAL *work, int *lwork, int *info); /* lapack 3.0 new SVD routine, faster than xgesvd() */ extern int GESDD(char *jobz, int *m, int *n, LM_REAL *a, int *lda, LM_REAL *s, LM_REAL *u, int *ldu, LM_REAL *vt, int *ldvt, LM_REAL *work, int *lwork, int *iwork, int *info); /* Cholesky decomposition */ #define POTF2 LM_MK_LAPACK_NAME(potf2) extern int POTF2(char *uplo, int *n, LM_REAL *a, int *lda, int *info); #ifdef __cplusplus } #endif #define LEVMAR_CHOLESKY LM_ADD_PREFIX(levmar_chol) #else /* !HAVE_LAPACK */ #define LEVMAR_LUINVERSE LM_ADD_PREFIX(levmar_LUinverse_noLapack) static int LEVMAR_LUINVERSE(LM_REAL *A, LM_REAL *B, int m); #endif /* HAVE_LAPACK */ /* blocked multiplication of the transpose of the nxm matrix a with itself (i.e. a^T a) * using a block size of bsize. The product is returned in b. * Since a^T a is symmetric, its computation can be sped up by computing only its * upper triangular part and copying it to the lower part. * * More details on blocking can be found at * http://www-2.cs.cmu.edu/afs/cs/academic/class/15213-f02/www/R07/section_a/Recitation07-SectionA.pdf */ void LEVMAR_TRANS_MAT_MAT_MULT(LM_REAL *a, LM_REAL *b, int n, int m) { #ifdef HAVE_LAPACK /* use BLAS matrix multiply */ LM_REAL alpha=LM_CNST(1.0), beta=LM_CNST(0.0); /* Fool BLAS to compute a^T*a avoiding transposing a: a is equivalent to a^T in column major, * therefore BLAS computes a*a^T with a and a*a^T in column major, which is equivalent to * computing a^T*a in row major! */ GEMM("N", "T", &m, &m, &n, &alpha, a, &m, a, &m, &beta, b, &m); #else /* no LAPACK, use blocking-based multiply */ register int i, j, k, jj, kk; register LM_REAL sum, *bim, *akm; const int bsize=__BLOCKSZ__; #define __MIN__(x, y) (((x)<=(y))? (x) : (y)) #define __MAX__(x, y) (((x)>=(y))? (x) : (y)) /* compute upper triangular part using blocking */ for(jj=0; jj R^n: Given a p in R^m it yields hx in R^n * jacf points to a function implementing the Jacobian of func, whose correctness * is to be tested. Given a p in R^m, jacf computes into the nxm matrix j the * Jacobian of func at p. Note that row i of j corresponds to the gradient of * the i-th component of func, evaluated at p. * p is an input array of length m containing the point of evaluation. * m is the number of variables * n is the number of functions * adata points to possible additional data and is passed uninterpreted * to func, jacf. * err is an array of length n. On output, err contains measures * of correctness of the respective gradients. if there is * no severe loss of significance, then if err[i] is 1.0 the * i-th gradient is correct, while if err[i] is 0.0 the i-th * gradient is incorrect. For values of err between 0.0 and 1.0, * the categorization is less certain. In general, a value of * err[i] greater than 0.5 indicates that the i-th gradient is * probably correct, while a value of err[i] less than 0.5 * indicates that the i-th gradient is probably incorrect. * * * The function does not perform reliably if cancellation or * rounding errors cause a severe loss of significance in the * evaluation of a function. therefore, none of the components * of p should be unusually small (in particular, zero) or any * other value which may cause loss of significance. */ void LEVMAR_CHKJAC( void (*func)(LM_REAL *p, LM_REAL *hx, int m, int n, void *adata), void (*jacf)(LM_REAL *p, LM_REAL *j, int m, int n, void *adata), LM_REAL *p, int m, int n, void *adata, LM_REAL *err) { LM_REAL factor=LM_CNST(100.0); LM_REAL one=LM_CNST(1.0); LM_REAL zero=LM_CNST(0.0); LM_REAL *fvec, *fjac, *pp, *fvecp, *buf; register int i, j; LM_REAL eps, epsf, temp, epsmch; LM_REAL epslog; int fvec_sz=n, fjac_sz=n*m, pp_sz=m, fvecp_sz=n; epsmch=LM_REAL_EPSILON; eps=(LM_REAL)sqrt(epsmch); buf=(LM_REAL *)malloc((fvec_sz + fjac_sz + pp_sz + fvecp_sz)*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, LCAT(LEVMAR_CHKJAC, "(): memory allocation request failed\n")); exit(1); } fvec=buf; fjac=fvec+fvec_sz; pp=fjac+fjac_sz; fvecp=pp+pp_sz; /* compute fvec=func(p) */ (*func)(p, fvec, m, n, adata); /* compute the Jacobian at p */ (*jacf)(p, fjac, m, n, adata); /* compute pp */ for(j=0; j=epsf*FABS(fvec[i])) temp=eps*FABS((fvecp[i]-fvec[i])/eps - err[i])/(FABS(fvec[i])+FABS(fvecp[i])); err[i]=one; if(temp>epsmch && temp=eps) err[i]=zero; } free(buf); return; } #ifdef HAVE_LAPACK /* * This function computes the pseudoinverse of a square matrix A * into B using SVD. A and B can coincide * * The function returns 0 in case of error (e.g. A is singular), * the rank of A if successful * * A, B are mxm * */ static int LEVMAR_PSEUDOINVERSE(LM_REAL *A, LM_REAL *B, int m) { LM_REAL *buf=NULL; int buf_sz=0; static LM_REAL eps=LM_CNST(-1.0); register int i, j; LM_REAL *a, *u, *s, *vt, *work; int a_sz, u_sz, s_sz, vt_sz, tot_sz; LM_REAL thresh, one_over_denom; int info, rank, worksz, *iwork, iworksz; /* calculate required memory size */ worksz=5*m; // min worksize for GESVD //worksz=m*(7*m+4); // min worksize for GESDD iworksz=8*m; a_sz=m*m; u_sz=m*m; s_sz=m; vt_sz=m*m; tot_sz=(a_sz + u_sz + s_sz + vt_sz + worksz)*sizeof(LM_REAL) + iworksz*sizeof(int); /* should be arranged in that order for proper doubles alignment */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", LEVMAR_PSEUDOINVERSE) "() failed!\n"); return 0; /* error */ } a=buf; u=a+a_sz; s=u+u_sz; vt=s+s_sz; work=vt+vt_sz; iwork=(int *)(work+worksz); /* store A (column major!) into a */ for(i=0; i0.0; eps*=LM_CNST(0.5)) ; eps*=LM_CNST(2.0); } /* compute the pseudoinverse in B */ for(i=0; ithresh; rank++){ one_over_denom=LM_CNST(1.0)/s[rank]; for(j=0; jmax) max=tmp; if(max==0.0){ fprintf(stderr, RCAT("Singular matrix A in ", LEVMAR_LUINVERSE) "()!\n"); free(buf); return 0; } work[i]=LM_CNST(1.0)/max; } for(j=0; j=max){ max=tmp; maxi=i; } } if(j!=maxi){ for(k=0; k=0; --i){ sum=x[i]; for(j=i+1; j0; ) tmp+=x[i]; xavg=tmp/(LM_REAL)n; if(x) for(i=n, SSerr=SStot=0.0; i-->0; ){ tmp=x[i]-hx[i]; SSerr+=tmp*tmp; tmp=x[i]-xavg; SStot+=tmp*tmp; } else /* x==0 */ for(i=n, SSerr=SStot=0.0; i-->0; ){ tmp=-hx[i]; SSerr+=tmp*tmp; tmp=-xavg; SStot+=tmp*tmp; } free(hx); return LM_CNST(1.0) - SSerr/SStot; } /* check box constraints for consistency */ int LEVMAR_BOX_CHECK(LM_REAL *lb, LM_REAL *ub, int m) { register int i; if(!lb || !ub) return 1; for(i=0; iub[i]) return 0; return 1; } #ifdef HAVE_LAPACK /* compute the Cholesky decomposition of C in W, s.t. C=W^t W and W is upper triangular */ int LEVMAR_CHOLESKY(LM_REAL *C, LM_REAL *W, int m) { register int i, j; int info; /* copy weights array C to W so that LAPACK won't destroy it; * C is assumed symmetric, hence no transposition is needed */ for(i=0, j=m*m; i>bpwr)<0; i-=blocksize){ e[i ]=x[i ]-y[i ]; sum0+=e[i ]*e[i ]; j1=i-1; e[j1]=x[j1]-y[j1]; sum1+=e[j1]*e[j1]; j2=i-2; e[j2]=x[j2]-y[j2]; sum2+=e[j2]*e[j2]; j3=i-3; e[j3]=x[j3]-y[j3]; sum3+=e[j3]*e[j3]; j4=i-4; e[j4]=x[j4]-y[j4]; sum0+=e[j4]*e[j4]; j5=i-5; e[j5]=x[j5]-y[j5]; sum1+=e[j5]*e[j5]; j6=i-6; e[j6]=x[j6]-y[j6]; sum2+=e[j6]*e[j6]; j7=i-7; e[j7]=x[j7]-y[j7]; sum3+=e[j7]*e[j7]; } /* * There may be some left to do. * This could be done as a simple for() loop, * but a switch is faster (and more interesting) */ i=blockn; if(i0; i-=blocksize){ e[i ]=-y[i ]; sum0+=e[i ]*e[i ]; j1=i-1; e[j1]=-y[j1]; sum1+=e[j1]*e[j1]; j2=i-2; e[j2]=-y[j2]; sum2+=e[j2]*e[j2]; j3=i-3; e[j3]=-y[j3]; sum3+=e[j3]*e[j3]; j4=i-4; e[j4]=-y[j4]; sum0+=e[j4]*e[j4]; j5=i-5; e[j5]=-y[j5]; sum1+=e[j5]*e[j5]; j6=i-6; e[j6]=-y[j6]; sum2+=e[j6]*e[j6]; j7=i-7; e[j7]=-y[j7]; sum3+=e[j7]*e[j7]; } /* * There may be some left to do. * This could be done as a simple for() loop, * but a switch is faster (and more interesting) */ i=blockn; if(ibuf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QR) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QR) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; tau=a+a_sz; r=tau+tau_sz; work=r+r_sz; /* store A (column major!) into a */ for(i=0; ibuf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QRLS) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_QRLS) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; tau=a+a_sz; r=tau+tau_sz; work=r+r_sz; /* store A (column major!) into a */ for(i=0; ibuf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_CHOL) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_CHOL) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; /* store A into a and B into x. A is assumed symmetric, * hence no transposition is needed */ memcpy(a, A, a_sz*sizeof(LM_REAL)); memcpy(x, B, m*sizeof(LM_REAL)); /* Cholesky decomposition of A */ //POTF2("L", (int *)&m, a, (int *)&m, (int *)&info); POTRF("L", (int *)&m, a, (int *)&m, (int *)&info); /* error treatment */ if(info!=0){ if(info<0){ fprintf(stderr, RCAT(RCAT(RCAT("LAPACK error: illegal value for argument %d of ", POTF2) "/", POTRF) " in ", AX_EQ_B_CHOL) "()\n", -info); exit(1); } else{ fprintf(stderr, RCAT(RCAT(RCAT("LAPACK error: the leading minor of order %d is not positive definite,\nthe factorization could not be completed for ", POTF2) "/", POTRF) " in ", AX_EQ_B_CHOL) "()\n", info); #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 0; } } /* solve using the computed Cholesky in one lapack call */ POTRS("L", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info); if(info<0){ fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", POTRS) " in ", AX_EQ_B_CHOL) "()\n", -info); exit(1); } #if 0 /* alternative: solve the linear system L y = b ... */ TRTRS("L", "N", "N", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info); /* error treatment */ if(info!=0){ if(info<0){ fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) " in ", AX_EQ_B_CHOL) "()\n", -info); exit(1); } else{ fprintf(stderr, RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_CHOL) "()\n", info); #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 0; } } /* ... solve the linear system L^T x = y */ TRTRS("L", "T", "N", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info); /* error treatment */ if(info!=0){ if(info<0){ fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", TRTRS) "in ", AX_EQ_B_CHOL) "()\n", -info); exit(1); } else{ fprintf(stderr, RCAT("LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in ", AX_EQ_B_CHOL) "()\n", info); #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 0; } } #endif /* 0 */ #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 1; } #ifdef HAVE_PLASMA /* Linear algebra using PLASMA parallel library for multicore CPUs. * http://icl.cs.utk.edu/plasma/ * * WARNING: BLAS multithreading should be disabled, e.g. setenv MKL_NUM_THREADS 1 */ #ifndef _LM_PLASMA_MISC_ /* avoid multiple inclusion of helper code */ #define _LM_PLASMA_MISC_ #include #include #include #include #include /* programmatically determine the number of cores on the current machine */ #ifdef _WIN32 #include #elif __linux #include #endif static int getnbcores() { #ifdef _WIN32 SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; #elif __linux return sysconf(_SC_NPROCESSORS_ONLN); #else // unknown system return 2<<1; // will be halved by right shift below #endif } static int PLASMA_ncores=-(getnbcores()>>1); // >0 if PLASMA initialized, <0 otherwise /* user-specified number of cores */ void levmar_PLASMA_setnbcores(int cores) { PLASMA_ncores=(cores>0)? -cores : ((cores)? cores : -2); } #endif /* _LM_PLASMA_MISC_ */ /* * This function returns the solution of Ax=b * * The function assumes that A is symmetric & positive definite and employs the * Cholesky decomposition implemented by PLASMA for homogeneous multicore processors. * * A is mxm, b is mx1 * * The function returns 0 in case of error, 1 if successfull * * This function is often called repetitively to solve problems of identical * dimensions. To avoid repetitive malloc's and free's, allocated memory is * retained between calls and free'd-malloc'ed when not of the appropriate size. * A call with NULL as the first argument forces this memory to be released. */ int AX_EQ_B_PLASMA_CHOL(LM_REAL *A, LM_REAL *B, LM_REAL *x, int m) { __STATIC__ LM_REAL *buf=NULL; __STATIC__ int buf_sz=0; LM_REAL *a; int a_sz, tot_sz; int info, nrhs=1; if(A==NULL){ #ifdef LINSOLVERS_RETAIN_MEMORY if(buf) free(buf); buf=NULL; buf_sz=0; #endif /* LINSOLVERS_RETAIN_MEMORY */ PLASMA_Finalize(); PLASMA_ncores=-PLASMA_ncores; return 1; } /* calculate required memory size */ a_sz=m*m; tot_sz=a_sz; #ifdef LINSOLVERS_RETAIN_MEMORY if(tot_sz>buf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_PLASMA_CHOL) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz*sizeof(LM_REAL)); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_PLASMA_CHOL) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; /* store A into a and B into x; A is assumed to be symmetric, * hence no transposition is needed */ memcpy(a, A, a_sz*sizeof(LM_REAL)); memcpy(x, B, m*sizeof(LM_REAL)); /* initialize PLASMA */ if(PLASMA_ncores<0){ PLASMA_ncores=-PLASMA_ncores; PLASMA_Init(PLASMA_ncores); fprintf(stderr, RCAT("\n", AX_EQ_B_PLASMA_CHOL) "(): PLASMA is running on %d cores.\n\n", PLASMA_ncores); } /* Solve the linear system */ info=PLASMA_POSV(PlasmaLower, m, 1, a, m, x, m); /* error treatment */ if(info!=0){ if(info<0){ fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", PLASMA_POSV) " in ", AX_EQ_B_PLASMA_CHOL) "()\n", -info); exit(1); } else{ fprintf(stderr, RCAT(RCAT("LAPACK error: the leading minor of order %d is not positive definite,\n" "the factorization could not be completed for ", PLASMA_POSV) " in ", AX_EQ_B_CHOL) "()\n", info); #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 0; } } #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 1; } #endif /* HAVE_PLASMA */ /* * This function returns the solution of Ax = b * * The function employs LU decomposition: * If A=L U with L lower and U upper triangular, then the original system * amounts to solving * L y = b, U x = y * * A is mxm, b is mx1 * * The function returns 0 in case of error, 1 if successful * * This function is often called repetitively to solve problems of identical * dimensions. To avoid repetitive malloc's and free's, allocated memory is * retained between calls and free'd-malloc'ed when not of the appropriate size. * A call with NULL as the first argument forces this memory to be released. */ int AX_EQ_B_LU(LM_REAL *A, LM_REAL *B, LM_REAL *x, int m) { __STATIC__ LM_REAL *buf=NULL; __STATIC__ int buf_sz=0; int a_sz, ipiv_sz, tot_sz; register int i, j; int info, *ipiv, nrhs=1; LM_REAL *a; if(!A) #ifdef LINSOLVERS_RETAIN_MEMORY { if(buf) free(buf); buf=NULL; buf_sz=0; return 1; } #else return 1; /* NOP */ #endif /* LINSOLVERS_RETAIN_MEMORY */ /* calculate required memory size */ ipiv_sz=m; a_sz=m*m; tot_sz=a_sz*sizeof(LM_REAL) + ipiv_sz*sizeof(int); /* should be arranged in that order for proper doubles alignment */ #ifdef LINSOLVERS_RETAIN_MEMORY if(tot_sz>buf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; ipiv=(int *)(a+a_sz); /* store A (column major!) into a and B into x */ for(i=0; ibuf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_SVD) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_SVD) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; u=a+a_sz; s=u+u_sz; vt=s+s_sz; work=vt+vt_sz; iwork=(int *)(work+worksz); /* store A (column major!) into a */ for(i=0; i0.0; eps*=LM_CNST(0.5)) ; eps*=LM_CNST(2.0); } /* compute the pseudoinverse in a */ for(i=0; ithresh; rank++){ one_over_denom=LM_CNST(1.0)/s[rank]; for(j=0; jbuf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_BK) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(LM_REAL *)malloc(buf_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_BK) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; work=a+a_sz; ipiv=(int *)(work+work_sz); /* store A into a and B into x; A is assumed to be symmetric, hence * the column and row major order representations are the same */ memcpy(a, A, a_sz*sizeof(LM_REAL)); memcpy(x, B, m*sizeof(LM_REAL)); /* LDLt factorization for A */ SYTRF("L", (int *)&m, a, (int *)&m, ipiv, work, (int *)&work_sz, (int *)&info); if(info!=0){ if(info<0){ fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", SYTRF) " in ", AX_EQ_B_BK) "()\n", -info); exit(1); } else{ fprintf(stderr, RCAT(RCAT("LAPACK error: singular block diagonal matrix D for", SYTRF) " in ", AX_EQ_B_BK)"() [D(%d, %d) is zero]\n", info, info); #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 0; } } /* solve the system with the computed factorization */ SYTRS("L", (int *)&m, (int *)&nrhs, a, (int *)&m, ipiv, x, (int *)&m, (int *)&info); if(info<0){ fprintf(stderr, RCAT(RCAT("LAPACK error: illegal value for argument %d of ", SYTRS) " in ", AX_EQ_B_BK) "()\n", -info); exit(1); } #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 1; } /* undefine all. IT MUST REMAIN IN THIS POSITION IN FILE */ #undef AX_EQ_B_QR #undef AX_EQ_B_QRLS #undef AX_EQ_B_CHOL #undef AX_EQ_B_LU #undef AX_EQ_B_SVD #undef AX_EQ_B_BK #undef AX_EQ_B_PLASMA_CHOL #undef GEQRF #undef ORGQR #undef TRTRS #undef POTF2 #undef POTRF #undef POTRS #undef GETRF #undef GETRS #undef GESVD #undef GESDD #undef SYTRF #undef SYTRS #undef PLASMA_POSV #else // no LAPACK /* precision-specific definitions */ #define AX_EQ_B_LU LM_ADD_PREFIX(Ax_eq_b_LU_noLapack) /* * This function returns the solution of Ax = b * * The function employs LU decomposition followed by forward/back substitution (see * also the LAPACK-based LU solver above) * * A is mxm, b is mx1 * * The function returns 0 in case of error, 1 if successful * * This function is often called repetitively to solve problems of identical * dimensions. To avoid repetitive malloc's and free's, allocated memory is * retained between calls and free'd-malloc'ed when not of the appropriate size. * A call with NULL as the first argument forces this memory to be released. */ int AX_EQ_B_LU(LM_REAL *A, LM_REAL *B, LM_REAL *x, int m) { __STATIC__ void *buf=NULL; __STATIC__ int buf_sz=0; register int i, j, k; int *idx, maxi=-1, idx_sz, a_sz, work_sz, tot_sz; LM_REAL *a, *work, max, sum, tmp; if(!A) #ifdef LINSOLVERS_RETAIN_MEMORY { if(buf) free(buf); buf=NULL; buf_sz=0; return 1; } #else return 1; /* NOP */ #endif /* LINSOLVERS_RETAIN_MEMORY */ /* calculate required memory size */ idx_sz=m; a_sz=m*m; work_sz=m; tot_sz=(a_sz+work_sz)*sizeof(LM_REAL) + idx_sz*sizeof(int); /* should be arranged in that order for proper doubles alignment */ #ifdef LINSOLVERS_RETAIN_MEMORY if(tot_sz>buf_sz){ /* insufficient memory, allocate a "big" memory chunk at once */ if(buf) free(buf); /* free previously allocated memory */ buf_sz=tot_sz; buf=(void *)malloc(tot_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n"); exit(1); } } #else buf_sz=tot_sz; buf=(void *)malloc(tot_sz); if(!buf){ fprintf(stderr, RCAT("memory allocation in ", AX_EQ_B_LU) "() failed!\n"); exit(1); } #endif /* LINSOLVERS_RETAIN_MEMORY */ a=buf; work=a+a_sz; idx=(int *)(work+work_sz); /* avoid destroying A, B by copying them to a, x resp. */ memcpy(a, A, a_sz*sizeof(LM_REAL)); memcpy(x, B, m*sizeof(LM_REAL)); /* compute the LU decomposition of a row permutation of matrix a; the permutation itself is saved in idx[] */ for(i=0; imax) max=tmp; if(max==0.0){ fprintf(stderr, RCAT("Singular matrix A in ", AX_EQ_B_LU) "()!\n"); #ifndef LINSOLVERS_RETAIN_MEMORY free(buf); #endif return 0; } work[i]=LM_CNST(1.0)/max; } for(j=0; j=max){ max=tmp; maxi=i; } } if(j!=maxi){ for(k=0; k=0; --i){ sum=x[i]; for(j=i+1; j #include #include #include #include "levmar.h" #include "misc.h" #if !defined(LM_DBL_PREC) && !defined(LM_SNGL_PREC) #error At least one of LM_DBL_PREC, LM_SNGL_PREC should be defined! #endif #ifdef LM_SNGL_PREC /* single precision (float) definitions */ #define LM_REAL float #define LM_PREFIX s #define LM_REAL_EPSILON FLT_EPSILON #define __SUBCNST(x) x##F #define LM_CNST(x) __SUBCNST(x) // force substitution #include "misc_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef LM_REAL_EPSILON #undef __SUBCNST #undef LM_CNST #endif /* LM_SNGL_PREC */ #ifdef LM_DBL_PREC /* double precision definitions */ #define LM_REAL double #define LM_PREFIX d #define LM_REAL_EPSILON DBL_EPSILON #define LM_CNST(x) (x) #include "misc_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef LM_REAL_EPSILON #undef LM_CNST #endif /* LM_DBL_PREC */ stimfit-0.16.7/src/libstfnum/levmar/lm.c0000664000175000017500000000465214750344764013630 ///////////////////////////////////////////////////////////////////////////////// // // Levenberg - Marquardt non-linear minimization algorithm // Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// /******************************************************************************** * Levenberg-Marquardt nonlinear minimization. The same core code is used with * appropriate #defines to derive single and double precision versions, see * also lm_core.c ********************************************************************************/ #include #include #include #include #include "levmar.h" #include "compiler.h" #include "misc.h" #define EPSILON 1E-12 #define ONE_THIRD 0.3333333334 /* 1.0/3.0 */ #if !defined(LM_DBL_PREC) && !defined(LM_SNGL_PREC) #error At least one of LM_DBL_PREC, LM_SNGL_PREC should be defined! #endif #ifdef LM_SNGL_PREC /* single precision (float) definitions */ #define LM_REAL float #define LM_PREFIX s #define LM_REAL_MAX FLT_MAX #define LM_REAL_MIN -FLT_MAX #define LM_REAL_EPSILON FLT_EPSILON #define __SUBCNST(x) x##F #define LM_CNST(x) __SUBCNST(x) // force substitution #include "lm_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef LM_REAL_MAX #undef LM_REAL_EPSILON #undef LM_REAL_MIN #undef __SUBCNST #undef LM_CNST #endif /* LM_SNGL_PREC */ #ifdef LM_DBL_PREC /* double precision definitions */ #define LM_REAL double #define LM_PREFIX d #define LM_REAL_MAX DBL_MAX #define LM_REAL_MIN -DBL_MAX #define LM_REAL_EPSILON DBL_EPSILON #define LM_CNST(x) (x) #include "lm_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef LM_REAL_MAX #undef LM_REAL_EPSILON #undef LM_REAL_MIN #undef LM_CNST #endif /* LM_DBL_PREC */ stimfit-0.16.7/src/libstfnum/levmar/lmbc.c0000664000175000017500000000503714750344764014133 ///////////////////////////////////////////////////////////////////////////////// // // Levenberg - Marquardt non-linear minimization algorithm // Copyright (C) 2004-05 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// /******************************************************************************** * Box-constrained Levenberg-Marquardt nonlinear minimization. The same core code * is used with appropriate #defines to derive single and double precision versions, * see also lmbc_core.c ********************************************************************************/ #include #include #include #include #include "levmar.h" #include "compiler.h" #include "misc.h" #define EPSILON 1E-12 #define ONE_THIRD 0.3333333334 /* 1.0/3.0 */ #define _LSITMAX_ 150 /* max #iterations for line search */ #define _POW_ 2.1 #if !defined(LM_DBL_PREC) && !defined(LM_SNGL_PREC) #error At least one of LM_DBL_PREC, LM_SNGL_PREC should be defined! #endif #ifdef LM_SNGL_PREC /* single precision (float) definitions */ #define LM_REAL float #define LM_PREFIX s #define LM_REAL_MAX FLT_MAX #define LM_REAL_MIN -FLT_MAX #define LM_REAL_EPSILON FLT_EPSILON #define __SUBCNST(x) x##F #define LM_CNST(x) __SUBCNST(x) // force substitution #include "lmbc_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef LM_REAL_MAX #undef LM_REAL_MIN #undef LM_REAL_EPSILON #undef __SUBCNST #undef LM_CNST #endif /* LM_SNGL_PREC */ #ifdef LM_DBL_PREC /* double precision definitions */ #define LM_REAL double #define LM_PREFIX d #define LM_REAL_MAX DBL_MAX #define LM_REAL_MIN -DBL_MAX #define LM_REAL_EPSILON DBL_EPSILON #define LM_CNST(x) (x) #include "lmbc_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef LM_REAL_MAX #undef LM_REAL_MIN #undef LM_REAL_EPSILON #undef LM_CNST #endif /* LM_DBL_PREC */ stimfit-0.16.7/src/libstfnum/levmar/lmlec.c0000664000175000017500000000450014750344764014304 ///////////////////////////////////////////////////////////////////////////////// // // Levenberg - Marquardt non-linear minimization algorithm // Copyright (C) 2004-05 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // ///////////////////////////////////////////////////////////////////////////////// /******************************************************************************* * Wrappers for linearly constrained Levenberg-Marquardt minimization. The same * core code is used with appropriate #defines to derive single and double * precision versions, see also lmlec_core.c *******************************************************************************/ #include #include #include #include "levmar.h" #include "misc.h" #ifndef HAVE_LAPACK #ifdef _MSC_VER #pragma message("Linearly constrained optimization requires LAPACK and was not compiled!") #else #warning Linearly constrained optimization requires LAPACK and was not compiled! #endif // _MSC_VER #else // LAPACK present #if !defined(LM_DBL_PREC) && !defined(LM_SNGL_PREC) #error At least one of LM_DBL_PREC, LM_SNGL_PREC should be defined! #endif #ifdef LM_SNGL_PREC /* single precision (float) definitions */ #define LM_REAL float #define LM_PREFIX s #define __SUBCNST(x) x##F #define LM_CNST(x) __SUBCNST(x) // force substitution #include "lmlec_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef __SUBCNST #undef LM_CNST #endif /* LM_SNGL_PREC */ #ifdef LM_DBL_PREC /* double precision definitions */ #define LM_REAL double #define LM_PREFIX d #define LM_CNST(x) (x) #include "lmlec_core.c" // read in core code #undef LM_REAL #undef LM_PREFIX #undef LM_CNST #endif /* LM_DBL_PREC */ #endif /* HAVE_LAPACK */ stimfit-0.16.7/src/libstfnum/levmar/levmar.h0000664000175000017500000004472514750344764014520 /* //////////////////////////////////////////////////////////////////////////////////// // // Prototypes and definitions for the Levenberg - Marquardt minimization algorithm // Copyright (C) 2004 Manolis Lourakis (lourakis at ics forth gr) // Institute of Computer Science, Foundation for Research & Technology - Hellas // Heraklion, Crete, Greece. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //////////////////////////////////////////////////////////////////////////////////// */ #ifndef _LEVMAR_H_ #define _LEVMAR_H_ /************************************* Start of configuration options *************************************/ /* Note that when compiling with CMake, this configuration section is automatically generated * based on the user's input, see levmar.h.in */ /* specifies whether to use LAPACK or not. Using LAPACK is strongly recommended */ #ifndef HAVE_LAPACK #define HAVE_LAPACK #endif /* specifies whether the PLASMA parallel library for multicore CPUs is available */ /* #undef HAVE_PLASMA */ /* to avoid the overhead of repeated mallocs(), routines in Axb.c can be instructed to * retain working memory between calls. Such a choice, however, renders these routines * non-reentrant and is not safe in a shared memory multiprocessing environment. * Bellow, an attempt is made to issue a warning if this option is turned on and OpenMP * is being used (note that this will work only if omp.h is included before levmar.h) */ #define LINSOLVERS_RETAIN_MEMORY #if (defined(_OPENMP)) # ifdef LINSOLVERS_RETAIN_MEMORY # ifdef _MSC_VER # pragma message("LINSOLVERS_RETAIN_MEMORY is not safe in a multithreaded environment and should be turned off!") # else # warning LINSOLVERS_RETAIN_MEMORY is not safe in a multithreaded environment and should be turned off! # endif /* _MSC_VER */ # endif /* LINSOLVERS_RETAIN_MEMORY */ #endif /* _OPENMP */ /* specifies whether double precision routines will be compiled or not */ #define LM_DBL_PREC /* specifies whether single precision routines will be compiled or not */ #define LM_SNGL_PREC /****************** End of configuration options, no changes necessary beyond this point ******************/ #ifdef __cplusplus extern "C" { #endif /* work arrays size for ?levmar_der and ?levmar_dif functions. * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes */ #define LM_DER_WORKSZ(npar, nmeas) (2*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar)) #define LM_DIF_WORKSZ(npar, nmeas) (4*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar)) /* work arrays size for ?levmar_bc_der and ?levmar_bc_dif functions. * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes */ #define LM_BC_DER_WORKSZ(npar, nmeas) (2*(nmeas) + 4*(npar) + (nmeas)*(npar) + (npar)*(npar)) #define LM_BC_DIF_WORKSZ(npar, nmeas) LM_BC_DER_WORKSZ((npar), (nmeas)) /* LEVMAR_BC_DIF currently implemented using LEVMAR_BC_DER()! */ /* work arrays size for ?levmar_lec_der and ?levmar_lec_dif functions. * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes */ #define LM_LEC_DER_WORKSZ(npar, nmeas, nconstr) LM_DER_WORKSZ((npar)-(nconstr), (nmeas)) #define LM_LEC_DIF_WORKSZ(npar, nmeas, nconstr) LM_DIF_WORKSZ((npar)-(nconstr), (nmeas)) /* work arrays size for ?levmar_blec_der and ?levmar_blec_dif functions. * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes */ #define LM_BLEC_DER_WORKSZ(npar, nmeas, nconstr) LM_LEC_DER_WORKSZ((npar), (nmeas)+(npar), (nconstr)) #define LM_BLEC_DIF_WORKSZ(npar, nmeas, nconstr) LM_LEC_DIF_WORKSZ((npar), (nmeas)+(npar), (nconstr)) /* work arrays size for ?levmar_bleic_der and ?levmar_bleic_dif functions. * should be multiplied by sizeof(double) or sizeof(float) to be converted to bytes */ #define LM_BLEIC_DER_WORKSZ(npar, nmeas, nconstr1, nconstr2) LM_BLEC_DER_WORKSZ((npar)+(nconstr2), (nmeas)+(nconstr2), (nconstr1)+(nconstr2)) #define LM_BLEIC_DIF_WORKSZ(npar, nmeas, nconstr1, nconstr2) LM_BLEC_DIF_WORKSZ((npar)+(nconstr2), (nmeas)+(nconstr2), (nconstr1)+(nconstr2)) #define LM_OPTS_SZ 5 /* max(4, 5) */ #define LM_INFO_SZ 10 #define LM_ERROR -1 #define LM_INIT_MU 1E-03 #define LM_STOP_THRESH 1E-17 #define LM_DIFF_DELTA 1E-06 #define LM_VERSION "2.6 (November 2011)" #ifdef LM_DBL_PREC /* double precision LM, with & without Jacobian */ /* unconstrained minimization */ extern int dlevmar_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, int itmax, double *opts, double *info, double *work, double *covar, void *adata); /* box-constrained minimization */ extern int dlevmar_bc_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *dscl, int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_bc_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *dscl, int itmax, double *opts, double *info, double *work, double *covar, void *adata); #ifdef HAVE_LAPACK /* linear equation constrained minimization */ extern int dlevmar_lec_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *A, double *b, int k, int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_lec_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *A, double *b, int k, int itmax, double *opts, double *info, double *work, double *covar, void *adata); /* box & linear equation constrained minimization */ extern int dlevmar_blec_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts, int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_blec_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts, int itmax, double *opts, double *info, double *work, double *covar, void *adata); /* box, linear equations & inequalities constrained minimization */ extern int dlevmar_bleic_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k1, double *C, double *d, int k2, int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_bleic_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k1, double *C, double *d, int k2, int itmax, double *opts, double *info, double *work, double *covar, void *adata); /* box & linear inequality constraints */ extern int dlevmar_blic_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *C, double *d, int k2, int itmax, double opts[4], double info[LM_INFO_SZ], double *work, double *covar, void *adata); extern int dlevmar_blic_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *lb, double *ub, double *C, double *d, int k2, int itmax, double opts[5], double info[LM_INFO_SZ], double *work, double *covar, void *adata); /* linear equation & inequality constraints */ extern int dlevmar_leic_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *A, double *b, int k1, double *C, double *d, int k2, int itmax, double opts[4], double info[LM_INFO_SZ], double *work, double *covar, void *adata); extern int dlevmar_leic_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *A, double *b, int k1, double *C, double *d, int k2, int itmax, double opts[5], double info[LM_INFO_SZ], double *work, double *covar, void *adata); /* linear inequality constraints */ extern int dlevmar_lic_der( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, double *x, int m, int n, double *C, double *d, int k2, int itmax, double opts[4], double info[LM_INFO_SZ], double *work, double *covar, void *adata); extern int dlevmar_lic_dif( void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, double *C, double *d, int k2, int itmax, double opts[5], double info[LM_INFO_SZ], double *work, double *covar, void *adata); #endif /* HAVE_LAPACK */ #endif /* LM_DBL_PREC */ #ifdef LM_SNGL_PREC /* single precision LM, with & without Jacobian */ /* unconstrained minimization */ extern int slevmar_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, int itmax, float *opts, float *info, float *work, float *covar, void *adata); extern int slevmar_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, int itmax, float *opts, float *info, float *work, float *covar, void *adata); /* box-constrained minimization */ extern int slevmar_bc_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *dscl, int itmax, float *opts, float *info, float *work, float *covar, void *adata); extern int slevmar_bc_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *dscl, int itmax, float *opts, float *info, float *work, float *covar, void *adata); #ifdef HAVE_LAPACK /* linear equation constrained minimization */ extern int slevmar_lec_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, float *A, float *b, int k, int itmax, float *opts, float *info, float *work, float *covar, void *adata); extern int slevmar_lec_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, float *A, float *b, int k, int itmax, float *opts, float *info, float *work, float *covar, void *adata); /* box & linear equation constrained minimization */ extern int slevmar_blec_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *A, float *b, int k, float *wghts, int itmax, float *opts, float *info, float *work, float *covar, void *adata); extern int slevmar_blec_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *A, float *b, int k, float *wghts, int itmax, float *opts, float *info, float *work, float *covar, void *adata); /* box, linear equations & inequalities constrained minimization */ extern int slevmar_bleic_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *A, float *b, int k1, float *C, float *d, int k2, int itmax, float *opts, float *info, float *work, float *covar, void *adata); extern int slevmar_bleic_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *A, float *b, int k1, float *C, float *d, int k2, int itmax, float *opts, float *info, float *work, float *covar, void *adata); /* box & linear inequality constraints */ extern int slevmar_blic_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *C, float *d, int k2, int itmax, float opts[4], float info[LM_INFO_SZ], float *work, float *covar, void *adata); extern int slevmar_blic_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, float *lb, float *ub, float *C, float *d, int k2, int itmax, float opts[5], float info[LM_INFO_SZ], float *work, float *covar, void *adata); /* linear equality & inequality constraints */ extern int slevmar_leic_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, float *A, float *b, int k1, float *C, float *d, int k2, int itmax, float opts[4], float info[LM_INFO_SZ], float *work, float *covar, void *adata); extern int slevmar_leic_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, float *A, float *b, int k1, float *C, float *d, int k2, int itmax, float opts[5], float info[LM_INFO_SZ], float *work, float *covar, void *adata); /* linear inequality constraints */ extern int slevmar_lic_der( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, float *x, int m, int n, float *C, float *d, int k2, int itmax, float opts[4], float info[LM_INFO_SZ], float *work, float *covar, void *adata); extern int slevmar_lic_dif( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, float *C, float *d, int k2, int itmax, float opts[5], float info[LM_INFO_SZ], float *work, float *covar, void *adata); #endif /* HAVE_LAPACK */ #endif /* LM_SNGL_PREC */ /* linear system solvers */ #ifdef HAVE_LAPACK #ifdef LM_DBL_PREC extern int dAx_eq_b_QR(double *A, double *B, double *x, int m); extern int dAx_eq_b_QRLS(double *A, double *B, double *x, int m, int n); extern int dAx_eq_b_Chol(double *A, double *B, double *x, int m); extern int dAx_eq_b_LU(double *A, double *B, double *x, int m); extern int dAx_eq_b_SVD(double *A, double *B, double *x, int m); extern int dAx_eq_b_BK(double *A, double *B, double *x, int m); #endif /* LM_DBL_PREC */ #ifdef LM_SNGL_PREC extern int sAx_eq_b_QR(float *A, float *B, float *x, int m); extern int sAx_eq_b_QRLS(float *A, float *B, float *x, int m, int n); extern int sAx_eq_b_Chol(float *A, float *B, float *x, int m); extern int sAx_eq_b_LU(float *A, float *B, float *x, int m); extern int sAx_eq_b_SVD(float *A, float *B, float *x, int m); extern int sAx_eq_b_BK(float *A, float *B, float *x, int m); #endif /* LM_SNGL_PREC */ #else /* no LAPACK */ #ifdef LM_DBL_PREC extern int dAx_eq_b_LU_noLapack(double *A, double *B, double *x, int n); #endif /* LM_DBL_PREC */ #ifdef LM_SNGL_PREC extern int sAx_eq_b_LU_noLapack(float *A, float *B, float *x, int n); #endif /* LM_SNGL_PREC */ #endif /* HAVE_LAPACK */ #ifdef HAVE_PLASMA #ifdef LM_DBL_PREC extern int dAx_eq_b_PLASMA_Chol(double *A, double *B, double *x, int m); #endif #ifdef LM_SNGL_PREC extern int sAx_eq_b_PLASMA_Chol(float *A, float *B, float *x, int m); #endif extern void levmar_PLASMA_setnbcores(int cores); #endif /* HAVE_PLASMA */ /* Jacobian verification, double & single precision */ #ifdef LM_DBL_PREC extern void dlevmar_chkjac( void (*func)(double *p, double *hx, int m, int n, void *adata), void (*jacf)(double *p, double *j, int m, int n, void *adata), double *p, int m, int n, void *adata, double *err); #endif /* LM_DBL_PREC */ #ifdef LM_SNGL_PREC extern void slevmar_chkjac( void (*func)(float *p, float *hx, int m, int n, void *adata), void (*jacf)(float *p, float *j, int m, int n, void *adata), float *p, int m, int n, void *adata, float *err); #endif /* LM_SNGL_PREC */ /* miscellaneous: standard deviation, coefficient of determination (R2), * Pearson's correlation coefficient for best-fit parameters */ #ifdef LM_DBL_PREC extern double dlevmar_stddev( double *covar, int m, int i); extern double dlevmar_corcoef(double *covar, int m, int i, int j); extern double dlevmar_R2(void (*func)(double *p, double *hx, int m, int n, void *adata), double *p, double *x, int m, int n, void *adata); #endif /* LM_DBL_PREC */ #ifdef LM_SNGL_PREC extern float slevmar_stddev( float *covar, int m, int i); extern float slevmar_corcoef(float *covar, int m, int i, int j); extern float slevmar_R2(void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, void *adata); extern void slevmar_locscale( void (*func)(float *p, float *hx, int m, int n, void *adata), float *p, float *x, int m, int n, void *adata, int howto, float locscl[2], float **residptr); extern int slevmar_outlid(float *r, int n, float thresh, float ls[2], char *outlmap); #endif /* LM_SNGL_PREC */ #ifdef __cplusplus } #endif #endif /* _LEVMAR_H_ */ stimfit-0.16.7/src/Makefile.am0000775000175000017500000000041214752207205011576 if WITH_BIOSIGLITE SUBDIRS = libbiosiglite else SUBDIRS = endif # The order is important here because libstimfit.la will be used by stfswig. if BUILD_MODULE SUBDIRS += libstfio libstfnum pystfio else SUBDIRS += libstfio libstfnum stimfit stimfit/py endif stimfit-0.16.7/src/Makefile.in0000664000175000017500000004767614764352410011635 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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@ 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@ # The order is important here because libstimfit.la will be used by stfswig. @BUILD_MODULE_TRUE@am__append_1 = libstfio libstfnum pystfio @BUILD_MODULE_FALSE@am__append_2 = libstfio libstfnum stimfit stimfit/py subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acsite.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/stfconf.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = 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 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # 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)` DIST_SUBDIRS = libstfio libstfnum pystfio stimfit stimfit/py \ libbiosiglite am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ GT_CPPFLAGS = @GT_CPPFLAGS@ GT_CXXFLAGS = @GT_CXXFLAGS@ GT_LDFLAGS = @GT_LDFLAGS@ GT_LIBS = @GT_LIBS@ HDF5_CFLAGS = @HDF5_CFLAGS@ HDF5_LIBS = @HDF5_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBIOSIG_LDFLAGS = @LIBBIOSIG_LDFLAGS@ LIBHDF5_LDFLAGS = @LIBHDF5_LDFLAGS@ LIBLAPACK_LDFLAGS = @LIBLAPACK_LDFLAGS@ LIBNUMPY_INCLUDES = @LIBNUMPY_INCLUDES@ LIBOBJS = @LIBOBJS@ LIBPYTHON_INCLUDES = @LIBPYTHON_INCLUDES@ LIBPYTHON_LDFLAGS = @LIBPYTHON_LDFLAGS@ LIBS = @LIBS@ LIBSTF_LDFLAGS = @LIBSTF_LDFLAGS@ LIBTOOL = @LIBTOOL@ LIBWXPYTHON_INCLUDES = @LIBWXPYTHON_INCLUDES@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MACSETFILE = @MACSETFILE@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ 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@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSTLINK_COMMAND = @POSTLINK_COMMAND@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIST_PKG = @PYTHON_DIST_PKG@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ PYTHON_NUMPY_INCLUDE = @PYTHON_NUMPY_INCLUDE@ PYTHON_PRE_DIST_PKG = @PYTHON_PRE_DIST_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ PYTHON_WXPYTHON_INCLUDE = @PYTHON_WXPYTHON_INCLUDE@ PY_AC_VERSION = @PY_AC_VERSION@ RANLIB = @RANLIB@ REZ = @REZ@ SED = @SED@ SETFILE = @SETFILE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STFIO_PYTHON_LIBNAME = @STFIO_PYTHON_LIBNAME@ STF_PYTHON_LIBNAME = @STF_PYTHON_LIBNAME@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ VERSION = @VERSION@ WX_CPPFLAGS = @WX_CPPFLAGS@ WX_CXXFLAGS = @WX_CXXFLAGS@ WX_LIBS = @WX_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ 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@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ 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@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @WITH_BIOSIGLITE_FALSE@SUBDIRS = $(am__append_1) $(am__append_2) @WITH_BIOSIGLITE_TRUE@SUBDIRS = libbiosiglite $(am__append_1) \ @WITH_BIOSIGLITE_TRUE@ $(am__append_2) all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(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-recursive 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" cscopelist: cscopelist-recursive 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 distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @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 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive 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-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir 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 installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # 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: stimfit-0.16.7/src/pystfio/0000775000175000017500000000000014764352501011322 5stimfit-0.16.7/src/pystfio/unittest_stfio.py0000664000175000017500000000715414750344764014715 """ unittest_stfio.py Tue, 20 Jul 2010 09:38:19 +0200 The unittest for stfio module created by Christoph, the stfio module is a Stimfit-independent python module to read/write electrophysiological data from/to different file formats. Note that to execute this test you need the following files: test.h5 test.abf test.dat These files correspond to the same recording with different file extensions; the recording contains the following properties: Number of channels = 4 Number of traces = 3 Sampling interval = 0.05 """ import numpy as np import unittest import stfio rec = stfio.read('test.h5') class DataListTest(unittest.TestCase): def testReadH5(self): """ testReadH5() Read HDF5 file system """ try: rec = stfio.read('test.h5') except SyntaxError: rec = None # test if Recording object was created self.assertTrue(True, isinstance(rec, stfio.Recording)) # def testReadCFS(self): # """ testReadCFS() Read CED filling system files""" # try: # rec = stfio.read('test.dat') # except SyntaxError: # rec = None # # test if Recording object was created # self.assertTrue(True, isinstance(rec, stfio.Recording)) # def testReadATF(self): # """ testReadATF() Read ABF files""" # try: # rec = stfio.read('test.atf') # except SyntaxError: # rec = None # # test if Recording object was created # self.assertTrue(True, isinstance(rec, stfio.Recording)) def testReadStfException(self): """ Raises a StfException if file format to read is not supported""" # should raise an StfIOException if filetype is not supported self.assertRaises(stfio.StfIOException, stfio.read, 'test.txt') def testWrite(self): """ testWrite() Returns False if file format to write is not supported""" # should raise an StfException if filetype is not supported rec = stfio.read('test.h5') res = rec.write('new.abf', 'abf') self.assertEquals(False, res) def testNumberofChannels(self): """ testNumberofChannels() returns the number of channels """ self.assertEquals(4,len(rec)) def testNumberofSections(self): """ testNumberofSections() returns the number of channels """ self.assertEquals(3,len(rec[0])) def testNumberofDataPoints(self): """ testNumberofDataPoints() returns the number of sampling points """ self.assertEquals(40000,len(rec[0][0])) def testunits(self): """ testunits() returns the units in the X/Y axis """ self.assertEquals('mV',rec[0].yunits) self.assertEquals('pA',rec[1].yunits) self.assertEquals('ms',rec.xunits) def testArrayCreation(self): """ testArrayCreation() creation of a numpy array""" self.assertTrue(type(rec[0][0].asarray()), type(np.empty(0))) def testChannelName(self): """ testChannelName() returns the names of the channels """ names = [rec[i].name for i in range(len(rec))] mynames = ['Amp1', 'Amp2', 'Amp3', 'Amp4'] self.assertEquals(names, mynames) def testSamplingRate(self): """ testSamplingRate() returns the sampling rate """ self.assertAlmostEqual(0.05, rec.dt, 3) def testDate(self): """ testDate() returns the creation date """ self.assertEquals(rec.date, '19/07/10') def testTime(self): """ testTime() returns the creation time """ self.assertEquals(rec.time, '23:24:42') if __name__ == '__main__': # test all cases unittest.main() stimfit-0.16.7/src/pystfio/pystfio.h0000775000175000017500000000175414752207205013117 #ifndef _PYSTFIO_H #define _PYSTFIO_H #include "../libstfio/stfio.h" #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #endif #include #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #define array_data(a) PyArray_DATA((PyArrayObject*)a) #if PY_MAJOR_VERSION >= 3 int #else void #endif wrap_array(); stfio::filetype gettype(const std::string& ftype); bool _read(const std::string& filename, const std::string& ftype, bool verbose, Recording& Data); PyObject* detect_events(double* data, int size_data, double* templ, int size_templ, double dt, const std::string& mode="criterion", bool norm=true, double lowpass=0.5, double highpass=0.0001); PyObject* peak_detection(double* invec, int size, double threshold, int min_distance); double risetime(double* invec, int size, double base, double amp, double frac=0.2); #endif stimfit-0.16.7/src/pystfio/stfio_plot.py0000664000175000017500000005430714750344764014016 """ Some plotting utilities to use scale bars rather than coordinate axes. 04 Feb 2011, C. Schmidt-Hieber, University College London From the stfio module: http://code.google.com/p/stimfit """ # TODO: Pin scale bars to their position # TODO: Implement 2-channel plots import os import sys import numpy as np import numpy.ma as ma HAS_MPL = True try: import matplotlib import matplotlib.pyplot as plt if (float(matplotlib.__version__[0:3]) > 2.1): from mpl_toolkits.axisartist import Subplot else: from mpl_toolkits.axes_grid.axislines import Subplot except ImportError as err: HAS_MPL = False MPL_ERR = err # dummy class class Subplot(object): pass scale_dist_x = 0.04 scale_dist_y = 0.04 graph_width = 6.0 graph_height = 4.0 key_dist = 0.04 def save_ma(ftrunk, marr): if not isinstance(marr, ma.core.MaskedArray): marr = ma.array(marr, mask=False) data = np.array(marr) mask = np.array(marr.mask) np.save(ftrunk + ".data.npy", data) np.save(ftrunk + ".mask.npy", mask) def load_ma(ftrunk): data = np.load(ftrunk + ".data.npy") mask = np.load(ftrunk + ".mask.npy") return ma.array(data, mask=mask) class Timeseries(object): # it this is 2d, the second axis (shape[1]) is time def __init__(self, *args, **kwargs): if len(args) > 2: raise RuntimeError( "Timeseries accepts at most two non-keyworded arguments") fromFile = False # First argument has to be either data or file_trunk if isinstance(args[0], str): if len(args) > 1: raise RuntimeError( "Timeseries accepts only one non-keyworded " "argument if instantiated from file") if os.path.exists("%s_data.npy" % args[0]): self.data = np.load("%s_data.npy" % args[0]) else: self.data = load_ma("%s_data.npy" % args[0]) self.dt = np.load("%s_dt.npy" % args[0]) fxu = open("%s_xunits" % args[0], 'r') self.xunits = fxu.read() fxu.close() fyu = open("%s_yunits" % args[0], 'r') self.yunits = fyu.read() fyu.close() fromFile = True else: self.data = args[0] self.dt = args[1] if len(kwargs) > 0 and fromFile: raise RuntimeError( "Can't set keyword arguments if Timeseries was " "instantiated from file") for key in kwargs: if key == "xunits": self.xunits = kwargs["xunits"] elif key == "yunits": self.yunits = kwargs["yunits"] elif key == "linestyle": self.linestyle = kwargs["linestyle"] elif key == "linewidth": self.linewidth = kwargs["linewidth"] elif key == "color": self.color = kwargs["color"] elif key == "colour": self.color = kwargs["colour"] else: raise RuntimeError("Unknown keyword argument: " + key) if "xunits" not in kwargs and not fromFile: self.xunits = "ms" if "yunits" not in kwargs and not fromFile: self.yunits = "mV" if "linestyle" not in kwargs: self.linestyle = "-" if "linewidth" not in kwargs: self.linewidth = 1.0 if "color" not in kwargs and "colour" not in kwargs: self.color = 'k' def __getitem__(self, idx): return self.data[idx] def __setitem__(self, idx, value): self.data[idx] = value def __add__(self, other): if isinstance(other, Timeseries): result = self.data + other.data else: result = self.data + other return self.copy_attributes(result) def __mul__(self, other): if isinstance(other, Timeseries): result = self.data * other.data else: result = self.data * other return self.copy_attributes(result) def __sub__(self, other): if isinstance(other, Timeseries): result = self.data - other.data else: result = self.data - other return self.copy_attributes(result) def __div__(self, other): if isinstance(other, Timeseries): result = self.data / other.data else: result = self.data / other return self.copy_attributes(result) def __truediv__(self, other): return self.__div__(other) def copy_attributes(self, data): return Timeseries( data, self.dt, xunits=self.xunits, yunits=self.yunits, linestyle=self.linestyle, linewidth=self.linewidth, color=self.color) def x_trange(self, tstart, tend): return np.arange(int(tstart/self.dt), int(tend/self.dt), 1.0, dtype=np.float) * self.dt def y_trange(self, tstart, tend): return self.data[int(tstart/self.dt):int(tend/self.dt)] def timearray(self): return np.arange(0.0, self.data.shape[-1]) * self.dt def duration(self): return self.data.shape[-1] * self.dt def interpolate(self, newtime, newdt): if len(self.data.shape) == 1: return Timeseries(np.interp(newtime, self.timearray(), self.data, left=np.nan, right=np.nan), newdt) else: # interpolate each row individually: # iparray = ma.zeros((self.data.shape[0], len(newtime))) # for nrow, row in enumerate(self.data): # flin = \ # interpolate.interp1d( # self.timearray(), row, # bounds_error=False, fill_value=np.nan, kind=kind) # iparray[nrow,:]=flin(newtime) iparray = ma.array([ np.interp( newtime, self.timearray(), row, left=np.nan, right=np.nan) for nrow, row in enumerate(self.data)]) return Timeseries(iparray, newdt) def maskedarray(self, center, left, right): # check whether we have enough data left and right: if len(self.data.shape) > 1: mask = \ np.zeros((self.data.shape[0], int((right+left)/self.dt))) maskedarray = \ ma.zeros((self.data.shape[0], int((right+left)/self.dt))) else: mask = np.zeros((int((right+left)/self.dt))) maskedarray = ma.zeros((int((right+left)/self.dt))) offset = 0 if center - left < 0: if len(self.data.shape) > 1: mask[:, :int((left-center)/self.dt)] = 1 else: mask[:int((left-center)/self.dt)] = 1 leftindex = 0 offset = int((left-center)/self.dt) else: leftindex = int((center-left)/self.dt) if center + right >= len(self.data) * self.dt: endtime = len(self.data) * self.dt if len(self.data.shape) > 1: mask[:, -int((center+right-endtime)/self.dt):] = 1 else: mask[-int((center+right-endtime)/self.dt):] = 1 rightindex = int(endtime/self.dt) else: rightindex = int((center+right)/self.dt) for timest in range(leftindex, rightindex): if len(self.data.shape) > 1: if timest-leftindex+offset < maskedarray.shape[1] and \ timest < self.data.shape[1]: maskedarray[:, timest-leftindex+offset] = \ self.data[:, timest] else: if timest-leftindex+offset < len(maskedarray): maskedarray[timest-leftindex+offset] = \ self.data[timest] maskedarray.mask = ma.make_mask(mask) return Timeseries(maskedarray, self.dt) def save(self, file_trunk): if isinstance(self.data, ma.MaskedArray): save_ma("%s_data.npy" % file_trunk, self.data) else: np.save("%s_data.npy" % file_trunk, self.data) np.save("%s_dt.npy" % file_trunk, self.dt) fxu = open("%s_xunits" % file_trunk, 'w') fxu.write(self.xunits) fxu.close() fyu = open("%s_yunits" % file_trunk, 'w') fyu.write(self.yunits) fyu.close() def plot(self): fig = plt.figure(figsize=(8, 6)) ax = StandardAxis(fig, 111, hasx=True) ax.plot(self.timearray(), self.data, '-k') class timeseries(Timeseries): def __init__(self, *args, **kwargs): super(timeseries, self).__init__(*args, **kwargs) sys.stderr.write("stfio_plot.timeseries is deprecated. " "Use stfio_plot.Timeseries instead.\n") class StandardAxis(Subplot): def __init__(self, *args, **kwargs): if not HAS_MPL: raise MPL_ERR hasx = kwargs.pop('hasx', False) hasy = kwargs.pop('hasy', True) kwargs['frameon'] = False super(StandardAxis, self).__init__(*args, **kwargs) args[0].add_axes(self) self.axis["right"].set_visible(False) self.axis["top"].set_visible(False) if not hasx: self.axis["bottom"].set_visible(False) if not hasy: self.axis["left"].set_visible(False) def average(tsl): # find fastest dt: dt_common = 1e12 for ts in tsl: if ts.dt < dt_common: newtime = ts.timearray() dt_common = ts.dt # interpolate all series to new dt: tslip = [ts.interpolate(newtime, dt_common) for ts in tsl] if len(tslip[0].data.shape) == 1: ave = np.empty((len(tslip), len(tslip[0].data))) else: ave = np.empty( (len(tslip), tslip[0].data.shape[0], tslip[0].data.shape[1])) for its, ts in enumerate(tslip): if len(ts.data.shape) == 1: ave[its] = ts.data else: ave[its, :, :] = ts.data[:, :] if len(ts.data.shape) == 1: return Timeseries(ma.mean(ave, axis=0), dt_common) else: avef = ma.zeros((tslip[0].data.shape[0], tslip[0].data.shape[1])) for nrow, row in enumerate(avef): avef[nrow, :] = ma.mean(ave[:, nrow, :], axis=0) return Timeseries(avef, dt_common) def prettyNumber(f): fScaled = f if fScaled < 1: correct = 10.0 else: correct = 1.0 # set stepsize try: nZeros = int(np.log10(fScaled)) except OverflowError: nZeros = 0 prev10e = 10.0**nZeros / correct next10e = prev10e * 10 if fScaled / prev10e > 7.5: return next10e elif fScaled / prev10e > 5.0: return 5 * prev10e else: return round(fScaled/prev10e) * prev10e def plot_scalebars(ax, div=3.0, labels=True, xunits="", yunits="", nox=False, sb_xoff=0, sb_yoff=0, sb_ylabel_xoff_comp=False, sb_ylabel_yoff=0, rotate_yslabel=False, linestyle="-k", linewidth=4.0, textcolor='k', textweight='normal', xmin=None, xmax=None, ymin=None, ymax=None): # print dir(ax.dataLim) if xmin is None: xmin = ax.dataLim.xmin if xmax is None: xmax = ax.dataLim.xmax if ymin is None: ymin = ax.dataLim.ymin if ymax is None: ymax = ax.dataLim.ymax xscale = xmax-xmin yscale = ymax-ymin xoff = (scale_dist_x + sb_xoff) * xscale if sb_ylabel_xoff_comp: xoff_ylabel = scale_dist_x * xscale else: xoff_ylabel = xoff yoff = (scale_dist_y - sb_yoff) * yscale # plot scale bars: xlength = prettyNumber((xmax-xmin)/div) xend_x, xend_y = xmax, ymin if not nox: xstart_x, xstart_y = xmax-xlength, ymin scalebarsx = [xstart_x+xoff, xend_x+xoff] scalebarsy = [xstart_y-yoff, xend_y-yoff] else: scalebarsx = [xend_x+xoff, ] scalebarsy = [xend_y-yoff] ylength = prettyNumber((ymax-ymin)/div) yend_x, yend_y = xmax, ymin+ylength scalebarsx.append(yend_x+xoff) scalebarsy.append(yend_y-yoff) ax.plot(scalebarsx, scalebarsy, linestyle, linewidth=linewidth, solid_joinstyle='miter') if labels: # if textcolor is not None: # color = "\color{%s}" % textcolor # else: # color = "" if not nox: # xlabel if xlength >= 1: xlabel = r"%d$\,$%s" % (xlength, xunits) else: xlabel = r"%g$\,$%s" % (xlength, xunits) xlabel_x, xlabel_y = xmax-xlength/2.0, ymin xlabel_y -= key_dist*yscale ax.text( xlabel_x+xoff, xlabel_y-yoff, xlabel, ha='center', va='top', weight=textweight, color=textcolor) # ylabel if ylength >= 1: ylabel = r"%d$\,$%s" % (ylength, yunits) else: ylabel = r"%g$\,$%s" % (ylength, yunits) if not rotate_yslabel: ylabel_x, ylabel_y = \ xmax, ymin + ylength/2.0 + sb_ylabel_yoff*yscale ylabel_x += key_dist*xscale ax.text(ylabel_x+xoff_ylabel, ylabel_y-yoff, ylabel, ha='left', va='center', weight=textweight, color=textcolor) else: ylabel_x, ylabel_y = xmax, ymin + ylength/2.0 + sb_ylabel_yoff ylabel_x += key_dist*xscale ax.text(ylabel_x+xoff_ylabel, ylabel_y-yoff, ylabel, ha='left', va='center', rotation=90, weight=textweight, color=textcolor) def xFormat(x, res, data_len, width): points = int(width/2.5 * res) part = float(x) / data_len return int(part*points) def yFormat(y): return y def reduce(ydata, dy, maxres, xoffset=0, width=graph_width): x_last = xFormat(0, maxres, len(ydata), width) y_last = yFormat(ydata[0]) y_max = y_last y_min = y_last x_next = 0 y_next = 0 xrange = list() yrange = list() xrange.append(x_last) yrange.append(y_last) for (n, pt) in enumerate(ydata[:-1]): x_next = xFormat(n+1, maxres, len(ydata), width) y_next = yFormat(ydata[n+1]) # if we are still at the same pixel column, # only draw if this is an extremum: if (x_next == x_last): if (y_next < y_min): y_min = y_next if (y_next > y_max): y_max = y_next else: # else, always draw and reset extrema: if (y_min != y_next): xrange.append(x_last) yrange.append(y_min) y_last = y_min if (y_max != y_next): xrange.append(x_last) yrange.append(y_max) y_last = y_max xrange.append(x_next) yrange.append(y_next) y_min = y_next y_max = y_next x_last = x_next y_last = y_next trace_len_pts = width/2.5 * maxres trace_len_time = len(ydata) * dy dt_per_pt = trace_len_time / trace_len_pts xrange = np.array(xrange)*dt_per_pt + xoffset return xrange, yrange def plot_traces(traces, traces2=None, ax=None, Fig=None, pulses=None, xmin=None, xmax=None, ymin=None, ymax=None, y2min=None, y2max=None, xoffset=0, maxres=None, plot_sb=True, sb_yoff=0, sb_xoff=0, linestyle_sb="-k", dashedline=None, sagline=None, rotate_yslabel=False, textcolor='k', textweight='normal', textcolor2='r', figsize=None, pulseprop=0.05, border=0.2): if ax is None: if figsize is None: Fig = plt.figure(dpi=maxres) else: Fig = plt.figure(dpi=maxres, figsize=figsize) Fig.patch.set_alpha(0.0) if pulses is not None and len(pulses) > 0: prop = 1.0-pulseprop-border else: prop = 1.0-border ax = Fig.add_axes([0.0, (1.0-prop), 1.0-border, prop], alpha=0.0) # This is a hack to find the y-limits of the # traces. It should be supplied by stf.plot_ymin() & stf.plot_ymax(). But # this doesn't work for a 2nd channel, and if the active channel is 2 (IN # 2). It seems like stf.plot_ymin/max always gets data from channel 0 (IN # 0), irrespective of which is choosen as the active channel. if y2min is not None and y2max is not None: ymin, ymax = np.inf, -np.inf for trace in traces: if maxres is None: xrange = trace.timearray()+xoffset yrange = trace.data else: xrange, yrange = reduce(trace.data, trace.dt, maxres=maxres) xrange += xoffset if y2min is not None and y2max is not None: ymin, ymax = min(ymin, yrange.min()), max(ymax, yrange.max()) # Hack to get y-limits of data. See comment above. ax.plot( xrange, yrange, trace.linestyle, lw=trace.linewidth, color=trace.color) y2min, y2max = np.inf, -np.inf # Hack to get y-limit of data, see comment above. if traces2 is not None: copy_ax = ax.twinx() for trace in traces2: if maxres is None: xrange = trace.timearray()+xoffset yrange = trace.data else: xrange, yrange = reduce(trace.data, trace.dt, maxres=maxres) xrange += xoffset y2min, y2max = min(y2min, yrange.min()), max(y2max, yrange.max()) # Hack to get y-limit of data, see comment above. copy_ax.plot(xrange, yrange, trace.linestyle, lw=trace.linewidth, color=trace.color) else: copy_ax = None if xmin is not None: phantomrect_x0 = xmin else: phantomrect_x0 = ax.dataLim.xmin if xmax is not None: phantomrect_x1 = xmax else: phantomrect_x1 = ax.dataLim.xmax if ymin is not None: phantomrect_y0 = ymin else: phantomrect_y0 = ax.dataLim.ymin if ymax is not None: phantomrect_y1 = ymax else: phantomrect_y1 = ax.dataLim.ymax ax.plot( [phantomrect_x0, phantomrect_x1], [phantomrect_y0, phantomrect_y1], alpha=0.0) if traces2 is not None: if y2min is not None: phantomrect_y20 = y2min else: phantomrect_y20 = copy_ax.dataLim.ymin if y2max is not None: phantomrect_y21 = y2max else: phantomrect_y21 = copy_ax.dataLim.ymax copy_ax.plot( [phantomrect_x0, phantomrect_x1], [phantomrect_y20, phantomrect_y21], alpha=0.0) xscale = ax.dataLim.xmax-ax.dataLim.xmin if dashedline is not None: ax.plot([ax.dataLim.xmin, ax.dataLim.xmax], [dashedline, dashedline], "--k", linewidth=traces[0].linewidth*2.0) gridline_x = ax.dataLim.xmax gridline_x += key_dist*xscale if sagline is not None: ax.plot([ax.dataLim.xmin, ax.dataLim.xmax],[sagline, sagline], "--k", linewidth=traces[0].linewidth*2.0) gridline_x = ax.dataLim.xmax gridline_x += key_dist*xscale if xmin is None: xmin = ax.dataLim.xmin if xmax is None: xmax = ax.dataLim.xmax if ymin is None: ymin = ax.dataLim.ymin if ymax is None: ymax = ax.dataLim.ymax ax.set_xlim(xmin, xmax) ax.set_ylim(ymin, ymax) if traces2 is not None: if y2min is None: y2min = copy_ax.dataLim.ymin if y2max is None: y2max = copy_ax.dataLim.ymax copy_ax.set_ylim(y2min, y2max) sb_xoff_total = -0.03+sb_xoff sb_yl_yoff = 0.025 else: sb_xoff_total = sb_xoff sb_yl_yoff = 0 if plot_sb: plot_scalebars( ax, linestyle=linestyle_sb, xunits=traces[0].xunits, yunits=traces[0].yunits, textweight=textweight, textcolor=textcolor, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, rotate_yslabel=rotate_yslabel, sb_xoff=sb_xoff_total, sb_ylabel_xoff_comp=(traces2 is not None), sb_ylabel_yoff=sb_yl_yoff) if traces2 is not None: plot_scalebars( copy_ax, linestyle=traces2[0].linestyle, xunits=traces2[0].xunits, yunits=traces2[0].yunits, textweight=textweight, textcolor=textcolor2, xmin=xmin, xmax=xmax, ymin=y2min, ymax=y2max, rotate_yslabel=rotate_yslabel, nox=True, sb_xoff=-0.01+sb_xoff, sb_ylabel_xoff_comp=True, sb_ylabel_yoff=-sb_yl_yoff) if pulses is not None and len(pulses) > 0: axp = Fig.add_axes( [0.0, 0.0, 1.0-border, pulseprop+border/4.0], sharex=ax) for pulse in pulses: xrange = pulse.timearray() yrange = pulse.data axp.plot( xrange, yrange, pulse.linestyle, linewidth=pulse.linewidth, color=pulse.color) plot_scalebars( axp, linestyle=linestyle_sb, nox=True, yunits=pulses[0].yunits, textweight=textweight, textcolor=textcolor) for o in axp.findobj(): o.set_clip_on(False) axp.axis('off') for o in ax.findobj(): o.set_clip_on(False) ax.axis('off') if traces2 is not None: copy_ax.axis('off') if ax is None: return Fig return ax # NOTE copy_ax HKT mod def standard_axis(fig, subplot, sharex=None, sharey=None, hasx=False, hasy=True): sys.stderr.write("This method is deprecated. " "Use stfio_plot.StandardAxis instead.\n") try: iter(subplot) if isinstance(subplot, matplotlib.gridspec.GridSpec): ax1 = Subplot( fig, subplot, frameon=False, sharex=sharex, sharey=sharey) else: ax1 = Subplot( fig, subplot[0], subplot[1], subplot[2], frameon=False, sharex=sharex, sharey=sharey) except: ax1 = Subplot( fig, subplot, frameon=False, sharex=sharex, sharey=sharey) fig.add_axes(ax1) ax1.axis["right"].set_visible(False) ax1.axis["top"].set_visible(False) if not hasx: ax1.axis["bottom"].set_visible(False) if not hasy: ax1.axis["left"].set_visible(False) return ax1 stimfit-0.16.7/src/pystfio/pystfio.i0000664000175000017500000003766214752216304013124 %define DOCSTRING "The stfio module provides functions to read/write data from/to common electrophysiology file formats" %enddef %module(docstring=DOCSTRING) stfio %{ #define SWIG_FILE_WITH_INIT #include #include #include #include #include #include #include "./../libstfio/stfio.h" #include "./../libstfio/recording.h" #include "./../libstfio/channel.h" #include "./../libstfio/section.h" #include "pystfio.h" static int myErr = 0; // flag to save error state %} %include "../stimfit/py/numpy.i" %include "std_string.i" %include "exception.i" %init %{ import_array(); PyDateTime_IMPORT; %} %define %apply_numpy_typemaps(TYPE) %apply (TYPE* IN_ARRAY1, int DIM1) {(TYPE* invec, int size)}; %apply (TYPE* IN_ARRAY1, int DIM1) {(TYPE* data, int size_data)}; %apply (TYPE* IN_ARRAY1, int DIM1) {(TYPE* templ, int size_templ)}; %enddef /* %apply_numpy_typemaps() macro */ %apply_numpy_typemaps(double) class Recording { public: Recording(); /* %feature("autodoc", "The sampling interval") dt; double dt; %feature("autodoc", "File description") file_description; %feature("autodoc", "The time of recording") time; %feature("autodoc", "The date of recording") date; %feature("autodoc", "Comment on the recording") comment; %feature("autodoc", "x unit string") xunits; %feature("autodoc", "The date and time of recording") datetime; std::string file_description, time, date, comment, xunits; PyObject* datetime; */ }; class Channel { public: /* %feature("autodoc", "Channel name") name; %feature("autodoc", "y unit string") yunits; std::string name, yunits;*/ }; class Section { }; %exception Recording::__getitem__ { assert(!myErr); $action if (myErr) { myErr = 0; SWIG_exception(SWIG_IndexError, "Index out of bounds"); } } %exception Channel::__getitem__ { assert(!myErr); $action if (myErr) { myErr = 0; SWIG_exception(SWIG_IndexError, "Index out of bounds"); } } %exception Section::__getitem__ { assert(!myErr); $action if (myErr) { myErr = 0; SWIG_exception(SWIG_IndexError, "Index out of bounds"); } } %extend Recording { Recording(PyObject* ChannelList) : dt(1.0), file_description(""), time(""), date(""), comment(""), xunits("") { if (!PyList_Check(ChannelList)) { std::cerr << "Argument is not a list\n"; return NULL; } Py_ssize_t listsize = PyList_Size(ChannelList); std::deque ChannelCpp(listsize); for (Py_ssize_t i=0; i(argp1); ChannelCpp[i] = *arg1; } // Note that array size is fixed by this allocation: Recording* rec = new Recording(ChannelCpp); return rec; } ~Recording() {delete $self;} double dt; std::string file_description; std::string time; std::string date; std::string comment; std::string xunits; PyObject* datetime; Channel* __getitem__(int at) { if (at >= 0 && at < (int)$self->size()) { return &(*($self))[at]; } else { myErr = 1; return NULL; } } int __len__() { return $self->size(); } %feature("autodoc", "Writes a Recording to a file. Arguments: fname -- file name #ifndef TEST_MINIMAL ftype -- file type (string). At present, only \"hdf5\" is supported. #else ftype -- file type (string). At present, \"hdf5\", \"gdf\", \"cfs\" and \"ibw\" are supported. #endif // TEST_MINIMAL verbose-- Show info while writing Returns: True upon successful completion.") write; bool write(const std::string& fname, const std::string& ftype="hdf5", bool verbose=false) { stfio::filetype stftype = gettype(ftype); stfio::StdoutProgressInfo progDlg("File export", "Writing file", 100, verbose); try { return stfio::exportFile(fname, stftype, *($self), progDlg); } catch (const std::exception& e) { std::cerr << "Couldn't write to file:\n" << e.what() << std::endl; return false; } } %pythoncode { def aspandas(self): import sys import numpy as np has_pandas = True try: import pandas as pd except ImportError: has_pandas = False if has_pandas: chnames = [ch.name for ch in self] channels = np.array([np.concatenate([sec for sec in ch]) for ch in self]) date_range = pd.date_range(start=self.datetime, periods=channels.shape[1], freq='%dU' % np.round(self.dt*1e3)) return pd.DataFrame(channels.transpose(), index=date_range, columns=chnames) else: sys.stderr.write("Pandas is not available on this system\n") return None } } %{ double Recording_dt_get(Recording *r) { return r->GetXScale(); } void Recording_dt_set(Recording *r, double val) { r->SetXScale(val); } const std::string& Recording_file_description_get(Recording *r) { return r->GetFileDescription(); } void Recording_file_description_set(Recording *r, const std::string& val) { r->SetFileDescription(val); } const std::string& Recording_time_get(Recording *r) { static char buffer[9]; struct tm dt = r->GetDateTime(); // Use strftime to format the time into the buffer. if (strftime(buffer, sizeof(buffer), "%H:%M:%S", &dt) == 0) { return "na"; } return std::string(buffer); } void Recording_time_set(Recording *r, const std::string& val) { r->SetTime(val); } const std::string& Recording_date_get(Recording *r) { static char buffer[11]; struct tm dt = r->GetDateTime(); // Use strftime to format the time into the buffer. if (strftime(buffer, sizeof(buffer), "%Y:%m:%d", &dt) == 0) { return ""; } return std::string(buffer); } void Recording_date_set(Recording *r, const std::string& val) { r->SetDate(val); } const std::string& Recording_xunits_get(Recording *r) { return r->GetXUnits(); } void Recording_xunits_set(Recording *r, const std::string& val) { r->SetXUnits(val); } const std::string& Recording_comment_get(Recording *r) { return r->GetComment(); } void Recording_comment_set(Recording *r, const std::string& val) { r->SetComment(val); } PyObject* Recording_datetime_get(Recording *r) { struct tm rec_tm = r->GetDateTime(); if (rec_tm.tm_hour < 0 || rec_tm.tm_hour >= 24) { std::cerr << "Date out of range: hour is " << rec_tm.tm_hour << std::endl; } return PyDateTime_FromDateAndTime(rec_tm.tm_year+1900, rec_tm.tm_mon+1, rec_tm.tm_mday, rec_tm.tm_hour, rec_tm.tm_min, rec_tm.tm_sec, 0); } void Recording_datetime_set(Recording *r, const PyObject* val) { if (val != NULL && PyDate_Check(val)) { int year = PyDateTime_GET_YEAR(val); int month = PyDateTime_GET_MONTH(val); int day = PyDateTime_GET_DAY(val); int hour = PyDateTime_DATE_GET_HOUR(val); int minute = PyDateTime_DATE_GET_MINUTE(val); int second = PyDateTime_DATE_GET_SECOND(val); r->SetDateTime(year, month, day, hour, minute, second); } } %} %extend Channel { Channel(PyObject* SectionList, const std::string& yunits_="") : name(""), yunits(yunits_) { if (!PyList_Check(SectionList)) { std::cerr << "Argument is not a list\n"; return NULL; } Py_ssize_t listsize = PyList_Size(SectionList); std::deque
SectionCpp(listsize); for (Py_ssize_t i=0; i(argp1); SectionCpp[i] = *arg1; } // Note that array size is fixed by this allocation: Channel *ch = new Channel(SectionCpp); ch->SetYUnits(yunits_); return ch; } ~Channel() {delete $self;} std::string name; std::string yunits; Section* __getitem__(int at) { if (at >= 0 && at < (int)$self->size()) { return &(*($self))[at]; } else { myErr = 1; return NULL; } } int __len__() { return $self->size(); } } %{ const std::string& Channel_name_get(Channel *c) { return c->GetChannelName(); } void Channel_name_set(Channel *c, const std::string& val) { c->SetChannelName(val); } const std::string& Channel_yunits_get(Channel *c) { return c->GetYUnits(); } void Channel_yunits_set(Channel *c, const std::string& val) { c->SetYUnits(val); } %} %extend Section { Section(PyArrayObject* nparray) { wrap_array(); npy_intp nplen = PyArray_DIM(nparray, 0); // Note that array size is fixed by this allocation: Section *sec = new Section(nplen, ""); double* npptr = (double*)PyArray_DATA(nparray); std::copy(&npptr[0], &npptr[nplen], &(sec->get_w()[0])); return sec; } ~Section() { delete($self); } double __getitem__(int at) { if (at >= 0 && at < (int)$self->size()) { return (*($self))[at]; } else { myErr = 1; return 0; } } int __len__() { return $self->size(); } %feature("autodoc", "Returns the section as a numpy array.") asarray; PyArrayObject* asarray() { npy_intp dims[1] = {$self->size()}; PyArrayObject* np_array = (PyArrayObject*) PyArray_SimpleNew(1, dims, NPY_DOUBLE); double* gDataP = (double*)array_data(np_array); std::copy( $self->get().begin(), $self->get().end(), gDataP); return np_array; }; } //-------------------------------------------------------------------- %feature("autodoc", 0) _read; %feature("docstring", "Reads a file and returns a recording object. Arguments: filename -- file name #ifndef TEST_MINIMAL ftype -- File type #else ftype -- File type (obsolete) #endif // TEST_MINIMAL verbose -- Show info while reading Returns: A recording object.") _read; bool _read(const std::string& filename, const std::string& ftype, bool verbose, Recording& Data); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) detect_events; %feature("kwargs") detect_events; %feature("docstring", " Arguments: ") detect_events; PyObject* detect_events(double* data, int size_data, double* templ, int size_templ, double dt, const std::string& mode="criterion", bool norm=true, double lowpass=0.5, double highpass=0.0001); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) peak_detection; %feature("kwargs") peak_detection; %feature("docstring", " Arguments: ") peak_detection; PyObject* peak_detection(double* invec, int size, double threshold, int min_distance); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) risetime; %feature("kwargs") risetime; %feature("docstring", " Arguments: ") risetime; double risetime(double* invec, int size, double base, double amp, double frac=0.2); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %pythoncode { import os class StfIOException(Exception): """ raises Exceptions for the Stfio module """ def __init__(self, error_msg): self.msg = error_msg def __str__(self): return repr(self.msg) filetype = { '.dat':'cfs', '.h5':'hdf5', '.abf':'abf', '.atf':'atf', '.axgd':'axg', '.axgx':'axg', '.clp':'intan'} def read(fname, ftype=None, verbose=False): """Reads a file and returns a Recording object. Arguments: fname -- file name #ifndef TEST_MINIMAL ftype -- file type (string); can be one of: "cfs" - CED filing system "hdf5" - HDF5 "abf" - Axon binary file "atf" - Axon text file "axg" - Axograph X binary file "heka" - HEKA binary file "intan" - INTAN clamp binary file if ftype is None (default), it will be guessed from the extension. #else ftype -- file type (string) is obsolete. in the past it has been used to determine the file type. Now an automated file type identification is used, and this parameter become obsolete; eventually it will be removed. #endif // TEST_MINIMAL verbose-- Show info while reading file Returns: A Recording object. """ if not os.path.exists(fname): raise StfIOException('File %s does not exist' % fname) #ifndef TEST_MINIMAL if ftype is None: ext = os.path.splitext(fname)[1] try: ftype = filetype[ext] except KeyError: raise StfIOException('Couldn\'t guess file type from extension (%s)' % ext) #endif // TEST_MINIMAL rec = Recording() if not _read(fname, ftype, verbose, rec): raise StfIOException('Error reading file') if verbose: print("") return rec def read_tdms(fn): import numpy as np import sys try: from nptdms import TdmsFile except ImportError: sys.stderr.write("nptdms module unavailable") return None tdms_file = TdmsFile(fn) try: times = np.array( [[channel.data for channel in tdms_file.group_channels(group) if channel.data is not None] for group in tdms_file.groups() if group.lower() == "time"][0][0]) dt = np.mean(np.diff(times)) except IndexError: if not "Sampling Rate" in tdms_file.object().properties.keys(): if not "Sampling Rate(AI)" in tdms_file.object().properties.keys(): dt = 1.0 else: sr = float(tdms_file.object().properties['Sampling Rate(AI)']) if sr > 0: dt = 1e3/sr else: dt = 1.0/25.0 else: sr = float(tdms_file.object().properties['Sampling Rate']) if sr > 0: dt = 1e3/sr else: dt = 1.0/25.0 return_dict = { "data": [ [channel.data.astype(np.float64) for channel in tdms_file.group_channels(group) if channel.data is not None] for group in tdms_file.groups() if group.lower()[:2] == "ai" or group.lower()[:2] == "ao"], "dt": dt, } return return_dict } //-------------------------------------------------------------------- stimfit-0.16.7/src/pystfio/Makefile.am0000664000175000017500000000462514750344764013314 if ISDARWIN PYTHON_TARGET_DIR=${PYTHON_DIST_PKG} else PYTHON_TARGET_DIR=${PYTHON_PRE_DIST_PKG} # PYTHON_TARGET_DIR=${PYTHON_DIST_PKG} endif PYTHON_DEST_DIR=${DESTDIR}${PYTHON_TARGET_DIR} pkglibdir = ${PYTHON_TARGET_DIR}/stfio pkglib_LTLIBRARIES = libpystfio.la TESTS_ENVIRONMENT = \ cp .libs/libpystfio.so ./_stfio.so && \ $(PYTHON) TESTS = ./unittest_stfio.py PYTHON_ADDINCLUDES = $(LIBPYTHON_INCLUDES) PYTHON_ADDLDFLAGS = $(LIBPYTHON_LDFLAGS) PYTHON_ADDLIBS = $(top_srcdir)/src/pystfio/pystfio_wrap.cxx $(top_srcdir)/src/pystfio/stfio.py: $(top_srcdir)/src/pystfio/pystfio.i $(SWIG) $(SWIG_PYTHON_OPT) -o $@ $< cat $(top_srcdir)/src/stimfit/py/gccwarn $(top_srcdir)/src/pystfio/pystfio_wrap.cxx > $(top_srcdir)/src/pystfio/pystfio_wrap_tmp.cxx mv $(top_srcdir)/src/pystfio/pystfio_wrap_tmp.cxx $(top_srcdir)/src/pystfio/pystfio_wrap.cxx nodist_libpystfio_la_SOURCES = $(top_srcdir)/src/pystfio/pystfio_wrap.cxx libpystfio_la_SOURCES = $(top_srcdir)/src/pystfio/pystfio.cxx noinst_HEADERS = $(top_srcdir)/src/pystfio/pystfio.h INCLUDES = $(LIBNUMPY_INCLUDES) $(PYTHON_ADDINCLUDES) EXTRA_DIST = ./pystfio.i ./unittest_stfio.py libpystfio_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src libpystfio_la_CXXFLAGS = $(OPT_CXXFLAGS) libpystfio_la_LDFLAGS = $(PYTHON_ADDLDFLAGS) $(LIBSTF_LDFLAGS) libpystfio_la_LIBADD = $(PYTHON_ADDLIBS) ./../libstfio/libstfio.la ./../libstfnum/libstfnum.la if WITH_BIOSIGLITE libpystfio_la_LIBADD += ./../libbiosiglite/libbiosiglite.la endif # LTTARGET=${PYTHON_DIST_PKG}/stfio LTTARGET=${PYTHON_DEST_DIR}/stfio install-exec-hook: mv ${PYTHON_DEST_DIR}/stfio/${STFIO_PYTHON_LIBNAME} ${PYTHON_DEST_DIR}/stfio/_stfio.so if BUILD_DEBIAN chrpath -r ${PYTHON_DIST_PKG}/stfio ${PYTHON_DEST_DIR}/stfio/_stfio.so endif rm -f ${PYTHON_DEST_DIR}/stfio/*.la rm -f ${PYTHON_DEST_DIR}/stfio/*.a cp -p $(top_srcdir)/src/pystfio/__init__.py ${PYTHON_DEST_DIR}/stfio cp -p $(top_srcdir)/src/pystfio/stfio_plot.py ${PYTHON_DEST_DIR}/stfio cp -p $(top_srcdir)/src/pystfio/stfio_neo.py ${PYTHON_DEST_DIR}/stfio cp -p $(top_srcdir)/src/pystfio/stfio.py ${PYTHON_DEST_DIR}/stfio ${PYTHON} -m compileall -l ${PYTHON_DEST_DIR}/stfio chmod -x ${PYTHON_DEST_DIR}/stfio/* uninstall-hook: rm -f ${PYTHON_DEST_DIR}/stfio/*.so rm -f ${PYTHON_DEST_DIR}/stfio.pth rm -r ${PYTHON_DEST_DIR}/stfio clean-local: rm -f $(top_srcdir)/src/pystfio/pystfio_wrap.cxx $(top_srcdir)/src/pystfio/stfio.py rm -f _stfio.so stimfit-0.16.7/src/pystfio/Makefile.in0000664000175000017500000011732414764352410013316 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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@ 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@ 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@ @WITH_BIOSIGLITE_TRUE@am__append_1 = ./../libbiosiglite/libbiosiglite.la subdir = src/pystfio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acsite.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/stfconf.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)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = libpystfio_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ ./../libstfio/libstfio.la ./../libstfnum/libstfnum.la \ $(am__append_1) am_libpystfio_la_OBJECTS = libpystfio_la-pystfio.lo nodist_libpystfio_la_OBJECTS = libpystfio_la-pystfio_wrap.lo libpystfio_la_OBJECTS = $(am_libpystfio_la_OBJECTS) \ $(nodist_libpystfio_la_OBJECTS) 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 = libpystfio_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libpystfio_la_CXXFLAGS) $(CXXFLAGS) $(libpystfio_la_LDFLAGS) \ $(LDFLAGS) -o $@ 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@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libpystfio_la-pystfio.Plo \ ./$(DEPDIR)/libpystfio_la-pystfio_wrap.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 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 = $(libpystfio_la_SOURCES) $(nodist_libpystfio_la_SOURCES) DIST_SOURCES = $(libpystfio_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # 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)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkglibdir = ${PYTHON_TARGET_DIR}/stfio ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ GT_CPPFLAGS = @GT_CPPFLAGS@ GT_CXXFLAGS = @GT_CXXFLAGS@ GT_LDFLAGS = @GT_LDFLAGS@ GT_LIBS = @GT_LIBS@ HDF5_CFLAGS = @HDF5_CFLAGS@ HDF5_LIBS = @HDF5_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBIOSIG_LDFLAGS = @LIBBIOSIG_LDFLAGS@ LIBHDF5_LDFLAGS = @LIBHDF5_LDFLAGS@ LIBLAPACK_LDFLAGS = @LIBLAPACK_LDFLAGS@ LIBNUMPY_INCLUDES = @LIBNUMPY_INCLUDES@ LIBOBJS = @LIBOBJS@ LIBPYTHON_INCLUDES = @LIBPYTHON_INCLUDES@ LIBPYTHON_LDFLAGS = @LIBPYTHON_LDFLAGS@ LIBS = @LIBS@ LIBSTF_LDFLAGS = @LIBSTF_LDFLAGS@ LIBTOOL = @LIBTOOL@ LIBWXPYTHON_INCLUDES = @LIBWXPYTHON_INCLUDES@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MACSETFILE = @MACSETFILE@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ 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@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSTLINK_COMMAND = @POSTLINK_COMMAND@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIST_PKG = @PYTHON_DIST_PKG@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ PYTHON_NUMPY_INCLUDE = @PYTHON_NUMPY_INCLUDE@ PYTHON_PRE_DIST_PKG = @PYTHON_PRE_DIST_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ PYTHON_WXPYTHON_INCLUDE = @PYTHON_WXPYTHON_INCLUDE@ PY_AC_VERSION = @PY_AC_VERSION@ RANLIB = @RANLIB@ REZ = @REZ@ SED = @SED@ SETFILE = @SETFILE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STFIO_PYTHON_LIBNAME = @STFIO_PYTHON_LIBNAME@ STF_PYTHON_LIBNAME = @STF_PYTHON_LIBNAME@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ VERSION = @VERSION@ WX_CPPFLAGS = @WX_CPPFLAGS@ WX_CXXFLAGS = @WX_CXXFLAGS@ WX_LIBS = @WX_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ 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@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ 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@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @ISDARWIN_FALSE@PYTHON_TARGET_DIR = ${PYTHON_PRE_DIST_PKG} @ISDARWIN_TRUE@PYTHON_TARGET_DIR = ${PYTHON_DIST_PKG} # PYTHON_TARGET_DIR=${PYTHON_DIST_PKG} PYTHON_DEST_DIR = ${DESTDIR}${PYTHON_TARGET_DIR} pkglib_LTLIBRARIES = libpystfio.la TESTS_ENVIRONMENT = \ cp .libs/libpystfio.so ./_stfio.so && \ $(PYTHON) TESTS = ./unittest_stfio.py PYTHON_ADDINCLUDES = $(LIBPYTHON_INCLUDES) PYTHON_ADDLDFLAGS = $(LIBPYTHON_LDFLAGS) PYTHON_ADDLIBS = nodist_libpystfio_la_SOURCES = $(top_srcdir)/src/pystfio/pystfio_wrap.cxx libpystfio_la_SOURCES = $(top_srcdir)/src/pystfio/pystfio.cxx noinst_HEADERS = $(top_srcdir)/src/pystfio/pystfio.h INCLUDES = $(LIBNUMPY_INCLUDES) $(PYTHON_ADDINCLUDES) EXTRA_DIST = ./pystfio.i ./unittest_stfio.py libpystfio_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src libpystfio_la_CXXFLAGS = $(OPT_CXXFLAGS) libpystfio_la_LDFLAGS = $(PYTHON_ADDLDFLAGS) $(LIBSTF_LDFLAGS) libpystfio_la_LIBADD = $(PYTHON_ADDLIBS) ./../libstfio/libstfio.la \ ./../libstfnum/libstfnum.la $(am__append_1) # LTTARGET=${PYTHON_DIST_PKG}/stfio LTTARGET = ${PYTHON_DEST_DIR}/stfio all: all-am .SUFFIXES: .SUFFIXES: .cxx .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/pystfio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/pystfio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || 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)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_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}; \ } libpystfio.la: $(libpystfio_la_OBJECTS) $(libpystfio_la_DEPENDENCIES) $(EXTRA_libpystfio_la_DEPENDENCIES) $(AM_V_CXXLD)$(libpystfio_la_LINK) -rpath $(pkglibdir) $(libpystfio_la_OBJECTS) $(libpystfio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpystfio_la-pystfio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpystfio_la-pystfio_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cxx.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 $@ $< .cxx.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) '$<'` .cxx.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 $@ $< libpystfio_la-pystfio.lo: $(top_srcdir)/src/pystfio/pystfio.cxx @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystfio_la_CPPFLAGS) $(CPPFLAGS) $(libpystfio_la_CXXFLAGS) $(CXXFLAGS) -MT libpystfio_la-pystfio.lo -MD -MP -MF $(DEPDIR)/libpystfio_la-pystfio.Tpo -c -o libpystfio_la-pystfio.lo `test -f '$(top_srcdir)/src/pystfio/pystfio.cxx' || echo '$(srcdir)/'`$(top_srcdir)/src/pystfio/pystfio.cxx @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpystfio_la-pystfio.Tpo $(DEPDIR)/libpystfio_la-pystfio.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(top_srcdir)/src/pystfio/pystfio.cxx' object='libpystfio_la-pystfio.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystfio_la_CPPFLAGS) $(CPPFLAGS) $(libpystfio_la_CXXFLAGS) $(CXXFLAGS) -c -o libpystfio_la-pystfio.lo `test -f '$(top_srcdir)/src/pystfio/pystfio.cxx' || echo '$(srcdir)/'`$(top_srcdir)/src/pystfio/pystfio.cxx libpystfio_la-pystfio_wrap.lo: $(top_srcdir)/src/pystfio/pystfio_wrap.cxx @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystfio_la_CPPFLAGS) $(CPPFLAGS) $(libpystfio_la_CXXFLAGS) $(CXXFLAGS) -MT libpystfio_la-pystfio_wrap.lo -MD -MP -MF $(DEPDIR)/libpystfio_la-pystfio_wrap.Tpo -c -o libpystfio_la-pystfio_wrap.lo `test -f '$(top_srcdir)/src/pystfio/pystfio_wrap.cxx' || echo '$(srcdir)/'`$(top_srcdir)/src/pystfio/pystfio_wrap.cxx @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpystfio_la-pystfio_wrap.Tpo $(DEPDIR)/libpystfio_la-pystfio_wrap.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(top_srcdir)/src/pystfio/pystfio_wrap.cxx' object='libpystfio_la-pystfio_wrap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystfio_la_CPPFLAGS) $(CPPFLAGS) $(libpystfio_la_CXXFLAGS) $(CXXFLAGS) -c -o libpystfio_la-pystfio_wrap.lo `test -f '$(top_srcdir)/src/pystfio/pystfio_wrap.cxx' || echo '$(srcdir)/'`$(top_srcdir)/src/pystfio/pystfio_wrap.cxx mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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" 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 # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? ./unittest_stfio.py.log: ./unittest_stfio.py @p='./unittest_stfio.py'; \ b='./unittest_stfio.py'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @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 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am 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: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) 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-local \ clean-pkglibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libpystfio_la-pystfio.Plo -rm -f ./$(DEPDIR)/libpystfio_la-pystfio_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ 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-pkglibLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook 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 ./$(DEPDIR)/libpystfio_la-pystfio.Plo -rm -f ./$(DEPDIR)/libpystfio_la-pystfio_wrap.Plo -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-pkglibLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: check-am install-am install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-generic clean-libtool clean-local \ clean-pkglibLTLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir 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-exec-hook \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am \ install-pkglibLTLIBRARIES install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am recheck tags tags-am uninstall \ uninstall-am uninstall-hook uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile $(top_srcdir)/src/pystfio/pystfio_wrap.cxx $(top_srcdir)/src/pystfio/stfio.py: $(top_srcdir)/src/pystfio/pystfio.i $(SWIG) $(SWIG_PYTHON_OPT) -o $@ $< cat $(top_srcdir)/src/stimfit/py/gccwarn $(top_srcdir)/src/pystfio/pystfio_wrap.cxx > $(top_srcdir)/src/pystfio/pystfio_wrap_tmp.cxx mv $(top_srcdir)/src/pystfio/pystfio_wrap_tmp.cxx $(top_srcdir)/src/pystfio/pystfio_wrap.cxx install-exec-hook: mv ${PYTHON_DEST_DIR}/stfio/${STFIO_PYTHON_LIBNAME} ${PYTHON_DEST_DIR}/stfio/_stfio.so @BUILD_DEBIAN_TRUE@ chrpath -r ${PYTHON_DIST_PKG}/stfio ${PYTHON_DEST_DIR}/stfio/_stfio.so rm -f ${PYTHON_DEST_DIR}/stfio/*.la rm -f ${PYTHON_DEST_DIR}/stfio/*.a cp -p $(top_srcdir)/src/pystfio/__init__.py ${PYTHON_DEST_DIR}/stfio cp -p $(top_srcdir)/src/pystfio/stfio_plot.py ${PYTHON_DEST_DIR}/stfio cp -p $(top_srcdir)/src/pystfio/stfio_neo.py ${PYTHON_DEST_DIR}/stfio cp -p $(top_srcdir)/src/pystfio/stfio.py ${PYTHON_DEST_DIR}/stfio ${PYTHON} -m compileall -l ${PYTHON_DEST_DIR}/stfio chmod -x ${PYTHON_DEST_DIR}/stfio/* uninstall-hook: rm -f ${PYTHON_DEST_DIR}/stfio/*.so rm -f ${PYTHON_DEST_DIR}/stfio.pth rm -r ${PYTHON_DEST_DIR}/stfio clean-local: rm -f $(top_srcdir)/src/pystfio/pystfio_wrap.cxx $(top_srcdir)/src/pystfio/stfio.py rm -f _stfio.so # 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: stimfit-0.16.7/src/pystfio/stfio_neo.py0000664000175000017500000000305114750344764013607 """ Adapter to represent stfio recordings as neo objects Based on exampleio.py and axonio.py from neo.io 08 Feb 2014, C. Schmidt-Hieber, University College London """ # needed for python 3 compatibility from __future__ import absolute_import import sys import numpy as np import stfio def neo2stfio(neo_obj): """Convert neo object to stfio recording. Restrictions: * Only converts the first block * Assumes that the sampling rate is constant throughout segments * Assumes that we have the same number of channels throughout segments * Assumes that the channel units do not change Usage: >>> import neo >>> neo_obj = neo.io.AxonIO("filename.abf") >>> import stfio >>> stfio_obj = stfio.neo.neo2stfio(neo_obj) >>> assert(stfio_obj[0][0][0] == neo_obj.read()[0].segments[0].analogsignals[0][0]) """ blocks = neo_obj.read() if len(blocks) > 1: sys.stderr.write("Warning: Only the first block" + "of this neo object will be converted\n") reference_signal = blocks[0].segments[0].analogsignals nchannels = len(reference_signal) rec = stfio.Recording([ stfio.Channel([ stfio.Section(np.array(seg.analogsignals[nc], dtype=np.float64)) for seg in blocks[0].segments ], reference_signal[nc].units.dimensionality.string) for nc in range(nchannels) ]) rec.dt = float(reference_signal[0].sampling_period.rescale('ms')) rec.xunits = "ms" return rec stimfit-0.16.7/src/pystfio/__init__.py0000664000175000017500000000033114750344764013357 # -*- coding: utf-8 -*- ''' Python module to read common electrophysiology file formats. ''' from .stfio import * from . import stfio_plot as plot try: from . import stfio_neo as neo except ImportError: pass stimfit-0.16.7/src/pystfio/pystfio.cxx0000775000175000017500000001374314750344764013505 #include #include #include #if 0 //def _WINDOWS #ifdef _DEBUG #undef _DEBUG #define _UNDEBUG #endif #endif #ifdef _POSIX_C_SOURCE #define _POSIX_C_SOURCE_WAS_DEF #undef _POSIX_C_SOURCE #endif #ifdef _XOPEN_SOURCE #define _XOPEN_SOURCE_WAS_DEF #undef _XOPEN_SOURCE #endif #include #ifdef _POSIX_C_SOURCE_WAS_DEF #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE #endif #endif #ifdef _XOPEN_SOURCE_WAS_DEF #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #endif #include #include #if 0//def _WINDOWS #ifdef _UNDEBUG #define _DEBUG #endif #endif #include "./../libstfnum/fit.h" #include "./../libstfnum/measure.h" #include "pystfio.h" #if PY_MAJOR_VERSION >= 3 int wrap_array() { import_array(); return 0; } #else void wrap_array() { import_array(); } #endif stfio::filetype gettype(const std::string& ftype) { stfio::filetype stftype = stfio::none; if (ftype == "cfs") { stftype = stfio::cfs; } else if (ftype == "hdf5") { stftype = stfio::hdf5; } else if (ftype == "abf") { stftype = stfio::abf; } else if (ftype == "atf") { stftype = stfio::atf; } else if (ftype == "axg") { stftype = stfio::axg; } else if (ftype == "biosig") { stftype = stfio::biosig; } else if (ftype == "gdf") { stftype = stfio::biosig; } else if (ftype == "heka") { stftype = stfio::heka; } else if (ftype == "igor") { stftype = stfio::igor; } else if (ftype == "tdms") { stftype = stfio::tdms; } else if (ftype == "intan") { stftype = stfio::intan; } else { stftype = stfio::none; } return stftype; } bool _read(const std::string& filename, const std::string& ftype, bool verbose, Recording& Data) { #ifndef TEST_MINIMAL stfio::filetype stftype = gettype(ftype); #else const stfio::filetype stftype = stfio::none; #endif // TEST_MINIMAL stfio::txtImportSettings tis; stfio::StdoutProgressInfo progDlg("File import", "Starting file import", 100, verbose); try { if (!stfio::importFile(filename, stftype, Data, tis, progDlg)) { std::cerr << "Error importing file\n"; return false; } } catch (const std::exception& e) { std::cerr << "Error importing file:\n" << e.what() << std::endl; return false; } return true; } PyObject* detect_events(double* data, int size_data, double* templ, int size_templ, double dt, const std::string& mode, bool norm, double lowpass, double highpass) { wrap_array(); Vector_double vtempl(templ, &templ[size_templ]); if (norm) { double fmin = *std::min_element(vtempl.begin(), vtempl.end()); double fmax = *std::max_element(vtempl.begin(), vtempl.end()); double basel = 0; double normval = 1.0; if (fabs(fmin) > fabs(fmax)) { basel = fmax; } else { basel = fmin; } vtempl = stfio::vec_scal_minus(vtempl, basel); fmin = *std::min_element(vtempl.begin(), vtempl.end()); fmax = *std::max_element(vtempl.begin(), vtempl.end()); if (fabs(fmin) > fabs(fmax)) { normval = fabs(fmin); } else { normval = fabs(fmax); } vtempl = stfio::vec_scal_div(vtempl, normval); } Vector_double trace(data, &data[size_data]); Vector_double detect(size_data); if (mode=="criterion") { stfio::StdoutProgressInfo progDlg("Computing detection criterion...", "Computing detection criterion...", 100, true); detect = stfnum::detectionCriterion(trace, vtempl, progDlg); } else if (mode=="correlation") { stfio::StdoutProgressInfo progDlg("Computing linear correlation...", "Computing linear correlation...", 100, true); detect = stfnum::linCorr(trace, vtempl, progDlg); } else if (mode=="deconvolution") { stfio::StdoutProgressInfo progDlg("Computing detection criterion...", "Computing detection criterion...", 100, true); try { detect = stfnum::deconvolve(trace, vtempl, 1.0/dt, highpass, lowpass, progDlg); } catch (const std::runtime_error& e) { std::cerr << e.what() << std::endl; return Py_BuildValue(""); } } npy_intp dims[1] = {(int)detect.size()}; PyObject* np_array = PyArray_SimpleNew(1, dims, NPY_DOUBLE); double* gDataP = (double*)array_data(np_array); /* fill */ std::copy(detect.begin(), detect.end(), gDataP); return np_array; } PyObject* peak_detection(double* invec, int size, double threshold, int min_distance) { wrap_array(); Vector_double data(invec, &invec[size]); std::vector peak_idcs = stfnum::peakIndices(data, threshold, min_distance); npy_intp dims[1] = {(int)peak_idcs.size()}; PyObject* np_array = PyArray_SimpleNew(1, dims, NPY_INT); if (sizeof(int) == 4) { int* gDataP = (int*)array_data(np_array); /* fill */ std::copy(peak_idcs.begin(), peak_idcs.end(), gDataP); return np_array; } else if (sizeof(short) == 4) { short* gDataP = (short*)array_data(np_array); /* fill */ std::copy(peak_idcs.begin(), peak_idcs.end(), gDataP); return np_array; } else { std::cerr << "Couldn't find 4-byte integer type\n"; return NULL; } } double risetime(double* invec, int size, double base, double amp, double frac) { wrap_array(); Vector_double data(invec, &invec[size]); double itLoReal, itHiReal, otLoReal, otHiReal; std::size_t argmax = 0; if (size > 0) { double max = data[0]; for (std::size_t nd=1; nd < data.size(); ++nd) { if (data[nd] > max) { max = data[nd]; argmax = nd; } } } return stfnum::risetime2(data, base, amp, 0, argmax, frac, itLoReal, itHiReal, otLoReal, otHiReal); } stimfit-0.16.7/src/stimfit/0000775000175000017500000000000014764352501011304 5stimfit-0.16.7/src/stimfit/res/0000775000175000017500000000000014764352500012074 5stimfit-0.16.7/src/stimfit/res/sum_new.xpm0000775000175000017500000000215514750344764014235 /* XPM */ static const char *sum_new[] = { /* columns rows colors chars-per-pixel */ "16 16 48 1", " c black", ". c gray8", "X c gray16", "o c #2A2A2A", "O c #2D2D2D", "+ c gray18", "@ c #2F2F2F", "# c #313131", "$ c #323232", "% c #343434", "& c #353535", "* c #373737", "= c #3A3A3A", "- c gray25", "; c gray27", ": c gray28", "> c #484848", ", c #494949", "< c #4C4C4C", "1 c #4E4E4E", "2 c gray31", "3 c #515151", "4 c gray32", "5 c #555555", "6 c #565656", "7 c #585858", "8 c #5D5D5D", "9 c gray39", "0 c #646464", "q c gray40", "w c #686868", "e c #6A6A6A", "r c #6D6D6D", "t c #6F6F6F", "y c gray44", "u c #727272", "i c gray45", "p c #767676", "a c #777777", "s c #7B7B7B", "d c #7E7E7E", "f c #818181", "g c #8B8B8B", "h c gray56", "j c #9A9A9A", "k c gray62", "l c gray74", "z c None", /* pixels */ "zzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzz", "zzfdspytw9zzzzzz", "zzdlsytwq8zzzzzz", "zzzghzzzz6zzzzzz", "zzzykqzzzzzzzzzz", "zzzzqjzzzzzzzzzz", "zzzzz74zzzzzzzzz", "zzzz64zzzzzzz zz", "zzz64,zzz%zz zzz", "zzz<:zzzz+z zzzz", "zz<::%%$+oz ---z", "zz:==%$+o. -zzz-", "zzzzzzzzz z-zzz-", "zzzzzzzz zz-zzz-", "zzzzzzz zzz-zzz-" }; stimfit-0.16.7/src/stimfit/res/arrow_out.xpm0000775000175000017500000000426114750344764014601 /* XPM */ static const char *arrow_out[] = { /* columns rows colors chars-per-pixel */ "16 16 96 2", " c #418A3E", ". c #428B3F", "X c #428C3F", "o c #438D40", "O c #448D40", "+ c #458E41", "@ c #458F41", "# c #469042", "$ c #479143", "% c #499445", "& c #4A9545", "* c #4C9447", "= c #4D9948", "- c #4E9948", "; c #4F9B4A", ": c #509C4A", "> c #529F4C", ", c #54A14E", "< c #55A24E", "1 c #56A34F", "2 c #57A450", "3 c #57A550", "4 c #58A651", "5 c #59A752", "6 c #5BA654", "7 c #5AA852", "8 c #5AA853", "9 c #5BA953", "0 c #5CAA54", "q c #5CAB54", "w c #5DAC55", "e c #5EAD56", "r c #5FAD56", "t c #5FAE57", "y c #5EA05A", "u c #61A55D", "i c #63A45F", "p c #64A65E", "a c #64A75F", "s c #60AF58", "d c #61B058", "f c #61B159", "g c #62B159", "h c #62B259", "j c #63B35A", "k c #64B45B", "l c #66B65C", "z c #67B45F", "x c #68B95E", "c c #69B95F", "v c #67A862", "b c #70AD6C", "n c #71AD6D", "m c #73AE6E", "M c #6ABB60", "N c #6BBC60", "B c #6DBF63", "V c #71B46A", "C c #73B46C", "Z c #73B56C", "A c #73B66C", "S c #73B66D", "D c #74B56E", "F c #75B86E", "G c #7AB773", "H c #79B375", "J c #7DBD75", "K c #7EBD76", "L c #6EC063", "P c #70C365", "I c #71C365", "U c #72C466", "Y c #72C566", "T c #73C667", "R c #74C768", "E c #75C56B", "W c #83BB7D", "Q c #82C479", "! c #84C77B", "~ c #86C07E", "^ c #87CA7E", "/ c #89BF83", "( c #8AC083", ") c #8AC084", "_ c #89C980", "` c #8CCC83", "' c #90C58A", "] c #93C78C", "[ c #94C88D", "{ c #95C98E", "} c #9BD192", "| c #A4D39B", " . c #A5D69D", ".. c #A7D69E", "X. c #A9D8A1", "o. c None", /* pixels */ "R R T T P o.o.o.o.o.o.l l g t t ", "R X...P o.o.o.o.o.o.o.o.z ] { 0 ", "U ..} ^ L o.o.o.o.o.o.g K ~ ' 8 ", "P R ` | ! N o.o.o.o.g K ] S 5 3 ", "P o.B _ Q N o.o.o.o.s F S 5 o.< ", "o.o.o.N x o.o.o.o.o.o.8 5 o.o.o.", "o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.", "o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.", "o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.", "o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.", "o.o.o.t t o.o.o.o.o.o.: ; o.o.o.", "g o.t S V 5 o.o.o.o.; a v & o.$ ", "g t V ) D 2 o.o.o.o.= p H i * O ", "t ( G D 3 o.o.o.o.o.o.& y p n X ", "q / W 6 o.o.o.o.o.o.o.o.$ n m X ", "8 5 < < > o.o.o.o.o.o.$ O X X " }; stimfit-0.16.7/src/stimfit/res/16-em-open.xpm0000775000175000017500000000112714750344764014342 /* XPM */ static const char *___em_open[] = { /* columns rows colors chars-per-pixel */ "16 16 11 1", " c #678FB1", ". c #72A6D6", "X c #B8B7AD", "o c #97B4CD", "O c #9DB8CF", "+ c #97BDE1", "@ c #AFCCE8", "# c #C4D9EE", "$ c #DCE9F5", "% c #EBF2F9", "& c None", /* pixels */ "&&&&&&&&&&&&&&&&", "&&&&&&& &&&&&&&", "&&&&&& OO &&&&&&", "&&&&& O%%O &&&&&", "&&&& O%##%O &&&&", "&&& O%#@@#%O &&&", "&& O%#@@@@#%O &&", "&& $$$+..+$$$ &&", "&& o$..$o &&", "&&XXX $..$ XXX&&", "&&&&& $..$ &&&&&", "&&&&& $..$ &&&&&", "&&&&& $$$$ &&&&&", "&&&&& &&&&&", "&&&&&XXXXXX&&&&&", "&&&&&&&&&&&&&&&&" }; stimfit-0.16.7/src/stimfit/res/zoom.xpm0000775000175000017500000000263114750344764013543 /* XPM */ static const char *zoom[] = { /* columns rows colors chars-per-pixel */ "16 16 67 1", " c #874828", ". c #9B5830", "X c #A55C33", "o c #AB6437", "O c #AB6737", "+ c #AB643D", "@ c #BE7340", "# c #B67943", "$ c #B77E47", "% c #B87F47", "& c #B98048", "* c #B98149", "= c #BC854A", "- c #BC844B", "; c #BB814C", ": c #BC834F", "> c #BC864C", ", c #BD864C", "< c #BD894C", "1 c #BE894D", "2 c #BE8A4D", "3 c #BE8A4F", "4 c #BC8451", "5 c #C18E4F", "6 c #C18F4F", "7 c #C28F50", "8 c #C18C52", "9 c #C18E58", "0 c #C39150", "q c #C39153", "w c #C39255", "e c #C39156", "r c #C49555", "t c #C69655", "y c #C79757", "u c #C69956", "i c #C79A57", "p c #C89C57", "a c #C99F5B", "s c #CDA45B", "d c #CCA15D", "f c #CDA55E", "g c #CDA65E", "h c #CEA65E", "j c #CEA75E", "k c #C99B61", "l c #CDA561", "z c #CEA660", "x c #CEA761", "c c #CEA662", "v c #CFA762", "b c #CFA861", "n c #CFA864", "m c #D2AB6F", "M c #D6B479", "N c #D7B57D", "B c #D6B57F", "V c #DABB80", "C c #DBBF87", "Z c #DEC48D", "A c #DFC58F", "S c #E0C793", "D c #E3CC99", "F c #E7D3A0", "G c #E8D5A3", "H c #E9D7A5", "J c None", /* pixels */ "JJJjxnxdaJJJJJJJ", "JJxjJJJJuyJJJJJJ", "JxsJJJJJJ00JJJJJ", "jjJJJJJJJJ7 c #5CA852", ", c #5EAB54", "< c #5FAD56", "1 c #65A75E", "2 c #61B057", "3 c #63B259", "4 c #67B65C", "5 c #6BAC63", "6 c #76B76D", "7 c #B98048", "8 c #BC854A", "9 c #BC844B", "0 c #BC834F", "q c #BC864C", "w c #BD864C", "e c #BD894C", "r c #BE894D", "t c #BE8A4D", "y c #BE8A4F", "u c #BC8451", "i c #C18E4F", "p c #C18F4F", "a c #C28F50", "s c #C18E58", "d c #C39150", "f c #C39153", "g c #C39156", "h c #C49555", "j c #C69655", "k c #C79757", "l c #C69956", "z c #C79A57", "x c #C89C57", "c c #C99F5B", "v c #CDA45B", "b c #CCA15D", "n c #CDA55E", "m c #CDA65E", "M c #CEA65E", "N c #CEA75E", "B c #C99B61", "V c #CDA561", "C c #CEA660", "Z c #CEA761", "A c #CEA662", "S c #CFA762", "D c #CFA861", "F c #CFA864", "G c #D7B57D", "H c #D6B57F", "J c #82C27D", "K c #86C57D", "L c #DABB80", "P c #8BC683", "I c #8BC785", "U c #90CA88", "Y c #9ACF92", "T c #9ED195", "R c #9FD297", "E c #A6D59D", "W c #DEC48D", "Q c #DFC58F", "! c #E0C793", "~ c #E3CC99", "^ c #E7D3A0", "/ c #E8D5A3", "( c #E9D7A5", ") c None", /* pixels */ "))))))))))))))))", ")))NCFFbc)))))))", "))DN))))lk))))))", ")Dv))))))dd)))))", "NN))))))))iy))))", "C))))))))))y))))", "C))))))42>)y))))", "C))))))TYKUP+))))", ")ki));-1I:o.))))", "))dy)))*Jo~Q0)))", ")))9ww9+X /(L&))", ")))))))))sQ^!B@)", "))))))))))uHHg%)", ")))))))))))#7%))" }; stimfit-0.16.7/src/stimfit/res/stimfit_128.png0000664000175000017500000002117114750344764014605 PNG  IHDR>a pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxi\uwyzawsmQ)M(8hMy;N q2`& L 8H c rP,%c!eK"-hR{uU;ޭrlnࡪ^?{pQ؍k +PXA V(1=/9EVK(_R"$^E. ",>.ܶḞz7& (lhksĘoT/p@@UO(˙w(6 " 7{ F!6гt_-Hp@ .#}ԉۑB95j?7j(> &8P ;)hseRF *]`MAqT=*D+PRQR~Oƽu-5 )R7/v >UI##Dʬ = od˽R)$ҙ( AoWP ؄: Aֈ*kRTagĶ?6PB&T%ʥ.jǟ:(B!@`1TwÊlݓK܅%i냤I-Kq&e]RœW}pRȯ Iqԗ8)Tz"$u-7aL" TH9h#@RzU@icz 1]!@d\te'p69(Q|&[)[U$mi-<.[RY^d1A~6ny$‘԰ԉ9CkWG 0of]+| ٴA){0&A PBrADGCژ᳂UAvf6CQ`}=w}k",vZdHҍ:BL/l-iOr 6D؎3g4hC׼w%UcN|h -JLm8⒳6Ep&y < HM@(P $@WoX= 40L{sXg5CZֹع;>HԲ"%(uA!5[n}ظi5T mNH.7ͫGÚ;Z6{ DV$R%JL|6p 1$."|s~+Pl^ɬ, {>T! h)hڑoF) $6FiF߁WO1v6m?I~RXZC̏=]_z`E~)CCH|@3lN_t3K OcqZ T*M& $@VZR! ;J"B0L׶=.gg$Ъ0^K_DH= T{ݷb}b(k'YC1r$;GO1WIt b ?g*29ҴAƽrFE#S($7r(1?RR'ceO˕55Ic:)".% ?tA Fɀ ,4n$p2xi&=Y478/4@=G!HmM{h]L 1_cU}hnb"l k\<,~ԿsXH:[n{/qe}x M Ʌ$S>}/Wg(o(UxS::(]3olJgn}i [#Ec|9w%tP -gE' ^TOd5x=/`I{?As+i} 1)oj!q]r.kO]Շյ\o'"@I*W:KOml3 Eh]}$Skf,6dm< ɁW9g NB8?Β$Sヘ_}K ce@JE$&5\Rjh=$L, |2q?:|8vEԤiM7Kƺ1Mކ;K tݿEԦNE?bKӵM/& }?#:CbRSR{=ks6~GB0ژ@o}t/aGAHMMVDzIxs|헦oivpaNN$S7 VU8.>/M/BF>[/nۯbV (xg_ȷ|R F1`"^ pBA=lÎp'agFcg32:}=IFVw*_ Uo+cwi ~׆IAB06O^ƚw)g@J?fzuhE'6W|5-w=˓}&u =c3c:f.&h6Xoi}lULžDB~>+r[|O'/%VM%0Ըߦc,#Ȗ.!d%=lc!~CdkwQ7^U{wr6*{$;?BLah79W~0IԳ34v$GhLm̷=jc{6a>"ŤƎ}1^椱1ʉ kmݷJ#Lm`mbY4Tzظ0cH wmy=A6x׾sœ'U %/Рֵw{YCc?͚,}^5fӎG"7,  ~*LJSB!yOE㌧u*QlwoO_{a8{t39fwI]&T#D!8V;7ƭ+D6YqݼM <w>}I#M2XT,nvϜ&Αh&:ZNb-ϖ47q:%qvY9۴ ˧?-7D%T4lZNՇغf3>U}o<Å3Q'N~깁- 2e*\Z@i]H8*`yևI6B$SXkHgYXL! !A%7uP~[+m‘!B!iWJ h!B@Ғ95wD lK ,AD 08M̘妥B,M(-YÊ%la7* @a +PXAV 4>m nsMO] [f蝛^Mlz5w-AYHƍ1k< ,;qctHr yd:zܙ;[x;aR:z0䮦{Pc8M$X.q7:վxw?WZehɃ9۳\k R},k@8O|.MϑySo?ϝwZCw۴GiP~ewHǟ~20p RgMO_Xw2&Ft8 Lì`쏎_|dcnlq[dGӻ TGTa;>Mw>rBiF^4߫|Tg ꅩ'?\H@am9O?v9hNEZm:@6<^O*PˁfҮE]T\{9<Ƚ^ExGwUXȏE,rSmS9P`ȹZq.曹Dndbr%.tK(pp-WI^<62{< ZOyra.DB,H\nqccFBhs1??[ 0ɽֶ֒99황s"Q®z;͍c#x@9Tσ_{B|\E2 vTx$p-`+EZPrrgx_`h%-}^W\䲃'¼_ \g}AŽƋf⹱Hnp/xS-IENDB`stimfit-0.16.7/src/stimfit/res/stimfit_32.png0000664000175000017500000000732614750344764014525 PNG  IHDR szz pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxėKlTe;wL;mi()hJ Q4ڄ$иp1&nݺӅ Ba (*@$)>{\tN|;sw󿢪,XnyCS=j#"bLX>݉0}NԖXê΂Ʀ7˦<|fc ŞNGC/dWt|8슎Bc.| ij57j-ߪ<:3iyXC |( V~Up.K=|8]o#bƋrJ:i 뻸g爓WG"ͅ$C(J'ΣX W7%u=ObA'!C)pj[6!}GGJt1D,b2&N jtD#LXE,g,z Zz/xMIoޏPcKR>CTqս<=wQ=B8V"S,;AI̭!ղ5?Q'&U2|}v`.1yߎ d7Tf1!A^#~+sMmc c #4C9545", ", c #50924B", "< c #509A48", "1 c #539E4A", "2 c #559A4E", "3 c #579951", "4 c #57A24E", "5 c #59A650", "6 c #5DAA53", "7 c #5FAD56", "8 c #63B259", "9 c #65B45B", "0 c #68B85D", "q c #6ABB5F", "w c #6CAD65", "e c #6DBE62", "r c #7CBF76", "t c #6FC063", "y c #70C265", "u c #72C566", "i c #73C667", "p c #74C768", "a c #7EC079", "s c #80C17A", "d c #82C27D", "f c #85C37E", "g c #87C581", "h c #89C682", "j c #8CC785", "k c #8EC987", "l c #91CA8A", "z c #93CB8B", "x c #95CC8E", "c c #98CE90", "v c #9ACF93", "b c #9CD094", "n c #9FD296", "m c #A1D398", "M c #A3D49A", "N c #A5D49C", "B c #A7D69E", "V c #A9D7A0", "C c #ABD8A2", "Z c None", /* pixels */ "ZZZZZZZZZZZZZZZZ", "ZZZZZZpuyeZZZZZZ", "ZZZZZZuCC0ZZZZZZ", "ZZZZZZtBN8ZZZZZZ", "ZZZZZZqMm6ZZZZZZ", "ZZZZZZ9nn4ZZZZZZ", "ZZZZZZ7vxjh$ZZZZZZ", "ZZZZZZ2gf#ZZZZZZ", "ZZZZ:*wds,+oZZZZ", "ZZZZZ%3ar=XZZZZZ", "ZZZZZZ@;=XZZZZZZ", "ZZZZZZZoXZZZZZZZ", "ZZZZZZZZZZZZZZZZ" }; stimfit-0.16.7/src/stimfit/res/event.xpm0000775000175000017500000000074514750344764013704 /* XPM */ static const char *event[] = { /* columns rows colors chars-per-pixel */ "16 16 4 1", " c grey32", "x c grey48", "X c grey64", ". c None", /* pixels */ "................", " X......... x", "... X........ x.", "... X....... x..", "... X...... x...", "... X..... x....", "... X....X X....", "... X.... X.....", "... X...X ......", "... X..X .......", "... X.X X.......", "...x X X.......", "...X X........", "....X ..........", "................", "................" }; stimfit-0.16.7/src/stimfit/res/table.xpm0000775000175000017500000000435614750344764013654 /* XPM */ static const char *table[] = { /* columns rows colors chars-per-pixel */ "16 16 100 2", " c #7CBE76", ". c #80C17A", "X c #84C37E", "o c #4277BB", "O c #5284C3", "+ c #5486C4", "@ c #5586C6", "# c #5687C7", "$ c #5D8AC5", "% c #5C8AC6", "& c #5F8CC6", "* c #598AC8", "= c #5B8AC9", "- c #5F8DC8", "; c #5E8ECB", ": c #5F8FCB", "> c #6392CE", ", c #6493CE", "< c #6896D1", "1 c #6A97D1", "2 c #6E99D3", "3 c #6F9BD4", "4 c #729ED6", "5 c #74A0D7", "6 c #75A1D7", "7 c #7AA3DA", "8 c #7AA4D9", "9 c #7DA5DC", "0 c #7EA8DD", "q c #89C682", "w c #8EC987", "e c #93CB8B", "r c #98CE90", "t c #9DD094", "y c #A1D398", "u c #A5D59C", "i c #80A9DD", "p c #82AADF", "a c #84ACE0", "s c #87AEE1", "d c #88AFE2", "f c #8CB1E3", "g c #8CB2E4", "h c #8FB4E5", "j c #90B5E6", "k c #93B7E7", "l c #94B7E7", "z c #96BAE9", "x c #98BAE9", "c c #9ABCEB", "v c #9BBDEB", "b c #9DBEEB", "n c #9EBFEC", "m c #9FC0ED", "M c #A6C3E9", "N c #A1C1EE", "B c #A2C1EF", "V c #A9C4E8", "C c #AAC6E9", "Z c #ACC7E8", "A c #ACC6E9", "S c #ADC7E9", "D c #ACC7EA", "F c #ADC7EA", "G c #AEC8E8", "H c #AEC9E9", "J c #AEC9EA", "K c #B0C8E8", "L c #B0C9E9", "P c #B0C9EA", "I c #B2CBEA", "U c #B3CCEA", "Y c #B5CCE8", "T c #B5CDEA", "R c #B7CEEA", "E c #BACFEA", "W c #BAD0EB", "Q c #BBD0EB", "! c #BDD1EB", "~ c #BED2EB", "^ c #BFD3EB", "/ c #D8E2F0", "( c #DBE4F1", ") c #DBE5F1", "_ c #DEE7F2", "` c #DEE7F3", "' c #E2EAF4", "] c #E6EDF6", "[ c #EAF0F7", "{ c #EBF1F7", "} c #EDF2F8", "| c #EEF3F9", " . c #EFF3F9", ".. c #F0F4FA", "X. c #F1F6FA", "o. c #F2F6FA", "O. c #F2F6FB", "+. c #F4F7FB", "@. c gray100", "#. c None", /* pixels */ "#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.", "#.#.B m b v z k k g d a i 9 7 #.", "#.B +.+.+.+.+.+.o.o.+.+.+.+.5 #.", "#.n +.u y t r e w q X . o.4 #.", "#.v +.@.@.@.@.@.@.@.@.@.@.+.1 #.", "#.x +.M M M M M M M M M M +., #.", "#.l +.M @.C @.@.@.A @.@.@.{ : #.", "#.h o.C A A A H K Z K K Y _ * #.", "#.g O.J @.K @.@.@.H @.@.@.) @ #.", "#.a o.U U U U U Y Z A K H / @ #.", "#.a .Y @.W @.@.@.W O.@.@./ & #.", "#.9 .W E ! W E ! Y Y T Y / % #.", "#.8 .^ @.! @.@.@.A @.@.@./ & #.", "#.5 .[ ] ' ` _ / / / / / / % #.", "#.4 2 < , ; = @ O O O O O O o #.", "#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#." }; stimfit-0.16.7/src/stimfit/res/resultset_last.xpm0000775000175000017500000000322314750344764015632 /* XPM */ static const char *resultset_last[] = { /* columns rows colors chars-per-pixel */ "16 16 83 1", " c #1239B6", ". c #133AB7", "X c #133CB7", "o c #143EB9", "O c #1441BB", "+ c #164ABD", "@ c #1752C0", "# c #1855C0", "$ c #1959C4", "% c #1859C6", "& c #195CC6", "* c #1A60C6", "= c #1A62C8", "- c #1A63C8", "; c #1E6BCD", ": c #2A72CF", "> c #2C74CF", ", c #397BD1", "< c #397BD2", "1 c #4281D3", "2 c #4481D3", "3 c #4685D6", "4 c #4E80D2", "5 c #4B87D6", "6 c #4584D8", "7 c #4E89D8", "8 c #5385D4", "9 c #578BD6", "0 c #528BD9", "q c #5E92D9", "w c #5E94D8", "e c #5990DD", "r c #5C92DF", "t c #6397DA", "y c #6095DF", "u c #6297DF", "i c #6699DD", "p c #6A9BDC", "a c #699DDF", "s c #6E9DDF", "d c #709FDE", "f c #74A3DF", "g c #76A3DF", "h c #659BE1", "j c #73A2E0", "k c #70A0E2", "l c #72A2E2", "z c #77A6E6", "x c #7AA6E5", "c c #7BA8E3", "v c #7EA8E1", "b c #7FA9E3", "n c #7FAAE3", "m c #7BA7E8", "M c #7EA9E8", "N c #81ABE2", "B c #82ABE3", "V c #83ACE3", "C c #85ADE4", "Z c #84AEE4", "A c #86AEE4", "S c #80ABE8", "D c #87B0E6", "F c #89B1E4", "G c #8AB1E5", "H c #8BB2E5", "J c #89B1E6", "K c #8BB3E7", "L c #8DB2E6", "P c #88B0E8", "I c #91B6E8", "U c #92B7E8", "Y c #94B7E8", "T c #97BAEA", "R c #98BBE9", "E c #9ABCEA", "W c #9EBEEA", "Q c #9EC0EB", "! c #A6C3EE", "~ c #A5C4ED", "^ c #ABC8EF", "/ c #ADC8EF", "( c None", /* pixels */ "((((((((((((((((", "((((((((((((((((", "(((SM((((hue0(((", "(((SMk(((rJE6(((", "(((z/Pu((0AY<(((", "(((k^!x7(3cL>(((", "(((h~TWa<V2&((@8tO(((", "(((;1%(((+4tO(((", "(((=#((((Oo (((", "((((((((((((((((", "((((((((((((((((" }; stimfit-0.16.7/src/stimfit/res/stimfit_256.png0000664000175000017500000004353514750344764014617 PNG  IHDR\rf pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FJA BJ@$\x XIpOTumcN=:p"9Go:A@bIVY_7/W p!C +I8ԅR?.U)$*=pD FX#r3 GHB doS+IVnx٫N2 A45h[ja$,- T2L} m82t[?"­XQXraODгP`pD&F;Hici805A $%Ħnl@:~鋣;;$ AD `1ؗB[o685! (Y&rlfl?o&'$eAd Ki);"YMm~1 q'лq*/lOw9|FW d׽HTlAܭa,R p@'ސAf!el[>9_W8Up+z" eP#N属H34¾A{f.;?s!{f^{_̺ z 67-w,__>0\IP,E,FycV=1wj[4e .dG5GҿSP@t dxxxj2,o@Ȱ,0AGг)I+5kDQ@U.2uiG3&BȀw [dv/FGؙ+}[Aٻ$#OecO+#HUB uV.05q3Oѷ[};*#}[Pa8ϧ'Kh SLRt"Lڵ$qR.c=aeo#x5_bPA9 @"2 %rJ!D3l9 O/&z/$΅K؂tF9=Xk8'B'U?y\4MPH_HTHQ  Xg!D&c>J\ԷOV6vƕPai %eS dRup) X,)&"`H\ ۚ'O:oaR*P) !4~k-F Dis@ ޟE')n"*dtuڥgQiJ)tRpDȖ@bҬAėӿMhU]O$s*"ȭM [nsId; t+ h>iT%OߤsI@Q~ȦO]!IbB I P(% D@QV3uψ/8k.=<?;z>=D}d* ڎ*CL tcMVoiy*5 \d?B"HD[p-n'R?zTOF1q=1c+b#("iH@Z, r Y$@HɻA/_"ܴ @JgDHYjKi卟;PMp(p'N l;IܨJO BJE3û+SDZZnhnIۀD` iP[lw .JՅ"{qS&axWX?D虋M&l*+ ~ ]!q\ xxXf V'9$ 61RfhD*$j@$=+q gw<<,5:4`AلM~ y6/{+w=ӍtǠkY18PP/gJR?kx:̣KY!m8\Ƹ}Èg fmHWq>+ `))>tvZb8 z6ɽXSna}?6%$t࢔xjv >o+i7a<<, >fӁK Pqδ^!vqn6X+dF9w PYP ,/k@ L[x:璈@؃K!k ?t* 2=Tk^xxXl kcLɃ\oaewXkP=@̵_"kX?>D1HX@["plj8zWbDH3,'@g.j hLQ[|7B`ssYs3踊 `Vg"L}k6ZƖ8 }1NWfTc/iߓy %]e᠌*'+1AO`i @c{ zk#q)! J4ؖ \@*%et452>Tv͸9B0ncGU37NNZf0P( i2:zWǵjʕ.ku; (m\D3D~ÌMT@2hՓ9c@&ǤP/i]Og$ UAuIJޭX5Xپ6~:u2is$жuX(!Ow<x\*,&֧s pYշcukqP}ۈU@x3i訚'0N7е1|02DnZ4oc=!21R& vh*>fL~g/WƦ~'O B߹fc_HEPL\XwqvZw=(3I/gЍzw ]g\{8ZUڀ {X 9R:6`ͬXrPHP*WbG0x c>@WF:(oI,D@K)٨2W՟8TTFs<x,j:kYRf rmB̚Lpg`!'6w 3Yf DILHܘIӖ<xt0pKTqCOYkS !öEI 5*mJ[* / Q 1jG?+ij'bg"0CSVߵHĨZ}')o["@ f\5 {ї~it\knt46ulm쪒 w`^a-8Kqnͩ+Pkf O+J4x%tT#<x[HR7k-R},ٿ\uƭCFlFXM݀u/iZ0@"BeD\gэItc{%6lcFε\_^gz1> `28!ȭ6}ҢZW@"8P.0dHw un1 ݄ C/~1l_`uxbS,domqg5};0tMbGko|m5JWtPL\JИa'x'iLM]@ 3+I!΢dHau^w wqnFR" V<@䆎"[.xS<&c4/Z'fo;qIlKlUa# y]犮sG(o6ƹքbt 4{ T#3_N[cl2IQw Lп)\d$FyHsh2~!iPr̜~<ܐ @4ur0س5Ϧ~Y*S޼DrQq>¡G~#$Bm<P@2s'4e 柬\@y6bL[Ë1v|XGHds̘u(U($1O> u4Mu@k7$AV- 6n3m+0ds=eǞףu!h \5C[, )@4Ǝ1_<qDjGMZ$ol̦wq$Sqqic!ztAjK|)H@x>ƒs Hz !?Ԇ_Lk xXtHF"N=ВFzI4̥rzVy6+/7OO}V]D'iL_ 8sM׹eÄRՍDثVYSթEzMH\F%&/rFs8cu1EcfU&V_'?i@JN&l@>k/2uڔPzRbA/Sgoc::Gֈ[WǨ\1sF q}!1o;&/<4,?~[s7X+Mpc+1RA?Js<4f.&<,_!5Aȩq+عo"UiV*_\R$YfJWI0RvD6a|tke.L}GkX_֣:BȀI.?KTA'>ud\ZRrVu=]<ߘaf<6#УO?qg;%smt&N=o}Boĵqc )# [I25߉?I]%hyc !oB04ǫܽm=MN"(5wB6) k 3 zGR+:77zqu DN|gFʀyR.ӥAdXm{gq>N. ƐG͞HY5 z gd]zXLwUG6>}cOSC@˴ iNO6(mNF8.V I.uAku*Ȩ6E@HF-ɳi#Q<\28?N|w6wms<; r5s,P8`M\5:b3WDc-ЇulVG,EJ43r1qݫOp}8mE5%_"iK21;xPGS޷AN9tCl>F: 2WMJ\<,: '{\~3s_pDmV+C$p/ě-FH&: ŸJ-呇>K)*$ 1zˉ @O 2~g+8kO_Sov^ ;.@6 Gz2O*6lk_qoa'q&^ҿ28س:bl,4+V*dȉ/Q=VzTX@BLLTKv ?o;3mU}.U-iOIEI\_ǣ7ohiF]LM!yqwp6X>K΍D"3|oYh iVGDQ=uN? t4w"C AI$FHE_vz{{wPHFUt}Gv>Op?G=MoSaԙcb1 ;n3X D}6@2t, 77 UMvelq[w!! ]㥸S'r4 /#|70MMUkVOwdTFR=dƟtkO>Ʌ_.sՓ{_OOy#&2 .Uc6F"/8ߘwr?cT\*Uog`I?F7`h>8?2ts)&$=B^[L4̈́l"&qx^mLq9gZ}Z7zoۼ/.%e4F_+(#w+dۈô $H"j'?}׸}V_5 ((!ݰwx?d}ÍIlD.6H\mɃ>@l"d:7 !O(gX MШ ד qIk܇sdw g&+¹O?%wη.y1PuƗ.K6 O'/|ɉ8\@5&.>ùGn{?E7&[jqyK -.owXd5QKg*wS\,NHbB8.?g {3p AT?yP=mtcba1 SsWFظ=1Ѭ`0`jL7x;ozqq;w HI]EUFwORkLn|cQ[uէ,k#罜~D(CbeLl,DOKD'tU݀`:r1ͤ HlU3 8wk2 Nq}k]t@<;G W q4fƿ>CSD2}ovyc@vYh g|Ϛu,)x?`Ͼ7#^G`%ĬyM8B0bQ*;g^TH NVF um#H<#e[^q?]ЧJk-XC *I'ݻ؉/s1:|jm m59b+wCPyw`S1ۃ^}};sf|cGUGFcl6%*\/~Xd@ߕT)L݂'UKgx.ܢlT!îM(Vg2L6JWWG6F51xf޿U.mDJ5.>Cʐmsjvp7uA"p%`Dl![U&Rް6I  s9k PR-%ݠ$Cq+51*ǪF6Wlİ)!)Rу,$%!QBdF4j5 ! &Lb|Q\W?ړЄѓzt\*lb5@16p.<7zk߸eo}H0G`tқ!ғzo=X&.6N;#d8Ÿo2\.~'7>oyG潷X!_Hҥ"%*Z ,V6Y`MV|AHg.]8gUkYo\{l +}ہ nLN'^ZݺI!d*Lf#rhX= u7k\lK;&!kcӧ'Xzqm֢eq"g2 ^P@9ߓ;^m"T D !H(Xg_swmT.ĵ闾yzgՁZQzk dapU6HЉ2($P@oVmcGB!J@ dW$x, כhɀ|,ןdPT'N~^;~`<d 0+N_r/R-(@[rOlGiIZtc]||JW!&b߿ܧUG?t[3s?+\ P@OA r_~MځCgp@xt5?M[㒝BaL+/:ߘr\/?1"0PT䉠1۸;6z侁z W "lz!=V>8c⚉j3W;5~{G=s)qࣜ E-@l'QP܀  s@GFATzw6 {DSE[~XGӓWjg~^]\~r@77@-+ :X82bP>8Ic)X F>ݣH #x_LZw=, ޸6ΑFu:D'ҧ<Š(H8t&઱oX'[EUZ;:tBI芥 (wu1k.`%.|/ ƚSj6xn@7.]H`.M+EEt`rƘw D9Ob7\'k\P$]QoTm'^戠Q >'Pb5bb_Ņ]0"ЅŽ@2&"PtdD"V{~^9 OKmE[M  a.Ӗ`VqٜQc*gne:o+Mv7tnn6X 2D ?|ke|c9މLCׅsX:;2æ Ȫ bj!NNnİ߭K@Zeo\\A {8@xn~K2h'+ t/iv =g+\E@<bEb/D\wAH@tYF_,)yXt78:fϘW卞B< ;Ifn_7zTv@^^ԟWUs n.C) c #9D9D9D", ", c gray62", "< c #A0A0A0", "1 c #A4A4A4", "2 c #A7A7A7", "3 c #A9A9A9", "4 c #AAAAAA", "5 c gray68", "6 c #AFAFAF", "7 c #B1B1B1", "8 c gray71", "9 c #B6B6B6", "0 c #B7B7B7", "q c #B9B9B9", "w c #BBBBBB", "e c gray74", "r c gray", "t c #C1C1C1", "y c gray77", "u c #C5C5C5", "i c #C6C6C6", "p c #C8C8C8", "a c #CBCBCB", "s c #D0D0D0", "d c #D5D5D5", "f c #D7D7D7", "g c gray85", "h c gray86", "j c #DFDFDF", "k c gray88", "l c #E1E1E1", "z c #E2E2E2", "x c gray89", "c c #E4E4E4", "v c gray90", "b c #E7E7E7", "n c gray91", "m c #EAEAEA", "M c #ECECEC", "N c gray93", "B c #EEEEEE", "V c #EFEFEF", "C c gray94", "Z c gray95", "A c #F4F4F4", "S c gray97", "D c None", /* pixels */ "DDDDDDDDDDDDDDDD", "DDDDpuDDDDDDDDDD", "DDDDugeDDDDDDDDD", "DDDDtSdqDDDDDDDD", "DDDDeSVa6DDDDDDD", "DDDD0SVVp2DDDDDD", "DDDD0ZncVu,DDDDD", "DDDD6Vczzct;DDDD", "DDDD6Vzzzccq%DDD", "DDDD2Zzcc;*%$$DD", "DDDD1d,aV*DDDDDD", "DDDD,,D;gt$DDDDD", "DDDD,DDD6Z@DDDDD", "DDDDDDDD@gqODDDD", "DDDDDDDDD4g.DDDD", "DDDDDDDDDO. DDDD" }; stimfit-0.16.7/src/stimfit/res/arrow_left.xpm0000775000175000017500000000212514750344764014721 /* XPM */ static const char *arrow_left[] = { /* columns rows colors chars-per-pixel */ "16 16 45 1", " c #205E1D", ". c #246321", "X c #296925", "o c #2F702A", "O c #35782F", "+ c #3B8035", "@ c #42883B", "# c #499141", "$ c #4F9947", "% c #56A14D", "& c #5CA953", "* c #64AA5B", "= c #62B158", "- c #68B85D", "; c #7BBE71", ": c #78BD72", "> c #7CBE76", ", c #71C365", "< c #74C768", "1 c #7EC078", "2 c #80C17A", "3 c #83C17A", "4 c #82C27D", "5 c #84C37E", "6 c #86C87B", "7 c #87C97C", "8 c #8ACC7F", "9 c #87C581", "0 c #89C682", "q c #8BC785", "w c #8BCD80", "e c #8EC987", "r c #90CA89", "t c #93CB8B", "y c #95CC8E", "u c #98CE90", "i c #9ACF93", "p c #9DD094", "a c #9FD296", "s c #A1D398", "d c #A3D49A", "f c #A5D59C", "g c #A7D69E", "h c #ABD8A2", "j c None", /* pixels */ "jjjjjjjjjjjjjjjj", "jjjjjjjjjjjjjjjj", "jjjjjjjjjjjjjjjj", "jjjjjjjjjjjjjjjj", "jjjj:.j", "jj-;3*$#@+OoX. j", "jjj&%jjjjjjjjjjj", "jjjj$jjjjjjjjjjj", "jjjjjjjjjjjjjjjj", "jjjjjjjjjjjjjjjj", "jjjjjjjjjjjjjjjj", "jjjjjjjjjjjjjjjj" }; stimfit-0.16.7/src/stimfit/res/resultset_next.xpm0000775000175000017500000000235714750344764015654 /* XPM */ static const char *resultset_next[] = { /* columns rows colors chars-per-pixel */ "16 16 55 1", " c #1441B7", ". c #1545B9", "X c #164ABD", "o c #1750BD", "O c #164EC0", "+ c #1853C0", "@ c #1859C4", "# c #1959C6", "$ c #1A62C6", "% c #1A62C9", "& c #236ECD", "* c #2C72CD", "= c #3B71CC", "- c #3C74CF", "; c #3577D2", ": c #3D77D0", "> c #3F7AD0", ", c #437FD3", "< c #4384D6", "1 c #4784D6", "2 c #4B88D6", "3 c #538EDB", "4 c #6095DD", "5 c #6197DD", "6 c #72A1DF", "7 c #75A3DF", "8 c #6297E1", "9 c #6EA0E2", "0 c #74A3E0", "q c #74A2E2", "w c #77A4E0", "e c #75A4E3", "r c #79A6E0", "t c #79A7E6", "y c #7CA9E1", "u c #7EA8E1", "i c #7CA9E8", "p c #7EA9E8", "a c #81ABE2", "s c #80AAE3", "d c #81ABE3", "f c #87AFE4", "g c #80ABE8", "h c #80ABEA", "j c #8AB1E4", "k c #87B0E8", "l c #90B5E7", "z c #92B7E8", "x c #99BBE9", "c c #99BBEA", "v c #A1C1EC", "b c #A3C2ED", "n c #A8C7EE", "m c #ADC8EF", "M c None", /* pixels */ "MMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMM", "MMMMhpMMMMMMMMMM", "MMMMhiqMMMMMMMMM", "MMMMtmk4MMMMMMMM", "MMMM9nbe1MMMMMMM", "MMMM8vzx5*MMMMMM", "MMMM3cssj2$MMMMM", "MMMM H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FYIDATx̚[lW93^8v'imS'4mh%BJ-P TE EҦ(C64IظfÃ&qetpYo0L@4B d18'9N6L^а*۱?ʮؕҾBܵ|p]47x?ȟLTy-[?_سO<-s%& >zo?VI`$ HeZXm\T^v۫^ҍkVng܊# 'R3_Mkۋҭ4ȈE\r@&q* r* HlV*JiBP:@^8S @XiVXg(\~G`6y,k\83%hBkWɴ%?O;L䔇$#<҃`*B͗،)S8Bc]3h!G~NT"X#zZ:92)x_*h^!L.z CUS"Qq Abf2w?LRO28 ʫA"ذqk@%PX}?Y)赠g&Cřմ4E읟Cyud;HqDE8 beш7ᮇqBV?ESyG2ڇ"/^n<"{?㔷(vj~%,pkc % e3T=T2so,Qc)"zHqq 9Ch&p Y`VRޙ0Qa%^ЄsKT6%ݶ/\b~d9IyšT& :TC[46Hymta߫ ~uLIy,x*R 1VEGJ-^G<%~cƔgQTC/EK,ëm+壼pK8dۻpZ|%O!VG8tn7+06PF{_su|B}oiç)V {ɭ݃ =aJ#TlȦ;)lTv \;6@D/<Q<S~4 @]=O̞KHdZtflJjf+= &*/WIf7hBfn,EQl$aM$*{˺( 6ϏCLDԶ%_|'7t~|7"v6;:``|m2bB3p}O1Gϡ0AQgb3T=?6-XH!ήaGGgyU;4e[.{l*wcד,ք |Oa7ie:*+lB>WsMHK|4^.# De.: ŀ]rh`}t/@2p(Pk;Czmk/xG5[nrp8pq qQ%h8:nM5[DŵLù|:dRU '.}Nd85iOGqç n6Sۡ /኉vzPPk|r_{ykN(Ȕ'ΏՋ#g_{8 \&+@6e[uja8̹o ''N+9`R%xu@hK$@u@ (ϏE ~C35kA0n7 KRKZa9ia$J((a^ҪޘqIENDB`stimfit-0.16.7/src/stimfit/res/stimfit_16.png0000664000175000017500000000634314750344764014525 PNG  IHDRa pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxڤKTQ?7ofI&C#,!Zբڶ jm/ M Zjނ,@dLSgL7{"B 9|=DUA.?|z|j{nf?/<$v(w yX['3JY4CƢ&!SdNw3X{EV;{ڀNzh2?bPħ1= KIkUP&I@? c gray26", ", c #444444", "< c #464646", "1 c gray28", "2 c gray29", "3 c #4E4E4E", "4 c #505050", "5 c #535353", "6 c #565656", "7 c gray34", "8 c #585858", "9 c #5A5A5A", "0 c #5B5B5B", "q c gray36", "w c gray37", "e c #5F5F5F", "r c #606060", "t c gray38", "y c #626262", "u c #646464", "i c #656565", "p c #676767", "a c #686868", "s c DimGray", "d c #6A6A6A", "f c #6C6C6C", "g c #6D6D6D", "h c gray43", "j c #6F6F6F", "k c #717171", "l c #727272", "z c #747474", "x c gray46", "c c #767676", "v c gray47", "b c gray48", "n c #7C7C7C", "m c #7E7E7E", "M c #857C69", "N c #9B937F", "B c #F3BE41", "V c #5C96D5", "C c #5E96D5", "Z c #5E97D6", "A c #5F98D6", "S c #6496CE", "D c #6899CE", "F c #689ACE", "G c #6397D0", "H c #6397D1", "J c #6496D0", "K c #6099D6", "L c #6299D6", "P c #609AD6", "I c #629AD7", "U c #639BD7", "Y c #669BD7", "T c #649CD7", "R c #659CD7", "E c #699AD4", "W c #6A9AD4", "Q c #619AD8", "! c #659BD8", "~ c #669CD8", "^ c #679CD8", "/ c #679DD8", "( c #669DD9", ") c #699ED9", "_ c #6A9FD9", "` c #6AA0D9", "' c #808080", "] c #818181", "[ c #848484", "{ c gray52", "} c #868686", "| c gray53", " . c #888888", ".. c #8B8B8B", "X. c gray55", "o. c #8D8D8D", "O. c #8E8E8E", "+. c #909090", "@. c #929292", "#. c #939392", "$. c #939393", "%. c gray58", "&. c #959595", "*. c gray59", "=. c #979797", "-. c #989898", ";. c #9A9A9A", ":. c #9B9B9B", ">. c #9D9D9D", ",. c gray62", "<. c #9F9F9F", "1. c #8393A3", "2. c #95A5B8", "3. c gray64", "4. c #A5A5A5", "5. c gray65", "6. c #A9A9A9", "7. c #AAAAAA", "8. c gray68", "9. c #AEAEAE", "0. c gray69", "q. c #B4B4B4", "w. c #B7B7B7", "e. c #B9B9B9", "r. c gray73", "t. c #BCBCBC", "y. c #F9E0A4", "u. c #A2B3C5", "i. c #B7C7DA", "p. c #C0C0C0", "a. c gray77", "s. c #C6C6C6", "d. c gray78", "f. c #C8C8C8", "g. c gray79", "h. c gray80", "j. c #D0D0D0", "k. c #D2D2D2", "l. c #D5D5D5", "z. c #D7D7D7", "x. c #D8D8D8", "c. c #DDDDDD", "v. c None", /* pixels */ "v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.", "v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.", "v.-.+... .] v k h c ..v.v.v.v.v.", "v.-.f.f.s.a.N y.B M +.v.q q q v.", "h 9.k.0.5.,.w.=.4.u.7.l a a a 5 ", "h t.5.t.c.z.z.h.5.[ =.q.,.o...: ", "a 5.r.i.W C V H u.=.k 9.-.a N # ", "p -.x.W L Y T A S 9.w 6.@.w b $ ", "i %.j.C ! ` ) R L 4.5 5.X.7 c % ", "y o.d.A ! ) ` ) L :.4 ,.{ 3 h $ ", "r | r.S U ! ! ! D X.2 -.' 1 a $ ", "w m ..2.S T ! D 1.0 : =.n : u O ", "7 j a b :.-.$.{ 8 ; p +.z t 9 O ", "v.$ $ , , : - * @ o . . . ", "v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.", "v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v." }; stimfit-0.16.7/src/stimfit/res/slope.xpm0000775000175000017500000000164014750344764013700 /* XPM */ static const char *slope[] = { "16 16 37 1", " c None", ". c #5297DA", "+ c #3E678F", "@ c #2A80D3", "# c #6D9BC8", "$ c #2981D5", "% c #2485E1", "& c #3176B8", "* c #318AE0", "= c #2C7DCB", "- c #2A7ED0", "; c #5998D5", "> c #2A7ECF", ", c #5897D5", "' c #6099D1", ") c #6F9BC6", "! c #287FD3", "~ c #1E90FF", "{ c #2C7BC8", "] c #2783DA", "^ c #5F99D0", "/ c #2581D8", "( c #5196D8", "_ c #2E7BC6", ": c #2C8AE5", "< c #2F7AC3", "[ c #328AE0", "} c #2782DA", "| c #3488DB", "1 c #2882D7", "2 c #348ADD", "3 c #2B7FCF", "4 c #2980D4", "5 c #2486E4", "6 c #1F8DF7", "7 c #3E94E8", "8 c #4B85BC", " ", " ", " .+@ ", " #$%&# ", " *=#@-; ", " @;@#>,@ ", " @'@@)!~@ ", " @'@ @){~@ ", " @'@ @]^~@ ", " @'@ #/(@@ ", " @'@ _:~@@ ", " @'@ <[~@@", " @'@ }|@@", "@@@1'@ =2@", "34567@ @8", " "}; stimfit-0.16.7/src/stimfit/res/latency_lim.xpm0000775000175000017500000000107714750344764015062 /* XPM */ static const char * latency_lim[] = { "16 16 13 1", " c None", ". c #678FB1", "+ c #97B4CD", "@ c #DCE9F5", "# c #97BDE1", "$ c #DBE8F4", "% c #95B2CC", "& c #72A6D6", "* c #EBF2F9", "= c #AFCCE8", "- c #96BCE0", "; c #D6E5F2", "> c #96B3CC", " ", " ", " .. .. ", " .+@..@+. ", " .+@@..@@+. ", " .+@#@..$#$%. ", " .+@#&#**#&#$+. ", ".+@#&&&==&&&-@+.", ".+@#&&&==&&&-@+.", " .+@#&#**#&#$+. ", " .+@#@..$-;>. ", " .+@@..@@+. ", " .+@..@+. ", " .. .. ", " ", " "}; stimfit-0.16.7/src/stimfit/res/resultset_first.xpm0000775000175000017500000000314714750344764016023 /* XPM */ static const char *resultset_first[] = { /* columns rows colors chars-per-pixel */ "16 16 80 1", " c #1233B2", ". c #1239B6", "X c #133CB7", "o c #143EB6", "O c #1441BB", "+ c #164ABD", "@ c #1752C0", "# c #1855C4", "$ c #195AC4", "% c #1859C6", "& c #195CC6", "* c #1A62C8", "= c #1E69CB", "- c #1E6BCD", "; c #3364C6", ": c #386BCA", "> c #2C74CF", ", c #3D77D0", "< c #397BD2", "1 c #4481D3", "2 c #4180D4", "3 c #4384D6", "4 c #4784D6", "5 c #4A85D6", "6 c #4584D8", "7 c #4A89D9", "8 c #4C89D8", "9 c #5089D9", "0 c #528BD9", "q c #538DD9", "w c #5E91D8", "e c #5C92DF", "r c #6397DA", "t c #6297DB", "y c #6597DB", "u c #6497DD", "i c #669ADF", "p c #6A9BDC", "a c #6B9CDD", "s c #699DDF", "d c #6E9FDD", "f c #6D9DDE", "g c #6D9EDE", "h c #709FDE", "j c #71A1DF", "k c #76A3DF", "l c #659BE1", "z c #73A2E1", "x c #70A0E2", "c c #77A4E1", "v c #77A6E6", "b c #79A7E1", "n c #7AA7E0", "m c #7BA8E1", "M c #7EA8E1", "N c #7EA9E2", "B c #7EA9E8", "V c #83ACE3", "C c #85ADE4", "Z c #86AEE4", "A c #80ABE8", "S c #80ABEA", "D c #8AB1E5", "F c #8DB2E6", "G c #8EB3E6", "H c #8FB5E7", "J c #8FB4E8", "K c #90B5E6", "L c #90B4E7", "P c #91B6E8", "I c #96B9EA", "U c #98BBE9", "Y c #9DBEEC", "T c #9EC0EB", "R c #A2C1EE", "E c #A5C4ED", "W c #ABC8EF", "Q c #B0CBF0", "! c #B4CEF2", "~ c None", /* pixels */ "~~~~~~~~~~~~~~~~", "~~~~~~~~~~~~~~~~", "~~~SSBv~~~~q0~~~", "~~~S!Rx~~~876~~~", "~~~vQYl~~5aP<~~~", "~~~xWIe~4lJF>~~~", "~~~lEJ01uKMC-~~~", "~~~eTU3xFbaM*~~~", "~~~0UF=1mrh@~~~", "~~~Vy*~~+:rO~~~", "~~~-mw%~~~o;X~~~", "~~~*&#@~~~~ .~~~", "~~~~~~~~~~~~~~~~", "~~~~~~~~~~~~~~~~" }; stimfit-0.16.7/src/stimfit/res/arrow_up.xpm0000775000175000017500000000246414750344764014421 /* XPM */ static const char *arrow_up[] = { /* columns rows colors chars-per-pixel */ "16 16 60 1", " c #22601E", ". c #256421", "X c #266522", "o c #296925", "O c #2B6B26", "+ c #2D6E28", "@ c #30722B", "# c #33752D", "$ c #367A31", "% c #397D33", "& c #3D8236", "* c #3F8539", "= c #438A3C", "- c #468D3F", "; c #4A9242", ": c #4C9545", "> c #509A48", ", c #539E4A", "< c #58A44F", "1 c #59A650", "2 c #5EAC55", "3 c #5FAD56", "4 c #65AC5D", "5 c #65B45B", "6 c #68B85D", "7 c #6EBF62", "8 c #78BD72", "9 c #7ABD74", "0 c #7CBF76", "q c #70C265", "w c #71C365", "e c #72C466", "r c #72C566", "t c #73C667", "y c #7DC073", "u c #7EC079", "i c #80C17A", "p c #83C679", "a c #82C27D", "s c #86C37D", "d c #85C37E", "f c #85C87B", "g c #87CA7C", "h c #88CA7E", "j c #87C581", "k c #89C682", "l c #8CC785", "z c #8EC987", "x c #91CA8A", "c c #93CB8B", "v c #95CC8E", "b c #98CE90", "n c #9ACF93", "m c #9CD094", "M c #9FD296", "N c #A1D398", "B c #A3D49A", "V c #A5D49C", "C c #A7D69E", "Z c None", /* pixels */ "ZZZZZZZZZZZZZZZZ", "ZZZZZZZrwZZZZZZZ", "ZZZZZZrhg6ZZZZZZ", "ZZZZZrgCV93ZZZZZ", "ZZZZw7pBNs<,ZZZZ", "ZZZZZZ5MM4ZZZZZZ", "ZZZZZZ3nv>ZZZZZZ", "ZZZZZZ1vc;ZZZZZZ", "ZZZZZZ,cz=ZZZZZZ", "ZZZZZZ:lk&ZZZZZZ", "ZZZZZZ-js$ZZZZZZ", "ZZZZZZ*au@ZZZZZZ", "ZZZZZZ%uuOZZZZZZ", "ZZZZZZ#98XZZZZZZ", "ZZZZZZ+oX ZZZZZZ", "ZZZZZZZZZZZZZZZZ" }; stimfit-0.16.7/src/stimfit/res/stimfit.png0000664000175000017500000000507614750344764014221 PNG  IHDR@@iqsRGBbKGD pHYs  tIME 6l IDATxmUϙwߺKEZ ByRhR"h5QP1  H DAF FHHR–m{޽wfy0vm.gdfdr?u#y$׳}$G\ӤG_;#0~> 2A3+b|U@.yAĉqڨ\t%]hȝS}\|{C8VjC7ԏק S WX.m jYTRFһRڷ7X Brt-\\[TI$g%_֖9ow,ӵz:/ rDi6_GU1X3~ z@m99'm]2 Sπq9u ƤT9nES 0FPm4˟sPdSu76P8T3^8d:`1#NmUuM#G 21H1 [Γ\J+2YQQx{^C.g#Vfih8qXڲt:ȻOg١ 2iAB')Оm#_f߆_L"Buo/o|2<7cbp`1_u BіC{/qud Z Iib1wY'|&O1o1 X@ KxbPO$RG 2-&i!_=u ( QDPux";Qd,l+{/Fv#0IqsϢs"A1UP܆(^) vXb7Q15  ܆pPWEpʊoa{l'bm|X0- Pj^qYjyVDRҬ*N@pP/x\Ђ_Jl 3 Q0BnC|(≡䩼p;Ќۃ?4XQs?b1ĈK(vSG`A \| 9bQ\FUZ/(eMbx_ZdC.\jͭ vtUzV|0!g)vnj6=Xy՗YDk\'\Ig0#x V-|a\ )/ |'YQ3@T" %w|"[;°9sI6o? ?1 |SGdCZ]6R!孨٫n"x~Vڃ L>47JlfT# GZz\UɋVADu8%f/I0g>P9ͩoރU[$y_9 Puo#Qhoiͬ5]4U'6*;dqhoQ:״lu1Ά |Yqԣ]d+y[8/o?yO#ͺk<ٮc /;`(D~c xzc9] /T/EQgPFvn%1C`.0W<3zV-xbiڦ4GKw c #BC854A", ", c #BC844B", "< c #BB814C", "1 c #BC834F", "2 c #BC864C", "3 c #BD864C", "4 c #BD894C", "5 c #BE894D", "6 c #BE8A4D", "7 c #BE8A4F", "8 c #BC8451", "9 c #C18E4F", "0 c #C18F4F", "q c #C28F50", "w c #C18C52", "e c #C18E58", "r c #C39150", "t c #C39153", "y c #C39156", "u c #C49555", "i c #C69655", "p c #C79757", "a c #C69956", "s c #C79A57", "d c #C89C57", "f c #C99F5B", "g c #CDA45B", "h c #CCA15D", "j c #CDA55E", "k c #CDA65E", "l c #CEA65E", "z c #CEA75E", "x c #C99B61", "c c #CDA561", "v c #CEA660", "b c #CEA761", "n c #CEA662", "m c #CFA762", "M c #CFA861", "N c #CFA864", "B c #D6B479", "V c #D7B57D", "C c #D6B57F", "Z c #DABB80", "A c #DBBF87", "S c #F3A09B", "D c #F4ABA4", "F c #F6B6AE", "G c #DEC48D", "H c #DFC58F", "J c #E0C793", "K c #E3CC99", "L c #E7D3A0", "P c #E8D5A3", "I c #E9D7A5", "U c #F7C0B7", "Y c #F8C8BF", "T c None", /* pixels */ "TTTTTTTTTTTTTTTT", "TTTzvNNhfTTTTTTT", "TTMzTTTTapTTTTTT", "TMgTTTTTTrrTTTTT", "zzTTTTTTTT97TTTT", "vTTTTTTTTTT7TTTT", "vTTTTTTTTTT7TTTT", "vTTTTTTTTTT3TTTT", "fTTTT;-=*&oXTTTT", "apTTT-YUFDS.TTTT", "Tp0TT=*&oX. TTTT", "TT97TTTTwBKG1TTT", "TTT>33,%1APIZ$TT", "TTTTTTTTTeHLJxOT", "TTTTTTTTTT8VVe#T", "TTTTTTTTTTT+:#TT" }; stimfit-0.16.7/src/stimfit/res/sum_new_aligned.xpm0000775000175000017500000000216514750344764015721 /* XPM */ static const char *sum_new_aligned[] = { /* columns rows colors chars-per-pixel */ "16 16 48 1", " c black", ". c gray8", "X c gray16", "o c #2A2A2A", "O c #2D2D2D", "+ c gray18", "@ c #2F2F2F", "# c #313131", "$ c #323232", "% c #343434", "& c #353535", "* c #373737", "= c #3A3A3A", "- c gray25", "; c gray27", ": c gray28", "> c #484848", ", c #494949", "< c #4C4C4C", "1 c #4E4E4E", "2 c gray31", "3 c #515151", "4 c gray32", "5 c #555555", "6 c #565656", "7 c #585858", "8 c #5D5D5D", "9 c gray39", "0 c #646464", "q c gray40", "w c #686868", "e c #6A6A6A", "r c #6D6D6D", "t c #6F6F6F", "y c gray44", "u c #727272", "i c gray45", "p c #767676", "a c #777777", "s c #7B7B7B", "d c #7E7E7E", "f c #818181", "g c #8B8B8B", "h c gray56", "j c #9A9A9A", "k c gray62", "l c gray74", "z c None", /* pixels */ "zzzzzzzzzzzzzzzz", "zzzzzzzzzzzzzzzz", "zzfdspytw9zzzzz ", "zzdlsytwq8zz zz ", "zzzghzzzz6zzz z ", "zzzykqzzzzz ", "zzzzqjzzzzzzz z ", "zzzzz74zzzzz zz ", "zzzz64zzzzzzz z ", "zzz64,zzz%zz zzz", "zzz<:zzzz+z zzzz", "zz<::%%$+oz ---z", "zz:==%$+o. -zzz-", "zzzzzzzzz z-zzz-", "zzzzzzzz zz-zzz-", "zzzzzzz zzz-zzz-" }; stimfit-0.16.7/src/stimfit/res/camera_ps.xpm0000775000175000017500000000604314750344764014512 /* XPM */ static const char *camera_ps[] = { /* columns rows colors chars-per-pixel */ "16 16 143 2", " c #2A2A2A", ". c gray17", "X c #2C2C2C", "o c #2D2D2D", "O c #313131", "+ c gray20", "@ c #343434", "# c #353535", "$ c #373737", "% c #393939", "& c gray23", "* c #3C3C3C", "= c #3E3E3E", "- c #3F3F3F", "; c gray25", ": c #414141", "> c gray26", ", c #444444", "< c #464646", "1 c gray28", "2 c gray29", "3 c #4E4E4E", "4 c #505050", "5 c #535353", "6 c #565656", "7 c gray34", "8 c #585858", "9 c #5A5A5A", "0 c #5B5B5B", "q c gray36", "w c gray37", "e c #5F5F5F", "r c #606060", "t c gray38", "y c #626262", "u c #646464", "i c #656565", "p c #676767", "a c #686868", "s c DimGray", "d c #6A6A6A", "f c #6C6C6C", "g c #6D6D6D", "h c gray43", "j c #6F6F6F", "k c #717171", "l c #727272", "z c #747474", "x c gray46", "c c #767676", "v c gray47", "b c gray48", "n c #7C7C7C", "m c #7E7E7E", "M c #857C69", "N c #9B937F", "B c #F3BE41", "V c #5C96D5", "C c #5E96D5", "Z c #5E97D6", "A c #5F98D6", "S c #6496CE", "D c #6899CE", "F c #689ACE", "G c #6397D0", "H c #6397D1", "J c #6496D0", "K c #6099D6", "L c #6299D6", "P c #609AD6", "I c #629AD7", "U c #639BD7", "Y c #669BD7", "T c #649CD7", "R c #659CD7", "E c #699AD4", "W c #6A9AD4", "Q c #619AD8", "! c #659BD8", "~ c #669CD8", "^ c #679CD8", "/ c #679DD8", "( c #669DD9", ") c #699ED9", "_ c #6A9FD9", "` c #6AA0D9", "' c #808080", "] c #818181", "[ c #848484", "{ c gray52", "} c #868686", "| c gray53", " . c #888888", ".. c #8B8B8B", "X. c gray55", "o. c #8D8D8D", "O. c #8E8E8E", "+. c #909090", "@. c #929292", "#. c #939392", "$. c #939393", "%. c gray58", "&. c #959595", "*. c gray59", "=. c #979797", "-. c #989898", ";. c #9A9A9A", ":. c #9B9B9B", ">. c #9D9D9D", ",. c gray62", "<. c #9F9F9F", "1. c #8393A3", "2. c #95A5B8", "3. c gray64", "4. c #A5A5A5", "5. c gray65", "6. c #A9A9A9", "7. c #AAAAAA", "8. c gray68", "9. c #AEAEAE", "0. c gray69", "q. c #B4B4B4", "w. c #B7B7B7", "e. c #B9B9B9", "r. c gray73", "t. c #BCBCBC", "y. c #F9E0A4", "u. c #A2B3C5", "i. c #B7C7DA", "p. c #C0C0C0", "a. c gray77", "s. c #C6C6C6", "d. c gray78", "f. c #C8C8C8", "g. c gray79", "h. c gray80", "j. c #D0D0D0", "k. c #D2D2D2", "l. c #D5D5D5", "z. c #D7D7D7", "x. c #D8D8D8", "c. c #DDDDDD", "v. c None", /* pixels */ "v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.", "v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.v.", "v.-.+... .] v k h c ..v.v.v.v.v.", "v.-.f.f.s.a.N y.B M +.v.q q q v.", "h 9.k.0.5.,.w.=.4.u.7.l a a a 5 ", "h t.5.t.c.z.z.h.5.[ =.q.,.o...: ", "a 5.r.i.W C V H u.=.k 9.-.a N # ", "p -.x.W L Y T A S 9.w 6.@.w b $ ", "i %.j.C ! ` ) R L 4.5 5.X.7 c % ", "y o.d.A ! ) ` v.v.v.v.v.v.v.v.v.", "r | r.S U ! ! v.. . . . v.. . . ", "w m ..2.S T ! v.. v.v.. v.. v.v.", "7 j a b :.-.$.v.. v.v.. v.. . v.", "v.$ $ , , : - v.. . . . v.v.. . ", "v.v.v.v.v.v.v.v.. v.v.v.v.v.v.. ", "v.v.v.v.v.v.v.v.. v.v.v.v.. . . " }; stimfit-0.16.7/src/stimfit/res/arrow_right.xpm0000775000175000017500000000210714750344764015104 /* XPM */ static const char *arrow_right[] = { /* columns rows colors chars-per-pixel */ "16 16 44 1", " c #246321", ". c #296925", "X c #35782F", "o c #3B8035", "O c #42883B", "+ c #45883F", "@ c #498B44", "# c #4A8C45", "$ c #499141", "% c #4F9947", "& c #50914A", "* c #5C9D55", "= c #56A14D", "- c #5CA953", "; c #5EA159", ": c #62A35A", "> c #62B158", ", c #68B85D", "< c #6DBE61", "1 c #7CBE76", "2 c #71C365", "3 c #74C768", "4 c #80C17A", "5 c #82C27D", "6 c #84C37E", "7 c #87C581", "8 c #89C682", "9 c #8BC785", "0 c #8EC987", "q c #90CA89", "w c #93CB8B", "e c #95CC8E", "r c #98CE90", "t c #9ACF93", "y c #9DD094", "u c #9FD296", "i c #A1D398", "p c #A3D49A", "a c #A5D59C", "s c #A7D69E", "d c #A9D7A0", "f c #ABD8A2", "g c #AEDAA5", "h c None", /* pixels */ "hhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhh", "hhhhhhhhhhh%hhhh", "hhhhhhhhhhh$Ohhh", "h332<,>-=%$:*Xhh", "h3gfsputeq975&.h", "h2ssiytq08641# h", "h<,>-=%$Oo+;@ hh", "hhhhhhhhhhh. hhh", "hhhhhhhhhhh hhhh", "hhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhh", "hhhhhhhhhhhhhhhh" }; stimfit-0.16.7/src/stimfit/res/accept.xpm0000775000175000017500000000546214750344764014023 /* XPM */ static const char *acceptbmp[] = { /* columns rows colors chars-per-pixel */ "16 16 136 2", " c #1D6C1A", ". c #1E6E1A", "X c #1E701A", "o c #1E711A", "O c #1F711B", "+ c #1E731A", "@ c #1F781B", "# c #1E7A1B", "$ c #1F7A1B", "% c #1E7F1B", "& c #1F831B", "* c #208A1B", "= c #20881C", "- c #2D961C", "; c #2F961C", ": c #329D1D", "> c #42A91F", ", c #42AB1F", "< c #42AD1F", "1 c #4C973D", "2 c #4BB426", "3 c #52B92B", "4 c #52BB2D", "5 c #54BB2D", "6 c #54BD31", "7 c #55BE34", "8 c #55C034", "9 c #59C236", "0 c #5BC239", "q c #4E9B41", "w c #52A042", "e c #5EA948", "r c #64B04C", "t c #6CB656", "y c #6DB757", "u c #6AB950", "i c #6EB558", "p c #6FB558", "a c #6FB559", "s c #70BF57", "d c #74B75B", "f c #74B75C", "g c #70B859", "h c #71B95B", "j c #72B95B", "k c #73BA5C", "l c #71BE5F", "z c #7DB766", "x c #77BC60", "c c #7CBA64", "v c #7DBC66", "b c #7DBE67", "n c #7FB869", "m c #74C259", "M c #6FC261", "N c #6FC361", "B c #6EC461", "V c #6EC462", "C c #6EC563", "Z c #6FC664", "A c #70C163", "S c #71C463", "D c #74C364", "F c #70C765", "G c #73C766", "H c #79C164", "J c #7EC169", "K c #7EC76F", "L c #72C868", "P c #74C868", "I c #75C868", "U c #76C969", "Y c #76CA6A", "T c #79C96B", "R c #7ACC6D", "E c #7FCA70", "W c #83BE6D", "Q c #87C272", "! c #85C575", "~ c #89C476", "^ c #80CA73", "/ c #80CC72", "( c #83CE77", ") c #87C979", "_ c #8BC878", "` c #90CE7F", "' c #96C783", "] c #9AC787", "[ c #96CB86", "{ c #97CC85", "} c #98CB86", "| c #9ACA87", " . c #98CC87", ".. c #96CD88", "X. c #99CD8A", "o. c #9DCE8B", "O. c #99D18B", "+. c #99D08C", "@. c #9AD48D", "#. c #9FD291", "$. c #9BD791", "%. c #9DD892", "&. c #A1D695", "*. c #A1D795", "=. c #A3D796", "-. c #ABD29B", ";. c #ABD39B", ":. c #AFD7A0", ">. c #AED7A1", ",. c #AEDCA5", "<. c #AFDCA6", "1. c #B3D9A5", "2. c #B4D9A5", "3. c #B4DAA6", "4. c #B1DDA7", "5. c #B2DBA8", "6. c #B5DBA8", "7. c #B4DDAA", "8. c #B4DFAC", "9. c #B5DFAC", "0. c #B5E1AE", "q. c #B7E1AF", "w. c #B7E1B0", "e. c #BEE3B6", "r. c #BFE3B8", "t. c #C0E4B9", "y. c #D6EED2", "u. c #D9ECD4", "i. c #E6F4E3", "p. c #EDF7EB", "a. c #F1F9F0", "s. c #F4FAF2", "d. c #FCFDFB", "f. c #FDFEFD", "g. c gray100", "h. c None", /* pixels */ "h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.", "h.h.h.h.h.h.0 6 4 3 h.h.h.h.h.h.", "h.h.h.h.9 m =.,.,.*.u < h.h.h.h.", "h.h.h.8 ` q.%.( ( %.q.~ : h.h.h.", "h.h.7 ` q.R I L I I T 8.~ - h.h.", "h.h.s q.R L Z Z Z S e.K q.e h.h.", "h.5 *.$.I Z Z M M r.g.i.O.o.= h.", "h.2 4./ L q.y.M e.g.d.+.J >.% h.", "h., ,./ ^ a.g.p.g.d...j b :.$ h.", "h.> &.+.D ) s.g.g.[ t j [ ] $ h.", "h.h.r 7.H l ! u.X.t i f 3.q h.h.", "h.h.; Q 5.x k j i i d 1.n o h.h.", "h.h.h.* W 3. .c c | 3.c h.h.h.", "h.h.h.h.= w .-.-.' 1 h.h.h.h.", "h.h.h.h.h.h.$ + O h.h.h.h.h.h.", "h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h." }; stimfit-0.16.7/src/stimfit/res/resultset_previous.xpm0000775000175000017500000000234414750344764016546 /* XPM */ static const char *resultset_previous[] = { /* columns rows colors chars-per-pixel */ "16 16 54 1", " c #1130B0", ". c #1233B4", "X c #1339B4", "o c #1339B7", "O c #1440B9", "+ c #1547BD", "@ c #164ABD", "# c #1752C0", "$ c #195CC4", "% c #195CC6", "& c #315FC4", "* c #1B65C9", "= c #276ECD", "- c #376BC9", "; c #2A72CF", ": c #3D77D0", "> c #3A7CD4", ", c #4180D6", "< c #4885D6", "1 c #4A87D9", "2 c #5089D9", "3 c #538DD9", "4 c #5A90DB", "5 c #5990DD", "6 c #5F95DC", "7 c #6295DA", "8 c #6095DD", "9 c #6698DB", "0 c #679ADC", "q c #6599DF", "w c #699BDC", "e c #6E9FDD", "r c #71A1DE", "t c #72A1DF", "y c #6297E1", "u c #6599E1", "i c #6B9BE1", "p c #6B9DE0", "a c #71A0E0", "s c #77A4E0", "d c #75A4E3", "f c #7AA6E1", "g c #7AA6E5", "h c #7CA9E1", "j c #81ABE3", "k c #83ADE3", "l c #86AFE5", "z c #8BB3E5", "x c #8DB2E6", "c c #95B8E8", "v c #95B9E8", "b c #99BBE9", "n c #9ABDEA", "m c None", /* pixels */ "mmmmmmmmmmmmmmmm", "mmmmmmmmmmmmmmmm", "mmmmmmmmmiummmmm", "mmmmmmmmqy5mmmmm", "mmmmmmm8gn1mmmmm", "mmmmmm4dnc>mmmmm", "mmmmm3ablx;mmmmm", "mmmm2pcjrk*mmmmm", "mmmm,7xtqt%mmmmm", "mmmmm;F*Fb7yBF0ب WVߐB`# *+ciBzT8\ XPB@b`Mbm+y4 n*̸V5Đ"V*(!-:PVY*my!DօX`ƿQU6 Bf6U*"T2FX00"`(X^dň`%"BϿ/؄"liu/YW yg`A B@5/sQ(@qa݉qfm?cݞ{xY1}H}8( m"?mqSRO?//=,r8PFT K0sї^:WWCWHHn1iu%(_2?mUt" _?k#_$  \&~cGn-{nZcm.!@@ۧ J PR}QgCcg~W\E@ |;NH[w^n}B@8wpJ`BoX` PJAݿZ:}׏}WTbu/5C,Q-Pv]ƿ躪_6巾}SDl쓟#B[jB6 J~߰/ ĀLVJBOϟ_8|06_k.6XM_5/,~\BW1j6㯔TRF**RJ(>p_~?a*)5Mw ~\q=f~n1"5Nu8…ϟBȦFџDDJ"!(ZP2N<]',LVSP\$ ß}dq3_S븨/0HK"ٍp !UH" T+ DzK~)^Y(V/J~o75܎AM Ps꨻ :G :B67>VLJ@e@GG(HjB J%z_|ZAV"(._7 ~Qnnc~_to݁_Ѩ5cPOz`r !.eځ!d9!Bu0?;?~!A@F _'tʳ|!.X`3QBNE_M~n} }CznZSvpA }D!ǞBgnЏBdөRQCA {-%d>V (K `"`S E~Ukz7e1kB@&jnc`X*(q+1@؅BnG 9q=[)^{OĀң2B/ّa.J*` a>G7wcߕ3N-S7~Ba~$B޾<}e! 7n"#{"Q)~: z T\#[Gg1J;M%yQЫ~͓jwѪOQkT@$#DO$_gp?٭~MFG :ne?U݅{G_%"63a"6(PAY0x?/>6߬Ш:5@Pd0Cip_h9/B}>V b˫id ]XZ Zk>We|ˡ8E6Į Zߢ7`wK\_™ZpDWQR342͊3∫PpEpѨ D} Hڹ??|}wَ兤ԾºJ`QՏJ+QIZ|ʼq#J7q'w$sadY @!gR% A싀8П|F~d`{_C^.`Q t_$.@@70x{3{Ӣ?d~5  =/B!U>#-A`WO $^kf$1jLxߺ_M-\"m3>75B1!̘D y{ǩ9R/JUؤԄBV& >cj;3Z*n]cٵzop-c9^يF\l we~DR˼C7"3#u 'TlJCQ>~BPB / N Ɲ[zzt|A8pS_qo0rY`5pC?ͅsf;p6䤀8{ƟB.ȋ$UuH?\Kn;ٝ*K& ଇ@ D4gݟzF?N)+B!^ 2 gn͖@1}e|(?FTP#|9a;ޯսxd_ei,'~Whغ$ĞTEoSXß 7v `DQ4NDH)Ȼ( 1Mn}K{(xݺb-u!g2/MJ߉ei !d]~;NM8Gy}w|׫Ph/@yAq$428P?-ك ˘D1&?;IM'q(@%Z_7;غ>gjl (`8(RVU&9zk]?Z(=B*=ƟBK  6 M@%?ֻt#-43ܚ^ (m-u6ּTi.H{4t۸DO!@ >r]K@@8Kg|ե(ٝ*QaVY_?఼Q_{NџV"O!|K̇Uuʣʣ̬fS aJ[F+ֿ4bF!($@t[ۮP(J{[!6Ê'!5hBNe.0!Z3MaxJ*@8̃>?!0?ۭ;F5F7J%dgC N 0O!3& *NJ6, G7E`Xݰa+8B:EESTY(yc b Q!ۥ,mMٷ]r/B6p>՘U5blㆊ*Z8%QBټCPѬ[yX `Ame9(oxB6[W Ƶ `ԤvFϟBH"@Xyߚq+V mT!!lO=FTo̢E BHűA @Q-JFM1`%nw]eB!dk.B!UJFB)'jB!BU~MX^H1BG:p!BYQM#!q66gum\JoLB!dݢX%'B(.` B\1{B!dCږ0٬(%9.SA!TIVldC=Da* q 6>!(C٘P OzP2$QEj)8&$!s}B"oé5Qom6x` !6]JM1~o ~y=x/"[S!k=o7AɝO$,, BփCy qȠ!Q}OԞØ{;dq _BtB!kI-Z>s&cKp tNw0\q&v^moR[B@Z #Ao!/阞?(`h;n4'PQ.B!$\/5zb]wmT,&O<\:l2ۧ)!\LO|&59^ PJHұCî߆֎k)!~R3pҰ"d' ٯY`?ͼDM![L/}O>@jMg#N 'a,fo|{`$!W2}bcx|H/y?gȠH!Atc ?Oa~QhT7wہ/X|.:g&B(Ym8#YB}x#wsQX q3I@sx鳿{o!BF> t`5~'6f3!ǵ&" $cFЛF d5b#{?y0&ԐgnBr[]a D's" VM@! ]Ƞ f~X> / - `p3QPD'qULH!dSd%C_Tص 7gл $vh$~7YIvB(9/?YR0 a=bфlAp)D!Pd؅x_{W͟M_7euf4M@R; |t#E:мg;q0XT<P.! R 'yQr9&/@(qp|3 !RG>$Bd}!v?G`xHT IJ`#X|.;YB(s:sHi~NGgc%PTC`m/Tu?X){E B* w>mOoda3ڬ0 p;1w @Z(Ea_~=eFB@H* }+߁HJj@}1PœX:zKFB@HQ =90qߚ7lH|"R I; M g?ދ_J{J|s !XN0/lU'LGdώv-3N`?L\D e'ϴf5H!}a ri=,>iQ =B( _|.7|[۟n]cO~o ld(K(K~H DErzʼ.2Fptg 2@s3=7B@H&OY awوCn0 <s!!kH 0a{D،~R80 A4=`3΂p-@ !lj/y/GbHjbAZYK{@B!J?0(˅m#xٛ] X Cql!_kK'7d*B@L8h0üG8h֚jLUk&,ڀI*@ X~sS #!rǟ(41U 4f'f ӍiԝLzڂl@<8(.r_2@ 9O gOԿ@!м.tc Sz_=2`nƤAAf* 8@0@ WQ gonKOzp/z5v]t&j7jIcfG?N d*B@6%&lفe؏R pPknA{x^FQ$Z(z4VdHPPqA{/uLB(ȦCag.ͥ?׍) L/mA㢦K),,J"G!dSu-%o?–]7jMt܂%o IQf6 G IDATA[ \sDΣf*B@6'QKuo( ?mY$^Zp˾ K2&js~٢?]dBj/ PM:PA7gƿ0Ee0r{x:~>عz\u7#!Gք"MiN鋸 JDru2@ /g L,ʤ0Bkz<%q*2[F/i~cZ Z]@!r!d3yJS8Cyb]BFsm],( 1e G/36XX6j Lwo/MAo'!l`s;W=$w\zd#Ѡ0M ׽ /6ץ(|] "]--fD Ȧ6B@6|{(73*z2КڝOI<tҟw_VD2B(CԝzZ `L2(hFbazw 4!P#dWV?B?$[B*NUǜ p!p ÂrkbğzPZ!Pup<56vhJODjԮ*L8N؅+x *"@_dV_G-=DIN B #-Z;lB!1fi*L؛Nj=^i,KhM}*z!\ҩz6OBY([o-=r4+/–U{"baff/靀R]LZg3@w;ğ9&B@6 4EymttaI}ŕac7"aF"7o; 8P?O Pu/LCܺտcxuP P 3ۯHh(xOlt1"@&!8P@?ws("BYl 9P'38Q6\}7B*^CJ@77!0Mz~$}̀BYoٜ7m3fWZ/S~ wP e&Y03O}.NH [=hQgo!<}k^- T0;Z%C\#U? n $PO9Spg$[4 බutJ` oz'$]Z3}eAf$@" |t g Pu(ETnܹ?GM\:r #}ax ֣C>((]#܏@_,OExsB@Ս~IǗ!&f.mOL*1FmFB0 z, B{H zeK*`ɸjzyG|*k ~g 2 /r@>@x E H,?{o[T< pbjH3SW]U~SQm.@=P3{F>!dȃBmɩݕL\ww@kئ^}~, .̡[ v'S3{oT pZX4(V@WG ЛGp3sqc !""ʦҋnk۪L*Мރ^CݩZ[QKp]08vvcēB@Ɨ飫YJ)OIx]P0RZ)z`nOGfK$"S 2)[@s Zs˪M]۶ǥ׽50[c/(5D^'?Ky` 2xszū"0bûmL] W^&4vQw9*&|2еN< 2d9ꍙUk ՚8pۻJwbD'fntJ`?2HL;Bxrsر:l╈T@7J%3֮dN% !81 `* B+ C820| ȏm\@ oӘƲN7Bnm pAT͍P2Ngˍ`l4;/ʟ Cmġ}htc`` A HсdJ` ?O_7B@XEd1[Xt/bK #eϭzG8{@Y<1P2 YW*g%*nӄHf@azwP8Uq*`Z1 68H(D5"HvL0SPDZ_1 75pd߁jmþAu{7i$GP'=b* B֚p)*\?,"M_l} ({8 c\$R1`I /|!T!)JIDݹR_Pe͙tiE8P7JSe=}zZ  UT!C֙p4Bf9'=wB*_3sJ[6'nM'j.}]LB@ȚEɄ+ SkH7^y=NEͩe6J%3"\5f`x d 9p>0@RϭۮZӿS2 ’4 UؔEI4V-z;Q dmC0"%uJ "ˤ^DJ"@7&ߖ ЏSb -0@!k -H@YځXOk} ݃ZCP 0@̂g _8G@ֱ͍NH%/G)ɀ1%-\Lt.0@![dChP{ȓ3!Za]xò%ڶ*e$xp+ %F @ ˁ(@% zLB@,>Wlq~ c#;9s)2] poۘF;hT-Ȯ DCp3}XLB@ȅFƋq%mJ)D*B9p"@?o o 9&-7tΥY Yq$Sq$ 8M&B!@/obc{dtH7= HD'0# >H o#24B(Yu!|J' '+ǂ1L* h/gD$-0ž  ƛ&g5d; mec},rޕKkc &:!P-2A*@IC5B(-/geSex@~ܙjmS i LF?̚`W(0T!?^NҗqImc`?p > 0R]|B6 u c{ <}Y5ܤH |H-k/-_%Ku1Ecc3 hRꑀ(DD?G F))BC=[oyמ&d7Z۰wPA[ۢ@z@ Cs B/UiUEY/'T5"}nhs*I-`Dm8P:]0 z  BtΌW\mjOl*{²V5h Lԋ@&ܯ 6qGTsl $G!A :MuyT\q;^6RcI]E)="P#G?(υAPB7PF,b~-㤧<L^n؅p7%PeW]l̔@# :~(}.. "J=*]M׉{ץP2Rnv(]n:JAmhG8=޳a* BF_sJ ! 1/MA <(o-u1W% WdžF 'Blȇ2SC͓ BDxD6?ymRmBcVQ&p%9T&alQZ=@[@ Ky H! "L+UԆI\q7Sxu x9E'?"8@u&r >}2TB6 pɮ7D LlsaJHfLGA))7ϓ B"a|27ؕ޷B.lM.pۻkT6!PP# .I$aˏ|0o-qk !ѦUѢplqp?=jmÕ7Re/ 'c^z gH!6-rUj̭|Ofך3h詀˯[XfF;$ `Bdȵ|X;C`B(/+35PbF ќIC⛉'T^\uD~?~cc8@f 9,|lj6WB@6gGP16 0~mঋ@I\}19{ :A';T HtO1 _zg>5x}@ٌqaC&ozì9d8X|?1% Z3Wb`i[@_!jމ#S@ *ܦ/œX8zB@6 JF h^_5*Psj \toˤs"+@f}0 N>sB@6-z#]7l@^^k{RX2FM'Q~zk#1 (:lFE#J)8i m iDdoE Ȅmb,s]\N:103ظN@@=Y@4(o0ǶƘnjj.4ıoC…+ 1 Zs8#?с8d=!d7La-\Uخ߾}8*/F~:%n{ŏm`[DIIG1 |mB@66``-)IT [.AO hmMw X1Qk523?.䄀HW , ;f@%3%@V[%`j䒛peSO')*]Ub4ctETŹ/wB@6*QCモ0!S;wݘV< 2̴^{;Кރe9XK~_ ;(œ#sP x S `KџR ^A*KaRX1QkekagF{ ҅5 ݓs8D]72?"ǂn5^k{ &qF1WP33ЇgB@;JI( J)u5p̥8xۻݠV/@O"t?+n[IFY@Y޿pQl`\Ual` hOQމ^؋7!sY҈$F?́(ag{ W ox499´?Kmp6S|+~Nc"THWQ0$2Q`9;Puyj Hn:nzKv^ydUTK"&zd 6؄ `DAO3O<0 2(B3G3Ag"@F'#((fN! IDATd #3G+mˋ5^ k8h82;_pXtp N7ۀ U.o _v2'p% c,B?d\qb_g%71~B)E)2B@mmFy= yP' PJsh AQ$@fpTWp1W(@7"@[َx[6ov$ƹG?zB(X sa3ɥ%ǟ2s0ЎKnb :گŎ^^8H * ʉA_yZe/. X:ޖ0gS4($콃 YW/5`[Bmq܌H@=P (@{@p9=d=!dL$1}_WZ#Ab`쾙|=A*eo qR ;5P3$ @X:waoB( 8<܍7Y R u^޽:/ f="!D_褅~b3!`p2`ˤ;s| kRva߸A8S 2 c\^J1p1벗jN-ho4g>$?Z 4HEQP5ҩϧ#* KzaJ)ND hqtU 0gE( Я8B@FK>M;=[Tg3ب_Vسf/"f=+^ PJa)p;@ZT `zhL0[ S :F)1'It=mYspwncYR8yP"`vR#D9.5 rQ X|oNX"yXH-P)(3_v=@p)p Jf1ٺ +?AAa_D}2MLßz{ۃ)T!dtKG>V>1 H`W |U? r>;;;UkOڑA@l:@bB(#CAoA? zzG>xecE%݅N'=@ԍF XSو@/`d,5 g#?S5=`~= lNXH[^Y~ vq$An8P@, (~; Co dT^Թ4>}܇q Z"hb`җŬxWPPX. * *W蔌 O c_:Q)" 5$PB8pk0=sߊWݠ F<$(XA) ʦ$CHS\L(y_̄Mۧ#Vgk\n Y}M_|{]`wD%SI+`yRJFdV8H(l%mO~%  +>Fl.uYRZ0(J01sC9?7CD(62YxKJ(hWAJK8B`לȃm}f=pdүT~+My ɼ{o ^%tNx^%xmbz Ϯ9g,I;fk-Y7vF,˨9tcTvFö?&}EAlÿ{#Cwѿ\џ_, 6U梀)z=@>W% S)8±΂ȜO"!$e0؟B6r.B(ȆAF>iC/G?=xG^++Mn[TP!Lo&LODOI9f=׼{x%za 2_п!Pdm?MB`ݡKPn;³X<wC~2_|X+e93@jX2?6 2e0W}Gގ%o[[[P(FdZ"LHdTJKI9 x3{SDЛ[D(uI1wS? O?Ql{fN-ݾH4ԝ:ӿ?ɝbq"aSôW7X1Q@;hdž[sL71!dw2?[JEԚ[ SGA?!<ߍw _I V7J A*>wQ<7 SVs[ 9ܚ^8)4B5} =*"@5{hNlτ]Vo" :i*_ /uK*L \/( xA!dh?o'Ҍt|(jrD;Ӎit^IC2‹ nsHwOڊ% Mb) #u/Xx |cgLQi5oy̏e"yURטB xo7H6z*`jrn>H%EZf:>"83P$OoUwK/=bv1C[+a+$,˸WXam ߤ詀n|;f^^Cݩqпg|4#f'@" t[ )2-+42l;jӛ*"ⰿ+{a|~)Ͳ p, zk~J),K K EU9+ "e do '9s~M2E9@p0՘o[B'ßAw^~5"A)[Oe٤@sy^fB}ڧ`B@/劝N=A[ {h H%sUF@H(ȅ&7gGAݟ_-.`(k[Ƕx2v9gd?r<G ٺۄ+T.3_0G "JGG2~+vhx @}2Tc ;&fMo_C{I۰y@=lf!_ ( J4KPFNOt xk'27]9폔 t6KWއPpp`\8_T~:W?"4`(oy=ΏkƟW )|?XѬr}e'a)f, ҄A>=.LլP"u\4q%jLtx+~o}iɊ@[ᆛ16hjeA dՍ=1IO٪?S8ǿ{j7f3en[wܣq뷢ڊeZ3b|Maj<AЛ/oT`;+e|`Ӭ1$"F.wسz'űS܉÷}GjN Q;SJ~_/(fzu5 2~]4:&듘nL6G>6(_o|{n%d 2V{ o-`Ks DAa_aHmE B@V?~p4f0ӜAͩA* ? /#R\׿ ~'w>Dzd?j<tq9F} /pi{$*~Uek&Qo) 1J"Et3ן9v?N|w./um@B'Q$U_XD'^8~@ID2d@:&ΗDmM;+a4䂢 8tիm~2Dݭ[Ny=f\\ /!$c 淢B8nLc>%o׽ᆫ_WsQc!SBoYkfŒdoZ.‘mT6U\xbKs &Ex)a-hЦ'}8Сu3elPnZ`BG?< 7-xc)pA((tG{#uTuO\vggo]^KK/KAؤDHڦ#*!)  t+J`% "&h/a.6,vP-&MiI-%wr2;wUT>TOLuBz״6s؟wwxuoaKy'`߁G|[wE;wem} Ge})k49xv-@\p_8[78w[l!4c(^>g@1Wj^ xcǟ~Tdc {U >4~!J}\!tu}"Y"OWoV"*3%Il-lEQBY;_RXyF3dȲ/ B8} -F Uxu.Dh( J4ە?]Pi(dhK,@;5^m ؈}(ݯW]fOчU},_)q¶dv]+k|pb#~?ipBkgit$` p'+g_όw*t+=Sxx |Ȉd>~ۯBBbB4O'P‰Qigf7!4#&wq'psx{;R}W_<=~~G%x}Ew߮ʻZ]pLk@^oXk՗9b=`\N6ᩧbm 'f6N`[a5RCSm}Xgfo=xQMP+ڧz8;$藵~pPj9[p(Yd}nW#чDq ՋMF Z2V+Ǎ2YϷ#N~Uܥ\,._ "e04d@(>l..b:?|Z/5J4+xo[XYO+(NΡ(ŚrS ǿ7n@BhF7J=&x XM@g-XUJBY>%HHn( `-#\S[<,z)Bu4.}= 4V0[؊}DOawbG7qYa!J`~/Q.`[q~3V'S/uNn;(LnwOݱϢ{Øv%/b0ǚ01\ԭ}IDAT;"{ Rbka+KRT:t~\+>t4yhxYm(p'~oҬ+ܬDLFux4Q2IlI,}izL@xz=&LlANJIMuBRĝMz8sV뻭5E0f+g_ %} 2^KеC_DYAo`0\;B"vfOH'Z;,ח1~+2,BhU|Wpˡ/bWČepX/=7Ė]=i~e:_}=!2= ~Bhr ?~pk2.s_gş{N{n;۱XT~ D)cB<4Ë0O~{ފJ$,bmy(KlIH*4r4Ox݀cJd!d4qʫkMRm iLh ,Ń6lK&qܫF:&-lb} S)l)l1AOa+`11&!:$13[/r}OnG`my@@!:$1_KnDQB ډ<  !3$6?'>4+4+Ω(BUQ Nz ?z)\8{psr=9'@6(5JzU5 !d6VpE+rŞO'qʻpʻPǻᅣGw 8Î9n@ ҇xhR4%?;揠^qX Rv 46sp[ ~lN@!_Y}X#=v]=K (W D~2WIBH qҫW7n840fv`fj< yypc;fBu_ifu/\Bh!d3fdE L0OJ?Z <,/"BSxXw H/fD4BO]0Y\B B !Bh!B@!B!B!B!4B B !Bh!B@!B!B!B!4B Bh!B@!B!B!B. B X?}B!4B*i!f!B9ppBG^fX5!a)pF cIq'BuGkh!? 0A3)d&BN:>Z9r˸A@! @Q De \ד6o 32\BnItxi֝lGÔXKM 'UFO!g -6l깰;6ɸߑWxB@;?m6 ܎}@wS.AU %7B!#Oʈ9hTWGy&aD3(aQ!. W 9 QOǓthS7]pb$+wѤtu2 /qbGܥCIH^m)Wc \Vݬ.#Rwd9 2"%2j x?g0CRsMfmq3#eg&H1EJf!dh?Gd `H %ՅoMK;R@6Y[9s& 4BHgF!vn3QAiR 3lzړxib mfI!${ѿFS }Vy'AmtsS3 ƅiVYx{oVΪ.#R ̛8B! j?eWBB^ygJͶ2fz̏HG>a(<ҁz11H#k78D2Kg~ yVy.#\@@!Y;{7 7Z5eB,=̛W[jHFcM!dL[ߍzp $ oɫ[ pP 2-םu~eK! \4 BH_*ܘ?| P]:W_~W>#0 kH乷R g:J. i!$YЧSww& ,mLJZ#R3ӯF,@ @όBɴwSwy4+ѿDr»/@(sl ۞k'Hp\I7P$ wg \X&FBG_L>A IJ@tmIntG]7M!'84~ֶf±so?F3?. qN6 4ԏ$d#2]hz?*! Z_MKk08㧟{>edm9I'ۗ__3P8#N%1g~dx!"Bъ;R_SQ~'_ogs?^<H 4L@./,[)w_yݏ [H87bpZpܖa!qtE'Be_4io5LAY+O9z3,6]a{&mҙYOca8AU'[>_DN蕤-|@8hh9H~3B!JV!\e{ <ԑ?fbU 1 ؊nM$`{Y v-~ϞZ CłQ{zN- VnB ߑ {BVFVF~i,{/i{ڟ^@tC? $6pR{nbk~$ xf 8mRfB^J@t4%BȸXP[_waT 1h$ia3#~1<'wBϝs'ts5[} ? 9kc !\ᶄ%u/Ο( !$mVQPR2Ĉm@5ccctY'58c:}]몟ezD1~&@B&c @x co^x zyCe`NLWWC|@0㸅w{nԌv6@$ҧ SoF^\[>koorCm vK`3 RfL¾V;nsKw' [s{MRoBij]GfmiY]X>ᓥoG4ŮKïe?_34 I]{d0LXH!mIq 1q6X HEh? ` ;y+qQw /@y~MB6[a)hI/a@R$oz Ǎ'5!ԋD尯lSM@U *nHuѿzGYM !?1@\xgsf#f rpP sq2qGY $BȰe#:TtK۶ < A3 m"R ?W" LmJgT|ְP`2{B0SZVӘ837DA6XF0 }Gdecg GPcB‚o3<:BȨD6AT 2Ios,72vA sS@tF@ l߁롮nbOES &`-f4`[`)[c0VF|CaW@#iW~]c!N4@BȰAN HkKOϔgD(+0$waG6M3kh!m`R @FT 0+LYXEh"~؈𻚨?V s  !f m_]p')PR!Ӹ\w$qg#?ţ)/V]k34a8aS6d|˨ߦoh,S@#(CPۊttSŁ, =`? NL\˘mB1P̀d414g=H]X/τ9Rs&]m}kE¶(ݶsl;1On3o>N5q{يItٹ!2@|]Pja``a |ڢ?B0XFiּLrq?Hk!H O/ !n kћdҼ1,gatHE| 0{qN#jV@ZlO3$FIϪ5j PmrBȸX3=zM21C'Y66&@P{' %C>vBȸh;Xᧉ2C#Y7g`%^g }n[ Ov IgZ5Rh"~ > !$6mkȊ4&0NjLg~B9#o6H7Uo#(^#ėc?M_˜~6A!kY? &=l (%4~*AYADn*c~-c~BH֍L06?olH+Iř :!d\ ')O+I`ZW} K Iz? 췘ߨf2J/;7¿ 7$ *b.>axMX R߯1X3Q:QN4"KJh+2:&@k RGNGvk8\5܄ O " Z)}156>!¿9<Wߺ0wBw$^$!hL@!N0" !ߓ(B`qx!B!B!djBaB!4B B !B6HN'4ۈIENDB`stimfit-0.16.7/src/stimfit/py/0000775000175000017500000000000014764352501011734 5stimfit-0.16.7/src/stimfit/py/extensions.py0000664000175000017500000000216314750344764014436 """ User-defined Python extensions that can be called from the menu. """ import spells # class to create a submenu of Extensions class Extension(object): """ A Python extension that can be added as a submenu in the Extensions menu of Stimfit. """ def __init__(self, menuEntryString, pyFunc, description="", requiresFile=True, parentEntry=None): """ Arguments: menuEntryString -- This will be shown as a menu entry. pyFunc -- The Python function that is to be called. Takes no arguments and returns a boolean. description -- A more verbose description of the function. requiresFile -- Whether pyFunc requires a file to be opened. """ self.menuEntryString = menuEntryString self.pyFunc = pyFunc self.description = description self.requiresFile = requiresFile self.parentEntry = parentEntry # define an Extension: it will appear as a submenu in the Extensions Menu myExt = Extension("Count APs", spells.count_aps, "Count events >0 mV in selected files", True) extensionList = [myExt,] stimfit-0.16.7/src/stimfit/py/ivtools.py0000775000175000017500000000756614750344764013755 """ Some functions to create I-V curves 2008-03-26, C. Schmidt-Hieber Indices are zero-based! """ import numpy as np # stimfit python module: import stf def analyze_iv( pulses, trace_start = 0, factor = 1.0 ): """Creates an IV for the currently active channel. Keyword arguments: pulses -- Number of pulses for the IV. trace_start -- ZERO-BASED index of the first trace to be used for the IV. Note that this is one less than what is diplayed in the drop-down box. factor -- Multiply result with an optional factor, typically from some external scaling. Returns: True upon success, False otherwise. """ if (stf.check_doc() == False): print("Couldn\'t find an open file; aborting now.") return False if (pulses < 1): print("Number of pulses has to be greater or equal 1.") return False # create an empty array (will contain random numbers) channel = list() for m in range(pulses): # A temporary array to calculate the average: set = np.empty( (int((stf.get_size_channel()-m-1-trace_start)/pulses)+1, stf.get_size_trace( trace_start+m )) ) n_set = 0 for n in range( trace_start+m, stf.get_size_channel(), pulses ): # Add this trace to set: set[n_set,:] = stf.get_trace( n ) n_set = n_set+1 # calculate average and create a new section from it, multiply: channel.append( np.average(set, 0) * factor ) stf.new_window_list( channel ) return True def select_pon( pon_pulses = 8 ): """Selects correction-subtracted pulses from FPulse-generated files. Keyword arguments: pon_pulses -- Number of p-over-n correction pulses. This is typically 4 (for PoN=5 in the FPulse script) or 8 (for PoN=9). Returns: True upon success, False otherwise. """ # Zero-based indices! Hence, for P over N = 8, the first corrected # trace index is 9. for n in range( pon_pulses+1, stf.get_size_channel(), pon_pulses+2 ): if ( stf.select_trace( n ) == False ): # Unselect everything and break if there was an error: stf.unselect_all() return False return True def pon_batch( iv_pulses, pon_pulses = 8, trace_start = 0, subtract_base = False, factor = 1.0 ): """Extracts p-over-n corrected traces in FPulse-generated files, and then creates an IV for the currently active channel. Keyword arguments: iv_pulses -- Number of pulses for the IV. pon_pulses -- Number of p-over-n correction pulses. This is typically 4 (for PoN=5 in the FPulse script) or 8 (for PoN=9). trace_start -- ZERO-BASED index of the first trace to be used for the IV. Note that this is one less than what is diplayed in the drop-down box. subtract_base -- Set to True if you want to subtract the baseline at the end. You will need to set the baseline cursors in the original file to appropriate positions if you want to do this. factor -- Multiply result with an optional factor, typically from some external scaling. Returns: True upon success, False otherwise. """ # Extract corrected pulses: if ( select_pon( pon_pulses ) == False ): return False if ( stf.new_window_selected_this( ) == False ): return False # Create IV: if ( analyze_iv( iv_pulses, trace_start, factor ) == False ): return False # Subtract base: if ( subtract_base == True ): stf.select_all( ) if ( stf.subtract_base( ) == False ): return False return True stimfit-0.16.7/src/stimfit/py/embedded_init.py0000664000175000017500000000235714750344764015020 #========================================================================= # embedded_init.py # 2009.12.31 # # This file loads both Numpy and stf modules into the current namespace. # Additionally, it loads the custom initialization script (stf_init.py) # # 2010.06.12 # Major stf classes were added (Recording, Channel, Section) # # It is used by embedded_stf.py and embedded_ipython.py # Please, do not modify this file unless you know what you are doing # #========================================================================= import numpy as np import stf from stf import * from os.path import basename try: from stf_init import * except ImportError: # let the user know stf_init does not work! pass except SyntaxError: pass else: pass def intro_msg(): """ this is the starting message of the embedded Python shell. Contains the current Stimfit version, together with the NumPy and wxPython version. """ # access current versions of wxWidgets and NumPy from wx import version as wx_version from numpy.version import version as numpy_version version_s = 'NumPy %s, wxPython %s' % (numpy_version, wx_version()) intro = '%s, using %s' % (stf.get_versionstring(), version_s) return intro stimfit-0.16.7/src/stimfit/py/natools.py0000775000175000017500000004457514750344764013736 """ 2008-04-11, C. Schmidt-Hieber Batch analysis of Na IVs """ import numpy as np from scipy.io import write_array def dens_batch( nFunc = 0 ): """Fits activation and inactivation of 15 iv pulses using a biexponential funtion with a delay, creates a table showing the results. Keyword argument: nFunc -- Index of function used for fitting. At present, 10 is the HH gNa function, 5 is a sum of two exponentials with a delay.""" stf = __import__("stf") # Some ugly definitions for the time being gFitStart = 70.56 gFSelect = nFunc # HH function gDictSize = stf.leastsq_param_size( gFSelect ) + 2 # Parameters, chisqr, peak value gBaseStartCtrl = 69.5 # Start and end of the baseline before the control pulse, in ms gBaseEndCtrl = 70.5 gPeakStartCtrl = 70.64 # Start and end of the peak cursors for the control pulse, in ms gPeakWindowSize = 0.8 gFitEnd = gFitStart+4.5 dt = stf.get_sampling_interval() if ( gDictSize < 0 ): print("Couldn\'t retrieve function id=%d; aborting now." % gFSelect) return False if ( not(stf.check_doc()) ): print("Couldn\'t find an open file; aborting now.") return False # set cursors: if ( not(stf.set_peak_start( gPeakStartCtrl/dt )) ): return False if ( not(stf.set_base_start( gBaseStartCtrl/dt )) ): return False if ( not(stf.set_base_end( gBaseEndCtrl/dt )) ): return False if ( not(stf.set_peak_mean( 3 )) ): return False if ( not(stf.set_peak_direction( "both" )) ): return False # A list for dictionary keys and values: dict_keys = [] dict_values = np.empty( (gDictSize, 1) ) if ( not(stf.set_peak_end( (gPeakStartCtrl + gPeakWindowSize)/dt )) ): return False stf.measure() # set the fit window cursors: if ( not(stf.set_fit_start( stf.peak_index()+1 )) ): return False if ( not(stf.set_fit_end( gFitEnd/dt )) ): return False # Least-squares fitting: p_dict = stf.leastsq( gFSelect ) if ( p_dict == 0 ): print('Couldn\'t perform a fit; aborting now.') return False # Create an empty list: tempdict_entry = [] row = 0 for k, v in p_dict.iteritems(): dict_keys.append( k ) dict_values[row][0] = v row = row+1 dict_keys.append( "Peak amplitude" ) dict_values[row][0] = stf.get_peak()-stf.get_base() retDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: retDict[ elem ] = dict_values[entry].tolist() entry = entry+1 if not stf.show_table_dictlist( retDict ): return False # divide by inactivation part: trace = stf.get_trace()[gFitStart/dt:gFitEnd/dt] l = np.empty( (3, len(trace)) ) l[1] = trace - stf.get_base() t = np.arange(0,len(l[1]))*dt l[2] = np.exp(-t/p_dict['Tau_0']) l[0] = l[1] / l[2] stf.new_window_matrix( l ) stf.set_base_start(0) stf.set_base_end(0) stf.set_peak_mean(-1) stf.set_peak_start(10) stf.set_peak_end(32) stf.measure() def act_batch( nFunc = 5, filename="", lat=60 ): """Fits activation and inactivation of 15 iv pulses using a biexponential funtion with a delay, creates a table showing the results. Keyword argument: nFunc -- Index of function used for fitting. At present, 10 is the HH gNa function, 5 is a sum of two exponentials with a delay. filename -- If not an empty string, stores the best-fit parameters in this file.""" stf = __import__("stf") # Some ugly definitions for the time being gFitStart = 70.5 + lat/1000.0 # fit end cursor is variable gFSelect = nFunc # HH function gDictSize = stf.leastsq_param_size( gFSelect ) + 2 # Parameters, chisqr, peak value gBaseStartCtrl = 69.5 # Start and end of the baseline before the control pulse, in ms gBaseEndCtrl = 70.5 gPeakStartCtrl = 70.64 # Start and end of the peak cursors for the control pulse, in ms gPeakWindowSizes = ( 2.5, 2, 1.5, 1, 1, 0.8, 0.8, 0.8, 0.6, 0.6, 0.5, 0.5, 0.4, 0.4, 0.4 ) gFitDurations = ( 8, 8, 7, 6, 5.5, 5, 4.5, 3.5, 2.5, 2, 1.5, 1.5, 1.0, 0.8, 0.8 ) gPulses = len( gFitDurations ) # Number of traces if ( gDictSize < 0 ): print("Couldn\'t retrieve function id=%d; aborting now." % gFSelect) return False if ( not(stf.check_doc()) ): print("Couldn\'t find an open file; aborting now.") return False # set cursors: if ( not(stf.set_peak_start( gPeakStartCtrl, True )) ): return False if ( not(stf.set_peak_end( stf.get_size_trace(0)-1 )) ): return False if ( not(stf.set_base_start( gBaseStartCtrl, True )) ): return False if ( not(stf.set_base_end( gBaseEndCtrl, True )) ): return False if ( not(stf.set_peak_mean( 3 )) ): return False if ( not(stf.set_peak_direction( "both" )) ): return False firstpass = True # A list for dictionary keys and values: dict_keys = [] dict_values = np.empty( (gDictSize, stf.get_size_channel()) ) if not filename=="": ls_file=np.empty((gPulses,stf.leastsq_param_size(nFunc))) for n in range( 0, gPulses ): if ( stf.set_trace( n ) == False ): print('Couldn\'t set a new trace; aborting now.') return False print('Analyzing trace %d of %d'%( n+1, stf.get_size_channel())) # set the fit window cursors: if ( not(stf.set_peak_end( gPeakStartCtrl + gPeakWindowSizes[n], True )) ): return False if ( not(stf.set_fit_start( gFitStart, True )) ): return False if ( not(stf.set_fit_end( gFitStart + gFitDurations[n], True )) ): return False stf.measure() # Least-squares fitting: p_dict = stf.leastsq( gFSelect ) if not filename=="": ls_file[n][0]=p_dict["gprime_na"] ls_file[n][1]=p_dict["tau_m"] ls_file[n][2]=p_dict["tau_h"] ls_file[n][3]=p_dict["offset"] if ( p_dict == 0 ): print('Couldn\'t perform a fit; aborting now.') return False # Create an empty list: tempdict_entry = [] row = 0 for k, v in p_dict.iteritems(): if ( firstpass == True ): dict_keys.append( k ) dict_values[row][n] = v row = row+1 if ( firstpass ): dict_keys.append( "Peak amplitude" ) dict_values[row][n] = stf.get_peak()-stf.get_base() firstpass = False if not filename=="": write_array(file(filename,'w'), ls_file, precision=15) retDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: retDict[ elem ] = dict_values[entry].tolist() entry = entry+1 return stf.show_table_dictlist( retDict ) def inact_batch(): """Determines peak amplitudes for inactivation protocol.""" stf = __import__("stf") # Some ugly definitions for the time being gDictSize = 1 # Parameters, chisqr, peak value gBaseStartCtrl = 69 # Start and end of the baseline before the control pulse, in ms gBaseEndCtrl = 70 gPeakStartCtrl = 70.12 # Start and end of the peak cursors for the control pulse, in ms gPeakWindowSize = 0.2 gPeakEndCtrl = gPeakStartCtrl + gPeakWindowSize gPulses = 11 # Number of traces if ( not(stf.check_doc()) ): print('Couldn\'t find an open file; aborting now.') return False # set cursors: if ( not(stf.set_peak_start( gPeakStartCtrl, True )) ): return False if ( not(stf.set_peak_end( gPeakEndCtrl, True )) ): return False if ( not(stf.set_base_start( gBaseStartCtrl, True )) ): return False if ( not(stf.set_base_end( gBaseEndCtrl, True )) ): return False if ( not(stf.set_peak_mean( 4 )) ): return False if ( not(stf.set_peak_direction( "both" )) ): return False # A list for dictionary keys and values: dict_keys = [ "Peak amplitude", ] dict_values = np.empty( (gDictSize, gPulses) ) for n in range( 0, gPulses ): if ( stf.set_trace( n ) == False ): print('Couldn\'t set a new trace; aborting now.') return False print('Analyzing pulse %d of %d'%( n+1, stf.get_size_channel())) # Update calculations: stf.measure() # Store values: dict_values[0][n] = stf.get_peak() - stf.get_base() inactDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: inactDict[ elem ] = dict_values[entry].tolist() entry = entry+1 return stf.show_table_dictlist( inactDict ) def deact_batch( filename="" ): """Fits deactivation time constants: Monoexponential until <=-70, biexponential for >-70 mV. filename -- If not an empty string, stores the best-fit parameters in this file.""" stf = __import__("stf") # Some ugly definitions for the time being gNMono = 5 # Monoexponential fits gNBi = 4 # Biexponential fits gFMono = 0 # id of monoexponential function gFBi = 3 # id of biexponential function gMonoDictSize = stf.leastsq_param_size( gFMono ) + 1 # Parameters, chisqr gBiDictSize = stf.leastsq_param_size( gFBi ) + 1 # Parameters, chisqr if ( gMonoDictSize < 0 or gBiDictSize < 0 ): print('Couldn\'t retrieve function; aborting now.') return False if ( not(stf.check_doc()) ): print('Couldn\'t find an open file; aborting now.') return False # set the test pulse window cursors: if ( not(stf.set_peak_start( 70.84, True )) ): return False if ( not(stf.set_peak_end( 74.84, True )) ): return False if ( not(stf.set_base_start( 69.5, True )) ): return False if ( not(stf.set_base_end( 70.5, True )) ): return False if ( not(stf.set_peak_mean( 1 )) ): return False if ( not(stf.set_peak_direction( "down" )) ): return False # Monoexponential loop --------------------------------------------------- firstpass = True # A list for dictionary keys... mono_keys = [] # ... and values: mono_values = np.empty( (gMonoDictSize, gNMono) ) if not filename=="": ls_file=np.empty((gNMono,stf.leastsq_param_size(gFMono))) # Monoexponential fits: for n in range( 0, gNMono ): if ( stf.set_trace( n ) == False ): print("Couldn't set a new trace; aborting now.") return False print('Analyzing trace %d of %d'%( n+1, stf.get_size_channel())) # set the fit window cursors: # use the index for the start cursor: if ( not(stf.set_fit_start( stf.peak_index( True ) )) ): return False # fit 1.5 ms: fit_end_time = stf.get_fit_start( True )+1.0 if ( not(stf.set_fit_end( fit_end_time, True)) ): return False # Least-squares fitting: p_dict = stf.leastsq( gFMono ) if not filename=="": ls_file[n][0]=p_dict["Amp_0"] ls_file[n][1]=p_dict["Tau_0"] ls_file[n][2]=p_dict["Offset"] if ( p_dict == 0 ): print('Couldn\'t perform a fit; aborting now.') return False # Create an empty list: tempdict_entry = [] row = 0 for k, v in p_dict.iteritems(): if ( firstpass == True ): mono_keys.append( k ) mono_values[row][n] = v row = row+1 firstpass = False monoDict = dict() # Create the dictionary for the table: entry = 0 for elem in mono_keys: monoDict[ elem ] = mono_values[entry].tolist() entry = entry+1 if ( not(stf.show_table_dictlist( monoDict )) ): return False # Biexponential loop --------------------------------------------------- firstpass = True # A list for dictionary keys... bi_keys = [] # ... and values: bi_values = np.empty( (gBiDictSize, gNBi) ) # Monoexponential fits: for n in range( gNMono, gNBi+gNMono ): if ( stf.set_trace( n ) == False ): print('Couldn\'t set a new trace; aborting now.') return False print('Analyzing trace %d of %d'%( n+1, stf.get_size_channel())) # set the fit window cursors: # use the index for the start cursor: if ( not(stf.set_fit_start( stf.peak_index( True ) )) ): return False # fit 4 ms: fit_end_time = stf.get_fit_start( True )+3.5 if ( not(stf.set_fit_end( fit_end_time, True)) ): return False # Least-squares fitting: p_dict = stf.leastsq( gFBi ) if ( p_dict == 0 ): print('Couldn\'t perform a fit; aborting now.') return False # Create an empty list: tempdict_entry = [] row = 0 for k, v in p_dict.iteritems(): if ( firstpass == True ): bi_keys.append( k ) bi_values[row][n-gNMono] = v row = row+1 firstpass = False biDict = dict() # Create the dictionary for the table: entry = 0 for elem in bi_keys: biDict[ elem ] = bi_values[entry].tolist() entry = entry+1 if not filename=="": write_array(file(filename,'w'), ls_file, precision=15) if ( not(stf.show_table_dictlist( biDict )) ): return False return True def inact_recov_batch( show_table = True ): """Determines recovery from inactivation.""" stf = __import__("stf") if ( not(stf.check_doc()) ): print('Couldn\'t find an open file; aborting now.') return False # Some ugly definitions for the time being gBaseStartCtrl = 69 # Start and end of the baseline before the control pulse, in ms gBaseEndCtrl = 70 gPeakStartCtrl = 70.12 # Start and end of the peak cursors for the control pulse, in ms gPeakWindowSize = 0.5 gPeakEndCtrl = gPeakStartCtrl + gPeakWindowSize gDictSize = 2 # Control peak amplitude, test peak amplitude gDurations = ( 0, 1, 2, 3, 5, 7, 9, 13, 20, 30, 50, 100 ) # Durations of the pulses gPulses = len( gDurations ) # Number of pulses # A list for dictionary keys... dict_keys = [ "Control amplitude", "Test amplitude" ] # ... and values: dict_values = np.empty( (gDictSize, gPulses) ) if ( not(stf.set_peak_mean( 3 )) ): return False if ( not(stf.set_peak_direction( "down" )) ): return False for n in range( 0, gPulses ): if ( stf.set_trace( n ) == False ): print('Couldn\'t set a new trace; aborting now.') return False # set the control pulse window cursors: if ( not(stf.set_peak_start( gPeakStartCtrl, True )) ): return False if ( not(stf.set_peak_end( gPeakEndCtrl, True )) ): return False if ( not(stf.set_base_start( gBaseStartCtrl, True )) ): return False if ( not(stf.set_base_end( gBaseEndCtrl, True )) ): return False # Update calculations: stf.measure() # Store values: dict_values[0][n] = stf.get_peak() - stf.get_base() # set the test pulse window cursors: if ( not(stf.set_peak_start( gDurations[n]+100.16, True )) ): return False if ( not(stf.set_peak_end( gDurations[n]+100.16+gPeakWindowSize, True )) ): return False if ( not(stf.set_base_start( gDurations[n]+100-1, True )) ): return False if ( not(stf.set_base_end( gDurations[n]+100, True )) ): return False # Update calculations: stf.measure() # Store values: dict_values[1][n] = stf.get_peak() - stf.get_base() inactDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: inactDict[ elem ] = dict_values[entry].tolist() entry = entry+1 if show_table: if not stf.show_table_dictlist( inactDict ): return -1 return dict_values def inact_onset_batch( show_table = True ): """Determines onset of inactivation.""" stf = __import__("stf") if ( not(stf.check_doc()) ): print('Couldn\'t find an open file; aborting now.') return -1 # Some ugly definitions for the time being gPeakWindowSize = 0.5 gDictSize = 1 # Control peak amplitude, test peak amplitude gDurations = ( 0, 1, 2, 3, 5, 7, 9, 13, 20, 25, 30 ) # Durations of the pulses gPulses = len( gDurations ) # Number of pulses # A list for dictionary keys... dict_keys = [ "Test amplitude", ] # ... and values: dict_values = np.empty( (gDictSize, gPulses) ) if ( not(stf.set_peak_mean( 4 )) ): return -1 if ( not(stf.set_peak_direction( "down" )) ): return -1 for n in range( 0, gPulses ): if ( stf.set_trace( n ) == False ): print('Couldn\'t set a new trace; aborting now.') return -1 print('Analyzing pulse %d of %d'%( n+1, stf.get_size_channel())) # set the test pulse window cursors: if ( not(stf.set_peak_start( gDurations[n]+70.12, True )) ): return -1 if ( not(stf.set_peak_end( gDurations[n]+70.12+gPeakWindowSize, True )) ): return -1 if ( not(stf.set_base_start( gDurations[n]+70-1, True )) ): return -1 if ( not(stf.set_base_end( gDurations[n]+70, True )) ): return -1 # Update calculations: stf.measure() # Store values: dict_values[0][n] = stf.get_peak() - stf.get_base() inactDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: inactDict[ elem ] = dict_values[entry].tolist() entry = entry+1 if show_table: if not stf.show_table_dictlist( inactDict ): return -1 return dict_values[0] stimfit-0.16.7/src/stimfit/py/pystf.cxx0000775000175000017500000015235614752207205013561 #include #include #ifndef WX_PRECOMP #include "wx/wx.h" #endif #ifdef _WINDOWS #ifdef _DEBUG #undef _DEBUG #define _UNDEBUG #endif #endif #ifdef _POSIX_C_SOURCE #define _POSIX_C_SOURCE_WAS_DEF #undef _POSIX_C_SOURCE #endif #ifdef _XOPEN_SOURCE #define _XOPEN_SOURCE_WAS_DEF #undef _XOPEN_SOURCE #endif #ifdef WITH_PYTHON #include #endif #ifdef _POSIX_C_SOURCE_WAS_DEF #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE #endif #endif #ifdef _XOPEN_SOURCE_WAS_DEF #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #endif #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic ignored "-Wwrite-strings" #endif #ifdef WITH_PYTHON #if PY_MAJOR_VERSION >= 3 #include #include #define PyInt_FromLong PyLong_FromLong #define PyString_AsString PyBytes_AsString #else #include #endif #endif // revert to previous behaviour #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic warning "-Wwrite-strings" #endif #ifdef _WINDOWS #ifdef _UNDEBUG #define _DEBUG #endif #endif #ifdef WITH_PYTHON #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #endif #include #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #endif #include "pystf.h" #include "./../gui/app.h" #include "./../gui/doc.h" #include "./../gui/view.h" #include "./../gui/graph.h" #include "./../gui/parentframe.h" #include "./../gui/childframe.h" #include "./../gui/dlgs/cursorsdlg.h" #include "./../../libstfnum/fit.h" #ifdef WITH_PYTHON #define array_data(a) (((PyArrayObject *)a)->data) #endif std::vector< std::vector< Vector_double > > gMatrix; std::vector< std::string > gNames; double _figsize[] = {8.0,6.0}; #if PY_MAJOR_VERSION >= 3 int wrap_array() { #ifdef WITH_PYTHON import_array1(-1); #endif return 0; } #else void wrap_array() { #ifdef WITH_PYTHON import_array(); #endif } #endif void ShowExcept(const std::exception& e) { wxString msg; msg << wxT("Caught an exception in the python module:\n") << wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg( msg ); return; } void ShowError( const wxString& msg ) { wxString fullmsg; fullmsg << wxT("Error in the python module:\n") << msg; wxGetApp().ErrorMsg( msg ); return; } wxStfDoc* actDoc() { return wxGetApp().GetActiveDoc(); } wxStfGraph* actGraph() { if ( !check_doc() ) return NULL; wxStfView* pView=(wxStfView*)actDoc()->GetFirstView(); if ( !pView ) return NULL; return pView->GetGraph(); } bool refresh_graph() { wxStfGraph* pGraph = actGraph(); if ( !pGraph ) { ShowError( wxT("Pointer to graph is zero") ); return false; } pGraph->Refresh(); return true; } // update data and labels in the results box bool update_results_table(){ wxStfChildFrame* pFrame = (wxStfChildFrame*)actDoc()->GetDocumentWindow(); if (!pFrame) { ShowError( wxT("Error in update_results_table()") ); return false; } wxGetApp().OnPeakcalcexecMsg(); pFrame->UpdateResults(); return true; } void write_stf_registry(const wxString& item, int value){ wxGetApp().wxWriteProfileInt(wxT("Settings"), item, value); } bool update_cursor_dialog( ) { if (wxGetApp().GetCursorsDialog()!=NULL && wxGetApp().GetCursorsDialog()->IsShown()) { try { wxGetApp().GetCursorsDialog()->UpdateCursors(); } catch (const std::runtime_error& e) { ShowExcept( e ); // We don't necessarily need to return false here. } } return refresh_graph(); } bool check_doc( bool show_dialog ) { if (actDoc() == NULL) { if (show_dialog) ShowError( wxT("Couldn't find open file") ); return false; } return true; } std::string get_filename( ) { if ( !check_doc() ) return 0; #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) return std::string(actDoc()->GetFilename()); #else return std::string(actDoc()->GetFilename().mb_str()); #endif } std::string get_versionstring() { #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) return std::string(wxGetApp().GetVersionString()); #else return std::string(wxGetApp().GetVersionString().mb_str()); #endif } #ifdef WITH_PYTHON PyObject* get_trace(int trace, int channel) { wrap_array(); if ( !check_doc() ) return NULL; if ( trace == -1 ) { trace = actDoc()->GetCurSecIndex(); } if ( channel == -1 ) { channel = actDoc()->GetCurChIndex(); } npy_intp dims[1] = {(int)actDoc()->at(channel).at(trace).size()}; PyObject* np_array = PyArray_SimpleNew(1, dims, NPY_DOUBLE); double* gDataP = (double*)PyArray_DATA((PyArrayObject*)np_array); /* fill */ std::copy( (*actDoc())[channel][trace].get().begin(), (*actDoc())[channel][trace].get().end(), gDataP); return np_array; } #endif bool new_window( double* invec, int size ) { bool open_doc = actDoc() != NULL; std::vector< double > va(size); std::copy( &invec[0], &invec[size], va.begin() ); Section sec(va); Channel ch(sec); if (open_doc) { ch.SetYUnits( actDoc()->at( actDoc()->GetCurChIndex() ).GetYUnits() ); } Recording new_rec( ch ); if (open_doc) { new_rec.SetXScale( actDoc()->GetXScale() ); } wxStfDoc* testDoc = wxGetApp().NewChild( new_rec, actDoc(), wxT("From python") ); if ( testDoc == NULL ) { ShowError( wxT("Failed to create a new window.") ); return false; } return true; } bool _new_window_gMatrix( ) { bool open_doc = actDoc() != NULL; Recording new_rec( gMatrix.size() ); for (std::size_t n_c=0; n_c < new_rec.size(); ++n_c) { Channel ch( gMatrix[n_c].size() ); for ( std::size_t n_s = 0; n_s < ch.size(); ++n_s ) { ch.InsertSection( Section(gMatrix[n_c][n_s]), n_s ); } std::string yunits = ""; if (open_doc) { yunits = actDoc()->at( actDoc()->GetCurChIndex() ).GetYUnits(); } ch.SetYUnits( yunits ); if ( !gNames.empty() ) { ch.SetChannelName(gNames[n_c]); } new_rec.InsertChannel( ch, n_c ); } gNames.resize(0); double xscale = 1.0; if (open_doc) { xscale = actDoc()->GetXScale(); } new_rec.SetXScale( xscale ); wxStfDoc* pDoc = NULL; if ( open_doc ) { pDoc = actDoc(); } wxStfDoc* testDoc = wxGetApp().NewChild( new_rec, pDoc, wxT("From python") ); if ( testDoc == NULL ) { ShowError( wxT("Failed to create a new window.") ); return false; } return true; } bool new_window_matrix( double* invec, int traces, int size ) { bool open_doc = actDoc() != NULL; Channel ch( traces ); for (int n = 0; n < traces; ++n) { std::size_t offset = n * size; std::vector< double > va(size); std::copy( &invec[offset], &invec[offset+size], &va[0] ); Section sec(va); ch.InsertSection(sec, n); } if (open_doc) { ch.SetYUnits( actDoc()->at( actDoc()->GetCurChIndex() ).GetYUnits() ); } Recording new_rec( ch ); if (open_doc) { new_rec.SetXScale( actDoc()->GetXScale() ); } wxStfDoc* testDoc = wxGetApp().NewChild( new_rec, actDoc(), wxT("From python") ); if ( testDoc == NULL ) { ShowError( wxT("Failed to create a new window.") ); return false; } return true; } bool new_window_selected_this( ) { if ( !check_doc() ) return false; if ( !actDoc()->OnNewfromselectedThis( ) ) { return false; } return true; } bool new_window_selected_all( ) { if ( !check_doc() ) return false; try { wxCommandEvent wce; wxGetApp().OnNewfromselected( wce ); } catch ( const std::exception& e) { ShowExcept( e ); return false; } return true; } int get_size_trace( int trace, int channel ) { if ( !check_doc() ) return 0; if ( trace == -1 ) { trace = actDoc()->GetCurSecIndex(); } if ( channel == -1 ) { channel = actDoc()->GetCurChIndex(); } int size = 0; try { size = actDoc()->at(channel).at(trace).size(); } catch ( const std::out_of_range& e) { ShowExcept( e ); return 0; } return size; } int get_size_channel( int channel ) { if ( !check_doc() ) return 0; if ( channel == -1 ) { channel = actDoc()->GetCurChIndex(); } int size = 0; try { size = actDoc()->at(channel).size(); } catch ( const std::out_of_range& e) { ShowExcept( e ); return 0; } return size; } int get_size_recording( ) { if ( !check_doc() ) return 0; return actDoc()->size(); } double get_maxdecay() { if ( !check_doc() ) return -1.0; return actDoc()->GetMaxDecay(); } double get_maxrise() { if ( !check_doc() ) return -1.0; return actDoc()->GetMaxRise(); } const char* get_recording_time( ) { if ( !check_doc() ) return 0; static char buffer[9]; struct tm dt = actDoc()->GetDateTime(); // Use strftime to format the time into the buffer. if (strftime(buffer, sizeof(buffer), "%H:%M:%S", &dt) == 0) { return NULL; } return buffer; } const char* get_recording_date( ) { if ( !check_doc() ) return 0; static char buffer[11]; struct tm dt = actDoc()->GetDateTime(); // Use strftime to format the time into the buffer. if (strftime(buffer, sizeof(buffer), "%Y:%m:%d", &dt) == 0) { return NULL; } return buffer; } std::string get_recording_comment( ) { if ( !check_doc() ) return ""; std::ostringstream comment; comment << actDoc()->GetFileDescription() << actDoc()->GetGlobalSectionDescription(); return comment.str(); } bool set_recording_comment( const char* comment ) { if ( !check_doc() ) return false; actDoc()->SetFileDescription(comment); return true; } bool set_recording_date( const char* date ) { if ( !check_doc() ) return false; actDoc()->SetDate(date); return true; } bool set_recording_time( const char* time ) { if ( !check_doc() ) return false; actDoc()->SetTime(time); return true; } bool select_trace( int trace ) { if ( !check_doc() ) return false; int max_size = (int)actDoc()->at(actDoc()->GetCurChIndex()).size(); if (trace < -1 || trace >= max_size) { wxString msg; msg << wxT("Select a trace with a zero-based index between 0 and ") << max_size-1; ShowError( msg ); return false; } if ((int)actDoc()->GetSelectedSections().size() == max_size) { ShowError(wxT("No more traces can be selected\nAll traces are selected")); return false; } if ( trace == -1 ) { trace = actDoc()->GetCurSecIndex(); } // control whether trace has already been selected: bool already=false; for (c_st_it cit = actDoc()->GetSelectedSections().begin(); cit != actDoc()->GetSelectedSections().end() && !already; ++cit) { if ((int)*cit == trace) { already = true; } } // add trace number to selected numbers, print number of selected traces if (!already) { actDoc()->SelectTrace(trace, actDoc()->GetBaseBeg(), actDoc()->GetBaseEnd()); //String output in the trace navigator wxStfChildFrame* pFrame = (wxStfChildFrame*)actDoc()->GetDocumentWindow(); if ( !pFrame ) { ShowError( wxT("Pointer to frame is zero") ); return false; } pFrame->SetSelected(actDoc()->GetSelectedSections().size()); } else { ShowError( wxT("Trace is already selected") ); return false; } return true; } void select_all( ) { if ( !check_doc() ) return; wxCommandEvent wce; actDoc()->Selectall( wce ); } void unselect_all( ) { if ( !check_doc() ) return; wxCommandEvent wce; actDoc()->Deleteselected( wce ); } #ifdef WITH_PYTHON PyObject* get_selected_indices() { if ( !check_doc() ) return NULL; PyObject* retObj = PyTuple_New( (int)actDoc()->GetSelectedSections().size() ); c_st_it cit; int n=0; for ( cit = actDoc()->GetSelectedSections().begin(); cit != actDoc()->GetSelectedSections().end(); ++cit ) { PyTuple_SetItem(retObj, n++, PyInt_FromLong( (long)*cit ) ); } // The main program apparently takes the ownership of the tuple; // no reference count decrement should be performed here. return retObj; } #endif bool set_trace( int trace ) { if ( !check_doc() ) return false; // use only with open document if ( !actDoc()->SetSection( trace ) ) { return false; } wxGetApp().OnPeakcalcexecMsg(); wxStfChildFrame* pFrame = (wxStfChildFrame*)actDoc()->GetDocumentWindow(); if ( !pFrame ) { ShowError( wxT("Pointer to frame is zero") ); return false; } pFrame->SetCurTrace( trace ); return refresh_graph(); } int get_trace_index() { if ( !check_doc() ) return -1; return actDoc()->GetCurSecIndex(); } int get_channel_index( bool active ) { if ( !check_doc() ) return -1; if ( active ) return actDoc()->GetCurChIndex(); else return actDoc()->GetSecChIndex(); } bool set_channel(int channel) { if ( !check_doc() ) return false; // use only with open document // channel negative if (channel<0) { ShowError( wxT("Negative value is not allowed") ); return false; } // only if we want to change the active channel if ((unsigned int)channel == actDoc()->GetCurChIndex() ) { return true; } int reference_ch = actDoc()->GetCurChIndex(); // catch exceptions (i.e out of range) try { actDoc()->SetCurChIndex(channel); } catch (const std::out_of_range& e) { ShowError( wxT("Value exceeds the number of available channels") ); return false; } // Pointer to wxStfChildFrame to access Channel selection combo wxStfChildFrame* pFrame = (wxStfChildFrame*)actDoc()->GetDocumentWindow(); if (!pFrame) { ShowError( wxT("Pointer to frame is zero") ); return false; } // set the channel selection combo //pFrame->SetChannels( actDoc()->GetCurChIndex(), actDoc()->GetSecChIndex()); pFrame->SetChannels( actDoc()->GetCurChIndex(), reference_ch); pFrame->UpdateChannels(); // update according to the combo return refresh_graph(); } const char* get_channel_name( int index ) { if ( !check_doc() ) return ""; if (index < 0) { index = actDoc()->GetCurChIndex(); } try { return actDoc()->at( index ).GetChannelName().c_str(); } catch (const std::out_of_range& e) { wxString msg(wxT("Index out of range in get_channel_name:\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return ""; } } bool set_channel_name( const char* name, int index ) { if ( !check_doc() ) return ""; if (index < 0) { index = actDoc()->GetCurChIndex(); } try { actDoc()->at( index ).SetChannelName(name); } catch (const std::out_of_range& e) { wxString msg(wxT("Index out of range in get_channel_name:\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return false; } return true; } const char* get_trace_name( int trace, int channel ) { if ( !check_doc() ) return ""; if (channel < 0) { channel = actDoc()->GetCurChIndex(); } if (trace < 0) { trace = actDoc()->GetCurSecIndex(); } try { return actDoc()->at( channel ).at( trace ).GetSectionDescription().c_str(); } catch (const std::out_of_range& e) { wxString msg(wxT("Index out of range in get_trace_name:\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return ""; } } bool subtract_base( ) { if ( !check_doc() ) return false; return actDoc()->SubtractBase(); } bool file_open( const char* filename ) { wxString wxFilename( filename, wxConvLocal ); return wxGetApp().OpenFilePy( wxFilename ); } bool file_save( const char* filename ) { if ( !check_doc() ) return false; wxString wxFilename( filename, wxConvLocal ); return actDoc()->OnSaveDocument( wxFilename ); } bool close_all( ) { return wxGetApp().CloseAll(); } bool close_this( ) { if ( !check_doc() ) return false; return actDoc()->DeleteAllViews( ); } double peak_index( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetMaxT(); } else { // Test whether a second channel is available at all: if ( actDoc()->size() < 2 ) { ShowError( wxT("No second channel found") ); return -1.0; } return actDoc()->GetAPMaxT(); } } double maxrise_index( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetMaxRiseT(); } else { // Test whether a second channel is available at all: if ( actDoc()->size() < 2 ) { ShowError( wxT("No second channel found") ); return -1.0; } return actDoc()->GetAPMaxRiseT(); } } double maxdecay_index( ) { if ( !check_doc() ) return -1.0; return actDoc()->GetMaxDecayT(); } double foot_index( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetTLoReal() - (actDoc()->GetTHiReal() - actDoc()->GetTLoReal()) / 3.0; } else { ShowError( wxT("At this time, foot_index() is only implemented for the active channel") ); return -1.0; } } double t50left_index( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetT50LeftReal(); } else { // Test whether a second channel is available at all: if ( actDoc()->size() < 2 ) { ShowError( wxT("No second channel found") ); return -1.0; } return actDoc()->GetAPT50LeftReal(); } } double t50right_index( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetT50RightReal(); } else { ShowError( wxT("At this time, t50right_index() is only implemented for the active channel") ); return -1.0; } } double get_halfwidth( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { double dt = actDoc()->GetXScale(); double t50left = actDoc()->GetT50LeftReal(); double t50right = actDoc()->GetT50RightReal(); return ( t50right-t50left )*dt; } else { ShowError( wxT("At this time, halfwidth is only implemented for the active channel") ); return -1.0; } } double rtlow_index( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetTLoReal(); } else { ShowError( wxT("At this time, rtlow_index() is only implemented for the active channel") ); return -1.0; } } double rthigh_index( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetTHiReal(); } else { ShowError( wxT("At this time, rthigh_index() is only implemented for the active channel") ); return -1.0; } } double get_threshold_time( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetThrT(); else return (double)actDoc()->GetThrT() * actDoc()->GetXScale(); } double get_threshold_value( ) { if ( !check_doc() ) return -1; return actDoc()->GetThreshold(); } double get_latency( ) { if ( !check_doc() ) return -1.0; double dt = actDoc()->GetXScale(); return ( actDoc()->GetLatency() )*dt; } double get_risetime( ) { if ( !check_doc() ) return -1.0; double dt = actDoc()->GetXScale(); return ( actDoc()->GetTHiReal()-actDoc()->GetTLoReal() )*dt; } double get_risetime_factor() { if ( !check_doc() ) return -1.0; return actDoc()->GetRTFactor()/100.; } double get_fit_start( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetFitBeg(); else return (double)actDoc()->GetFitBeg() * actDoc()->GetXScale(); } bool set_risetime_factor(double factor) { if ( !check_doc() ) return false; if (factor > 0.45 || factor < 0.05) { ShowError( wxT("Value out of range (0.05-0.45) in set_risetime_factor()") ); return false; } int RTFactor = (int)(factor*100); actDoc()->SetRTFactor(RTFactor); // defined in wxStfApp::OnPeakcalcexecMsg update_cursor_dialog(); update_results_table(); write_stf_registry(wxT("RTFactor"), RTFactor); return true; } bool set_fit_start( double pos, bool is_time ) { if ( !check_doc() ) return false; if ( is_time ) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); // range check: if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ) { ShowError( wxT("Value out of range in set_fit_start()") ); return false; } //conversion of pixel on screen to time (inversion of xFormat()) if (wxGetApp().GetCursorsDialog() != NULL && wxGetApp().GetCursorsDialog()->GetStartFitAtPeak()) { ShowError( wxT("Fit will start at the peak. Change cursor settings (Edit->Cursor settings) to set manually.") ); return false; } actDoc()->SetFitBeg( posInt ); return update_cursor_dialog(); } double get_fit_end( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetFitEnd(); else return (double)actDoc()->GetFitEnd() * actDoc()->GetXScale(); } bool set_fit_end( double pos, bool is_time ) { if ( !check_doc() ) return false; if ( is_time ) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); // range check: if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ) { ShowError( wxT("Value out of range in set_fit_end()") ); return false; } //conversion of pixel on screen to time (inversion of xFormat()) if (wxGetApp().GetCursorsDialog() != NULL && wxGetApp().GetCursorsDialog()->GetStartFitAtPeak()) { ShowError( wxT("Fit will start at the peak. Change cursor settings (Edit->Cursor settings) to set manually.") ); return false; } actDoc()->SetFitEnd( posInt ); return update_cursor_dialog(); } double get_peak_start( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetPeakBeg(); else return (double)actDoc()->GetPeakBeg() * actDoc()->GetXScale(); } bool set_peak_start( double pos, bool is_time ) { if ( !check_doc() ) return false; if ( is_time ) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); // range check: if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ) { ShowError( wxT("Value out of range in set_peak_start()") ); return false; } actDoc()->SetPeakBeg( posInt ); return update_cursor_dialog(); } double get_peak_end( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetPeakEnd(); else return (double)actDoc()->GetPeakEnd() * actDoc()->GetXScale(); } bool set_peak_end( double pos, bool is_time ) { if ( !check_doc() ) return false; if ( is_time ) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); // range check: if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ) { ShowError( wxT("Value out of range in set_peak_end()") ); return false; } actDoc()->SetPeakEnd( posInt ); return update_cursor_dialog(); } bool set_peak_mean( int pts ) { if ( !check_doc() ) return false; // range check (-1 is a legal value!): if ( pts == 0 || pts < -1 ) { ShowError( wxT("Value out of range in set_peak_mean()") ); return false; } actDoc()->SetPM( pts ); return update_cursor_dialog(); } int get_peak_mean() { if ( !check_doc() ) return 0; return (int)actDoc()->GetPM(); } const char* get_peak_direction( ) { if ( !check_doc() ) return ""; const char *direction = "both"; if ( actDoc()->GetDirection() == stfnum::up ) direction = "up"; else if ( actDoc()->GetDirection() == stfnum::down ) direction = "down"; else if ( actDoc()->GetDirection() == stfnum::both ) direction = "both"; return direction; } bool set_peak_direction( const char* direction ) { if ( !check_doc() ) return false; if ( strcmp( direction, "up" ) == 0 ) { actDoc()->SetDirection( stfnum::up ); return update_cursor_dialog(); } if ( strcmp( direction, "down" ) == 0 ) { actDoc()->SetDirection( stfnum::down ); return update_cursor_dialog(); } if ( strcmp( direction, "both" ) == 0 ) { actDoc()->SetDirection( stfnum::both ); return update_cursor_dialog(); } wxString msg; msg << wxT("\"") << wxString::FromAscii(direction) << wxT("\" is not a valid direction\n"); msg << wxT("Use \"up\", \"down\" or \"both\""); ShowError( msg ); return false; } const char* get_baseline_method() { if ( !check_doc() ) return ""; const char *method=" "; if ( actDoc()->GetBaselineMethod() == stfnum::mean_sd ) method = "mean"; else if ( actDoc()->GetBaselineMethod() == stfnum::median_iqr ) method = "median"; return method; } bool set_baseline_method( const char* method ) { if ( !check_doc() ) return false; const wxString myitem = wxT("BaselineMethod"); if ( strcmp( method, "mean" ) == 0 ) { actDoc()->SetBaselineMethod( stfnum::mean_sd ); update_cursor_dialog(); update_results_table(); write_stf_registry(myitem, stfnum::mean_sd); return true; } else if ( strcmp( method, "median" ) == 0 ) { actDoc()->SetBaselineMethod( stfnum::median_iqr ); update_cursor_dialog(); // update wxStfCursorsDlg update_results_table(); // update results and labels in the table write_stf_registry(myitem, stfnum::median_iqr); // write in .Stimfit return true; } else { wxString msg; msg << wxT("\"") << wxString::FromAscii(method) << wxT("\" is not a valid method\n"); msg << wxT("Use \"mean\" or \"median\""); ShowError( msg ); return false; } } const char* get_latency_start_mode( ) { if ( !check_doc() ) return ""; const char *mode = "undefined"; if ( actDoc()->GetLatencyStartMode() == stf::manualMode ) mode = "manual"; else if ( actDoc()->GetLatencyStartMode() == stf::peakMode ) mode = "peak"; else if ( actDoc()->GetLatencyStartMode() == stf::riseMode ) mode = "rise"; else if ( actDoc()->GetLatencyStartMode() == stf::halfMode ) mode = "half"; return mode; } bool set_latency_start(double pos, bool is_time) { if ( !check_doc() ) return false; if (is_time) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); /* range check */ if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ){ ShowError( wxT("Value out of range in set_latency_start()") ); return false; } actDoc()->SetLatencyStartMode( stf::manualMode ); actDoc()->SetLatencyBeg( posInt ); /* set start latency mode to manual and write in registry */ const wxString myitem = wxT("LatencyStartMode"); bool dlg_OK, result_OK; dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::manualMode); return true; } return false; } bool set_latency_start_mode( const char* mode ) { if ( !check_doc() ) return false; const wxString myitem = wxT("LatencyStartMode"); bool dlg_OK, result_OK; if ( strcmp( mode, "manual" ) == 0 ) { actDoc()->SetLatencyStartMode( stf::manualMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::manualMode); return true; } return false; } else if ( strcmp( mode, "peak" ) == 0 ) { actDoc()->SetLatencyStartMode( stf::peakMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::peakMode); return true; } return false; } else if ( strcmp( mode, "rise" ) == 0 ) { actDoc()->SetLatencyStartMode( stf::riseMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::riseMode); return true; } return false; } else if ( strcmp( mode, "half" ) == 0 ) { actDoc()->SetLatencyStartMode( stf::halfMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::halfMode); return true; } return false; } else { wxString msg; msg << wxT("\"") << wxString::FromAscii(mode) << wxT("\" is not a valid start latency mode\n"); msg << wxT("Use \"manual\", \"peak\", \"rise\" or \"half\""); ShowError( msg ); return false; } } const char* get_latency_end_mode( ) { if ( !check_doc() ) return ""; const char *mode = "undefined"; if ( actDoc()->GetLatencyEndMode() == stf::manualMode ) mode = "manual"; else if ( actDoc()->GetLatencyEndMode() == stf::peakMode ) mode = "peak"; else if ( actDoc()->GetLatencyEndMode() == stf::riseMode ) mode = "rise"; else if ( actDoc()->GetLatencyEndMode() == stf::halfMode ) mode = "half"; else if ( actDoc()->GetLatencyEndMode() == stf::footMode ) mode = "foot"; return mode; } bool set_latency_end(double pos, bool is_time) { if ( !check_doc() ) return false; if (is_time) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); /* range check */ if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ){ ShowError( wxT("Value out of range in set_latency_start()") ); return false; } actDoc()->SetLatencyEndMode( stf::manualMode ); actDoc()->SetLatencyEnd( posInt ); /* set start latency mode to manual and write in registry */ const wxString myitem = wxT("LatencyEndMode"); bool dlg_OK, result_OK; dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::manualMode); return true; } return false; } bool set_latency_end_mode( const char* mode ) { if ( !check_doc() ) return false; const wxString myitem = wxT("LatencyEndMode"); bool dlg_OK, result_OK; if ( strcmp( mode, "manual" ) == 0 ) { actDoc()->SetLatencyEndMode( stf::manualMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::manualMode); return true; } return false; } else if ( strcmp( mode, "peak" ) == 0 ) { actDoc()->SetLatencyEndMode( stf::peakMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::peakMode); return true; } return false; } else if ( strcmp( mode, "rise" ) == 0 ) { actDoc()->SetLatencyEndMode( stf::riseMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::riseMode); return true; } return false; } else if ( strcmp( mode, "half" ) == 0 ) { actDoc()->SetLatencyEndMode( stf::halfMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::halfMode); return true; } return false; } else if ( strcmp( mode, "foot" ) == 0 ) { actDoc()->SetLatencyEndMode( stf::footMode ); dlg_OK = update_cursor_dialog(); result_OK = update_results_table(); if (dlg_OK && result_OK) { write_stf_registry(myitem, stf::footMode); return true; } return false; } else { wxString msg; msg << wxT("\"") << wxString::FromAscii(mode) << wxT("\" is not a valid end latency mode\n"); msg << wxT("Use \"manual\", \"peak\", \"rise\", \"half\" or \"foot\""); ShowError( msg ); return false; } } double get_latency_start( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetLatencyBeg(); else return (double)actDoc()->GetLatencyBeg() * actDoc()->GetXScale(); } double get_latency_end( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetLatencyEnd(); else return (double)actDoc()->GetLatencyEnd() * actDoc()->GetXScale(); } double get_base_SD() { if ( !check_doc() ) return 0.0; return actDoc()->GetBaseSD(); } double get_base_start( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetBaseBeg(); else return (double)actDoc()->GetBaseBeg() * actDoc()->GetXScale(); } bool set_base_start( double pos, bool is_time ) { if ( !check_doc() ) return false; if ( is_time ) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); // range check: if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ) { ShowError( wxT("Value out of range in set_base_start()") ); return false; } actDoc()->SetBaseBeg( posInt ); return update_cursor_dialog(); } double get_base_end( bool is_time ) { if ( !check_doc() ) return -1; if ( !is_time ) return actDoc()->GetBaseEnd(); else return (double)actDoc()->GetBaseEnd() * actDoc()->GetXScale(); } bool set_base_end( double pos, bool is_time ) { if ( !check_doc() ) return false; if ( is_time ) pos /= actDoc()->GetXScale(); int posInt = stf::round( pos ); // range check: if ( posInt < 0 || posInt >= (int)actDoc()->cursec().size() ) { ShowError( wxT("Value out of range in set_base_end()") ); return false; } actDoc()->SetBaseEnd( posInt ); return update_cursor_dialog(); } bool set_slope(double slope) { if ( !check_doc() ) return false; actDoc()->SetSlopeForThreshold( slope ); actDoc()->SetFromBase( false ); return update_cursor_dialog(); } double get_sampling_interval( ) { if ( !check_doc() ) return -1.0; return actDoc()->GetXScale(); } const char* get_xunits( ) { if ( !check_doc() ) return ""; return actDoc()->GetXUnits().c_str(); } const char* get_yunits( int trace, int channel ) { if ( !check_doc() ) return ""; if (channel < 0) { channel = actDoc()->GetCurChIndex(); } if (trace < 0) { trace = actDoc()->GetCurSecIndex(); } try { return actDoc()->at( channel ).GetYUnits().c_str(); } catch (const std::out_of_range& e) { wxString msg(wxT("Index out of range in get_yunits:\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return ""; } } bool set_xunits( const char* units ) { if ( !check_doc() ) return false; actDoc()->SetXUnits(units); return true; } bool set_yunits( const char* units, int trace, int channel ) { if ( !check_doc() ) return false; if (channel < 0) { channel = actDoc()->GetCurChIndex(); } if (trace < 0) { trace = actDoc()->GetCurSecIndex(); } try { actDoc()->at( channel ).SetYUnits(units); } catch (const std::out_of_range& e) { wxString msg(wxT("Index out of range in set_yunits:\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return false; } return true; } bool set_sampling_interval( double si ) { if ( !check_doc() ) return false; if (si <= 0) { ShowError( wxT("New sampling interval needs to be greater than 0.") ); return false; } actDoc()->SetXScale( si ); return refresh_graph(); } bool measure( ) { if ( !check_doc() ) return false; // check cursor positions: if ( actDoc()->GetPeakBeg() > actDoc()->GetPeakEnd() ) { ShowError( wxT("Peak window cursors are reversed; will abort now.") ); return false; } if ( actDoc()->GetBaseBeg() > actDoc()->GetBaseEnd() ) { ShowError( wxT("Base window cursors are reversed; will abort now.") ); return false; } if ( actDoc()->GetFitBeg() > actDoc()->GetFitEnd() ) { ShowError( wxT("Fit window cursors are reversed; will abort now.") ); return false; } wxStfChildFrame* pFrame = (wxStfChildFrame*)actDoc()->GetDocumentWindow(); if ( !pFrame ) { ShowError( wxT("Pointer to frame is zero") ); return false; } wxGetApp().OnPeakcalcexecMsg(); pFrame->UpdateResults(); return true; } double get_base( bool active ) { if ( !check_doc() ) return -1.0; if ( active ) { return actDoc()->GetBase(); } else { // Test wheter a second channel is available at all: if ( actDoc()->size() < 2) { ShowError( wxT("No second channel was found") ); return -1.0; } return actDoc()->GetAPBase(); } } #ifdef WITH_PSLOPE double get_pslope() { if (!check_doc() ) return 0.0; return actDoc()->GetPSlope(); } #endif double get_peak( ) { if ( !check_doc() ) return 0.0; return actDoc()->GetPeak(); } void _gMatrix_resize( std::size_t channels, std::size_t sections ) { gMatrix.resize( channels ); std::vector< std::vector< Vector_double > >::iterator it; for (it = gMatrix.begin(); it != gMatrix.end(); ++it) { it->resize( sections ); } } void _gMatrix_at( double* invec, int size, int channel, int section ) { std::vector< double > va(size); std::copy( &invec[0], &invec[size], va.begin() ); try{ gMatrix.at(channel).at(section).resize( va.size() ); gMatrix[channel][section] = va; } catch (const std::out_of_range& e) { wxString msg(wxT("Out of range exception in _gMatrix_at:\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return; } } void _gNames_resize( std::size_t channels ) { gNames.resize( channels ); } void _gNames_at( const char* name, int channel ) { try{ gNames.at(channel) = std::string(name); } catch (const std::out_of_range& e) { wxString msg(wxT("Out of range exception in _gNames_at:\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return; } } void align_selected( double (*alignment)( bool ), bool active ) { if ( !check_doc() ) return; wxStfDoc* pDoc = actDoc(); //store current section: std::size_t section_old = pDoc->GetCurSecIndex(); if ( pDoc->GetSelectedSections().empty() ) { ShowError( wxT("No selected traces") ); return; } // check for a second channel if ( actDoc()->size() < 2 ) { ShowError( wxT("No second channel found") ); return; } //initialize the lowest and the highest index: std::size_t min_index=0; try { min_index=pDoc->get()[pDoc->GetSecChIndex()].at(pDoc->GetSelectedSections().at(0)).size()-1; } catch (const std::out_of_range& e) { wxString msg(wxT("Error while aligning\nIt is safer to re-start the program\n")); msg+=wxString( e.what(), wxConvLocal ); ShowError( msg ); return; } std::size_t max_index=0; std::vector shift( pDoc->GetSelectedSections().size(), 0 ); int_it it = shift.begin(); //loop through all selected sections: for (c_st_it cit = pDoc->GetSelectedSections().begin(); cit != pDoc->GetSelectedSections().end() && it != shift.end(); cit++) { //Set the selected section as the current section temporarily: pDoc->SetSection(*cit); if ( pDoc->GetPeakAtEnd() ) { pDoc->SetPeakEnd((int)pDoc->get()[pDoc->GetSecChIndex()][*cit].size()-1); } // Calculate all variables for the current settings // APMaxSlopeT will be calculated for the second (==reference) // channel, so channels may not be changed! try { pDoc->Measure(); } catch (const std::out_of_range& e) { ShowExcept( e ); return; } //check whether the current index is a max or a min, //and if so, store it: double alignIndex = alignment( active ); *it = stf::round( alignIndex ); if (alignIndex > max_index) { max_index=alignIndex; } if (alignIndex < min_index) { min_index=alignIndex; } it++; } // now that max and min indices are known, calculate the number of // points that need to be shifted: for (int_it it2 = shift.begin(); it2 != shift.end(); it2++) { (*it2) -= (int)min_index; } //restore section and channel settings: pDoc->SetSection( section_old ); int new_size=(int)(pDoc->get()[0][pDoc->GetSelectedSections()[0]].size()-(max_index-min_index)); Recording Aligned( pDoc->size(), pDoc->GetSelectedSections().size(), new_size ); ch_it chan_it; // Channel iterator std::size_t n_ch = 0; for ( ch_it chan_it = pDoc->get().begin(); chan_it != pDoc->get().end(); ++chan_it ) { Channel ch( pDoc->GetSelectedSections().size() ); ch.SetChannelName( pDoc->at(n_ch).GetChannelName() ); ch.SetYUnits( pDoc->at(n_ch).GetYUnits() ); std::size_t n_sec = 0; int_it it3 = shift.begin(); for ( c_st_it sel_it = pDoc->GetSelectedSections().begin(); sel_it != pDoc->GetSelectedSections().end() && it3 != shift.end(); ++sel_it ) { Vector_double va( new_size ); std::copy( &(chan_it->at( *sel_it ).get_w()[ 0 + (*it3) ]), &(chan_it->at( *sel_it ).get_w()[ (*it3) + new_size ]), &va[0] ); Section sec(va); ch.InsertSection(sec, n_sec++); ++it3; } Aligned.InsertChannel( ch, n_ch++ ); } wxString title( pDoc->GetTitle() ); title += wxT(", aligned"); Aligned.CopyAttributes( *pDoc ); wxStfDoc* testDoc = wxGetApp().NewChild(Aligned, pDoc, title); if ( testDoc == NULL ) { ShowError( wxT("Failed to create a new window.") ); } return; } int leastsq_param_size( int fselect ) { int npar = 0; try { npar = (int)wxGetApp().GetFuncLib().at(fselect).pInfo.size(); } catch (const std::out_of_range& e) { wxString msg( wxT("Could not retrieve function from library:\n") ); msg << wxString( e.what(), wxConvLocal ); ShowError(msg); return -1; } return npar; } PyObject* leastsq( int fselect, bool refresh ) { if ( !check_doc() ) return NULL; wxStfDoc* pDoc = actDoc(); wxCommandEvent wce; int n_params = 0; try { n_params=(int)wxGetApp().GetFuncLib().at(fselect).pInfo.size(); } catch (const std::out_of_range& e) { wxString msg( wxT("Could not retrieve function from library:\n") ); msg << wxString( e.what(), wxConvLocal ); ShowError(msg); return NULL; } std::vector< double > x( pDoc->GetFitEnd() - pDoc->GetFitBeg() ); //fill array: std::copy(&pDoc->cursec()[pDoc->GetFitBeg()], &pDoc->cursec()[pDoc->GetFitEnd()], &x[0]); std::vector< double > params( n_params ); // initialize parameters from init function, wxGetApp().GetFuncLib().at(fselect).init( x, pDoc->GetBase(), pDoc->GetPeak(), pDoc->GetRTLoHi(), pDoc->GetHalfDuration(), pDoc->GetXScale(), params ); std::string fitInfo; int fitWarning = 0; std::vector< double > opts( 6 ); // check values in src/stimfit/gui/dlgs/fitseldlg.cpp // Respectively the scale factor for initial damping term \mu, // stopping thresholds for ||J^T e||_inf, ||Dp||_2 and ||e||_2, // maxIter, maxPass //opts[0]=5*1E-3; //default: 1E-03; opts[0] = 1E-05; //default: 1E-03; opts[1] = 1E-17; //default: 1E-17; opts[2] = 1E-17; //default: 1E-17; opts[3] = 1E-32; //default: 1E-17; opts[4] = 64; //default: 64; opts[5] = 16; double chisqr = 0.0; try { chisqr = stfnum::lmFit( x, pDoc->GetXScale(), wxGetApp().GetFuncLib().at(fselect), opts, true, params, fitInfo, fitWarning ); pDoc->SetIsFitted( pDoc->GetCurChIndex(), pDoc->GetCurSecIndex(), params, wxGetApp().GetFuncLibPtr(fselect), chisqr, pDoc->GetFitBeg(), pDoc->GetFitEnd() ); } catch (const std::out_of_range& e) { ShowExcept( e ); return NULL; } catch (const std::runtime_error& e) { ShowExcept( e ); return NULL; } catch (const std::exception& e) { ShowExcept( e ); return NULL; } if ( refresh ) { if ( !refresh_graph() ) return NULL; } // Dictionaries apparently grow as needed; no initial size is required. PyObject* retDict = PyDict_New( ); for ( std::size_t n_dict = 0; n_dict < params.size(); ++n_dict ) { PyDict_SetItemString( retDict, wxGetApp().GetFuncLib()[fselect].pInfo.at(n_dict).desc.c_str(), PyFloat_FromDouble( params[n_dict] ) ); } PyDict_SetItemString( retDict, "SSE", PyFloat_FromDouble( chisqr ) ); return retDict; } #ifdef WITH_PYTHON PyObject* get_fit( int trace, int channel ) { wrap_array(); if ( !check_doc() ) return NULL; if ( trace == -1 ) { trace = actDoc()->GetCurSecIndex(); } if ( channel == -1 ) { channel = actDoc()->GetCurChIndex(); } /* Does the specified section contain a fit at all? */ stf::SectionAttributes sec_attr; try { sec_attr = actDoc()->GetSectionAttributes(channel, trace); } catch (const std::out_of_range& e) { return NULL; } if (!sec_attr.isFitted) { return Py_None; } unsigned int size = sec_attr.storeFitEnd - sec_attr.storeFitBeg; Vector_double xy_fit(2*size); for (unsigned int x = 0; x < size; ++x) { xy_fit[x] = (x+sec_attr.storeFitBeg) * actDoc()->GetXScale(); xy_fit[x+size] = sec_attr.fitFunc->func(x*actDoc()->GetXScale(), sec_attr.bestFitP); } npy_intp dims[2] = {2, size}; PyObject* np_array = PyArray_SimpleNew(2, dims, NPY_DOUBLE); double* gDataP = (double*)PyArray_DATA((PyArrayObject*)np_array); /* fill */ std::copy(xy_fit.begin(), xy_fit.end(), gDataP); return np_array; } #endif bool show_table( PyObject* dict, const char* caption ) { if ( !check_doc() ) return false; // Check whether the dictionary is intact: if ( !PyDict_Check( dict ) ) { ShowError( wxT("First argument to ShowTable() is not a dictionary.") ); return false; } std::map< std::string, double > pyMap; Py_ssize_t n_dict = 0; PyObject *pkey = NULL, *pvalue = NULL; while ( PyDict_Next( dict, &n_dict, &pkey, &pvalue ) ) { if ( !pkey || !pvalue ) { ShowError( wxT("Couldn't read from dictionary in ShowTable().") ); return false; } std::string key = PyString_AsString( pkey ); double value = PyFloat_AsDouble( pvalue ); pyMap[key] = value; } stfnum::Table pyTable( pyMap ); wxStfChildFrame* pFrame = (wxStfChildFrame*)actDoc()->GetDocumentWindow(); if ( !pFrame ) { ShowError( wxT("Pointer to frame is zero") ); return false; } pFrame->ShowTable( pyTable, wxString( caption, wxConvLocal ) ); return true; } bool show_table_dictlist( PyObject* dict, const char* caption, bool reverse ) { if ( !check_doc() ) return false; if ( !reverse ) { ShowError( wxT("Row-major order (reverse = False) has not been implemented yet.") ); return false; } // Check whether the dictionary is intact: if ( !PyDict_Check( dict ) ) { ShowError( wxT("First argument to ShowTable() is not a dictionary.") ); return false; } Py_ssize_t n_dict = 0; PyObject *pkey = NULL, *pvalue = NULL; std::vector< Vector_double > pyVector; std::vector< std::string > pyStrings; while ( PyDict_Next( dict, &n_dict, &pkey, &pvalue ) ) { if ( !pkey || !pvalue ) { ShowError( wxT("Couldn't read from dictionary in ShowTable().") ); return false; } pyStrings.push_back(PyString_AsString( pkey )); if ( !PyList_Check( pvalue ) ) { ShowError( wxT("Dictionary values are not (consistently) lists.") ); return false; } Vector_double values( PyList_Size( pvalue ) ); for (int n_list = 0; n_list < (int)values.size(); ++n_list ) { PyObject* plistvalue = PyList_GetItem( pvalue, n_list ); if ( !plistvalue ) { ShowError( wxT("Can't read list elements in show_table().") ); return false; } values[n_list] = PyFloat_AsDouble( plistvalue ); } pyVector.push_back( values ); } if ( pyVector.empty() ) { ShowError( wxT("Dictionary was empty in show_table().") ); return false; } stfnum::Table pyTable( pyVector[0].size(), pyVector.size() ); std::vector< std::vector< double > >::const_iterator c_va_it; std::size_t n_col = 0; for ( c_va_it = pyVector.begin(); c_va_it != pyVector.end(); ++c_va_it ) { try { pyTable.SetColLabel( n_col, pyStrings[n_col] ); for ( std::size_t n_va=0; n_va < (*c_va_it).size(); ++n_va ) { pyTable.at( n_va, n_col ) = (*c_va_it)[n_va]; } } catch ( const std::out_of_range& e ) { ShowExcept( e ); return false; } n_col++; } wxStfChildFrame* pFrame = (wxStfChildFrame*)actDoc()->GetDocumentWindow(); if ( !pFrame ) { ShowError( wxT("Pointer to frame is zero") ); return false; } pFrame->ShowTable( pyTable, wxString( caption, wxConvLocal ) ); return true; } bool set_marker(double x, double y) { if ( !check_doc() ) return false; try { actDoc()->GetCurrentSectionAttributesW().pyMarkers. push_back(stf::PyMarker(x,y)); } catch (const std::out_of_range& e) { wxString msg( wxT("Could not set the marker:\n") ); msg << wxString( e.what(), wxConvLocal ); ShowError(msg); return false; } return refresh_graph(); } bool erase_markers() { if ( !check_doc() ) return false; try { actDoc()->GetCurrentSectionAttributesW().pyMarkers.clear(); } catch (const std::out_of_range& e) { wxString msg( wxT("Could not erase markers:\n") ); msg << wxString( e.what(), wxConvLocal ); ShowError(msg); return false; } return refresh_graph(); } double plot_xmin() { wxStfGraph* pGraph = actGraph(); if ( !pGraph ) { ShowError( wxT("Pointer to graph is zero") ); return 0; } return pGraph->get_plot_xmin(); } double plot_xmax() { wxStfGraph* pGraph = actGraph(); if ( !pGraph ) { ShowError( wxT("Pointer to graph is zero") ); return 0; } return pGraph->get_plot_xmax(); } double plot_ymin() { wxStfGraph* pGraph = actGraph(); if ( !pGraph ) { ShowError( wxT("Pointer to graph is zero") ); return 0; } return pGraph->get_plot_ymin(); } double plot_ymax() { wxStfGraph* pGraph = actGraph(); if ( !pGraph ) { ShowError( wxT("Pointer to graph is zero") ); return 0; } return pGraph->get_plot_ymax(); } double plot_y2min() { wxStfGraph* pGraph = actGraph(); if ( !pGraph ) { ShowError( wxT("Pointer to graph is zero") ); return 0; } return pGraph->get_plot_y2min(); } double plot_y2max() { wxStfGraph* pGraph = actGraph(); if ( !pGraph ) { ShowError( wxT("Pointer to graph is zero") ); return 0; } return pGraph->get_plot_y2max(); } PyObject* mpl_panel(const std::vector& figsize) { if ( !check_doc() ) return NULL; if (figsize.size() < 2) { ShowError( wxT("figsize has to have length 2") ); } wxStfParentFrame* parent = wxGetApp().GetMainFrame(); if ( !parent ) { ShowError( wxT("Parent window is NULL") ); return 0; } std::ostringstream mpl_name; mpl_name << "mpl" << parent->GetMplFigNo(); int width = 800 * figsize[0]/8.0; int height = 600 * figsize[1]/6.0; PyObject* result = parent->MakePythonWindow("makeWindowMpl", mpl_name.str(), "Matplotlib", true, false, true, width, height, figsize[0], figsize[1]).pyWindow; return result; } stimfit-0.16.7/src/stimfit/py/gccwarn0000664000175000017500000000023414750344764013231 #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic ignored "-Wuninitialized" #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif stimfit-0.16.7/src/stimfit/py/embedded_stf.py0000664000175000017500000000330114750344764014637 #=========================================================================== # embedded_stf.py # 2009.09.14 # Don't modify this file unless you know what you are doing!!! #=========================================================================== """ embedded_stf.py starting code to embed wxPython into the stf application. """ import sys if 'win' in sys.platform and sys.platform != 'darwin': import wxversion wxversion.select('3.0-msw') import wx wx.CallAfter = lambda x, y : (x, y) from wx.py import shell # to access the current versions of Stimfit, NumPy and wxPython from embedded_init import intro_msg # test if stf_init was loaded try: import stf_init except ImportError: LOADED = " " except SyntaxError: LOADED = " Syntax error in custom initialization script stf_init.py" else: LOADED = " Successfully loaded custom initializaton script stf_init.py" class MyPanel(wx.Panel): """ The wxPython shell application """ def __init__(self, parent): # super makes the same as wx.Panel.__init__(self, parent, etc..) # but prepares for Python 3.0 among other things... super(MyPanel, self).__init__(parent, -1, \ style = wx.BORDER_NONE | wx.MAXIMIZE) # the Pycrust shell object self.pycrust = shell.Shell(self,-1, \ introText = intro_msg() + LOADED) # Workaround for http://trac.wxwidgets.org/ticket/15008 if "darwin" in sys.platform: self.pycrust.autoCallTip = False self.pycrust.push('from embedded_init import *', silent = True) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.pycrust, 1, wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 10) self.SetSizer(sizer) stimfit-0.16.7/src/stimfit/py/pystf.h0000775000175000017500000001126314750344764013207 #ifndef _PYSTF_H #define _PYSTF_H #undef _DEBUG #include #undef _DEBUG #include std::string get_versionstring( ); #ifdef WITH_PYTHON PyObject* get_trace(int trace=-1, int channel=-1); #endif bool new_window( double* invec, int size ); bool new_window_matrix( double* inarr, int traces, int size ); bool new_window_selected_this( ); bool new_window_selected_all( ); #ifdef WITH_PYTHON bool show_table( PyObject* dict, const char* caption = "Python table" ); bool show_table_dictlist( PyObject* dict, const char* caption = "Python table", bool reverse = true ); #endif int get_size_trace( int trace = -1, int channel = -1 ); int get_size_channel( int channel = -1 ); int get_size_recording( ); double get_sampling_interval( ); bool set_sampling_interval( double si ); const char* get_xunits( ); const char* get_yunits( int trace = -1, int channel = -1 ); bool set_xunits( const char* units ); bool set_yunits( const char* units, int trace = -1, int channel = -1 ); double get_maxdecay(); double get_maxrise(); const char* get_recording_time( ); const char* get_recording_date( ); std::string get_recording_comment( ); bool set_recording_comment( const char* comment ); bool set_recording_time( const char* time ); bool set_recording_date( const char* date ); bool select_trace( int trace = -1 ); void select_all( ); void unselect_all( ); #ifdef WITH_PYTHON PyObject* get_selected_indices( ); #endif bool set_trace( int trace ); int get_trace_index(); const char* get_trace_name( int trace = -1, int channel = -1 ); bool set_channel( int channel); int get_channel_index( bool active = true ); const char* get_channel_name( int index = -1 ); bool set_channel_name( const char* name, int index = -1 ); void align_selected( double (*alignment)( bool ), bool active = false ); bool subtract_base( ); int leastsq_param_size( int fselect ); #ifdef WITH_PYTHON PyObject* leastsq( int fselect, bool refresh = true ); PyObject* get_fit( int trace = -1, int channel = -1 ); #endif bool check_doc( bool show_dialog = true ); std::string get_filename( ); bool file_open( const char* filename ); bool file_save( const char* filename ); bool close_all( ); bool close_this( ); bool measure( ); double get_base( bool active = true ); double get_base_SD( ); double get_peak( ); double get_halfwidth (bool active = true); #ifdef WITH_PSLOPE double get_pslope(); #endif double get_threshold_time( bool is_time = false ); double get_threshold_value( ); double get_latency(); double get_risetime(); double peak_index( bool active = true ); double maxrise_index( bool active = true ); double maxdecay_index( ); double foot_index( bool active = true ); double rtlow_index( bool active = true ); double rthigh_index( bool active = true ); double t50left_index( bool active = true ); double t50right_index( bool active = true ); double get_risetime_factor(); bool set_risetime_factor(double factor); bool set_marker(double x, double y); bool erase_markers(); double get_fit_start( bool is_time = false ); bool set_fit_start( double pos, bool is_time = false ); double get_fit_end( bool is_time = false ); bool set_fit_end( double pos, bool is_time = false ); double get_peak_start( bool is_time = false ); bool set_peak_start( double pos, bool is_time = false ); double get_peak_end( bool is_time = false ); bool set_peak_end( double pos, bool is_time = false ); int get_peak_mean( ); bool set_peak_mean( int pts ); const char* get_peak_direction( ); bool set_peak_direction( const char* direction ); double get_base_start( bool is_time = false ); bool set_base_start( double pos, bool is_time = false ); double get_base_end( bool is_time = false ); bool set_base_end( double pos, bool is_time = false ); const char* get_baseline_method( ); bool set_baseline_method( const char* method); const char* get_latency_start_mode( ); bool set_latency_start_mode( const char* direction ); const char* get_latency_end_mode( ); bool set_latency_end_mode( const char* direction ); double get_latency_start( bool is_time = false ); bool set_latency_start( double pos, bool is_time = false ); double get_latency_end( bool is_time = false ); bool set_latency_end( double pos, bool is_time = false ); bool set_slope(double slope); double plot_xmin(); double plot_xmax(); double plot_ymin(); double plot_ymax(); double plot_y2min(); double plot_y2max(); void _gMatrix_resize( std::size_t channels, std::size_t sections ); void _gNames_resize( std::size_t channels ); void _gMatrix_at( double* invec, int size, int channel, int section ); void _gNames_at( const char* name, int channel ); bool _new_window_gMatrix( ); extern double _figsize[]; #ifdef WITH_PYTHON PyObject* mpl_panel(const std::vector& figsize = std::vector(_figsize, _figsize+2)); #endif #endif stimfit-0.16.7/src/stimfit/py/pystf.i0000775000175000017500000020346114752207205013201 #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic ignored "-Wwrite-strings" #endif %define DOCSTRING "The stf module allows to access a running stimfit application from the embedded python shell." %enddef %module(docstring=DOCSTRING) stf %{ #define SWIG_HAVE_SNPRINTF #define SWIG_FILE_WITH_INIT #include "pystf.h" %} %include "numpy.i" %include "std_string.i" %include "std_vector.i" namespace std { %template(vectord) vector; }; %init %{ import_array(); %} %define %apply_numpy_typemaps(TYPE) %apply (TYPE* IN_ARRAY1, int DIM1) {(TYPE* invec, int size)}; %apply (TYPE* IN_ARRAY2, int DIM1, int DIM2) {(TYPE* inarr, int traces, int size)}; %enddef /* %apply_numpy_typemaps() macro */ %apply_numpy_typemaps(double) //-------------------------------------------------------------------- %feature("autodoc", 0) get_versionstring; %feature("docstring", "Returns the current version of Stimfit.") get_versionstring; std::string get_versionstring( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_trace; %feature("kwargs") get_trace; %feature("docstring", """Returns a trace as a 1-dimensional NumPy array. Arguments: trace -- ZERO-BASED index of the trace within the channel. Note that this is one less than what is shown in the drop-down box. The default value of -1 returns the currently displayed trace. channel -- ZERO-BASED index of the channel. This is independent of whether a channel is active or not. The default value of -1 returns the currently active channel. Returns: The trace as a 1D NumPy array.""") get_trace; PyObject* get_trace(int trace=-1, int channel=-1); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) new_window; %feature("docstring", "Creates a new window showing a 1D NumPy array. Arguments: invec -- The NumPy array to be shown. Returns: True upon successful completion, false otherwise.") new_window; bool new_window( double* invec, int size ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) _new_window_gMatrix; %feature("docstring", "Creates a new window from the global matrix. Do not use directly.") _new_window_gMatrix; bool _new_window_gMatrix( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) new_window_matrix; %feature("docstring", "Creates a new window showing a 2D NumPy array. Arguments: inarr -- The NumPy array to be shown. First dimension are the traces, second dimension the sampling points within the traces. Returns: True upon successful completion, false otherwise.") new_window_matrix; bool new_window_matrix( double* inarr, int traces, int size ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) new_window_selected_this; %feature("docstring", "Creates a new window showing the selected traces of the current file. Returns: True if successful.") new_window_selected_this; bool new_window_selected_this( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) new_window_selected_all; %feature("docstring", "Creates a new window showing the selected traces of all open files. Returns: True if successful.") new_window_selected_all; bool new_window_selected_all( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) show_table; %feature("kwargs") show_table; %feature("docstring", "Shows a python dictionary in a results table. The dictionary has to have the form \"string\" : float Arguments: dict -- A dictionary with strings as key values and floating point numbers as values. caption -- An optional caption for the table. Returns: True if successful.") show_table; bool show_table( PyObject* dict, const char* caption = "Python table" ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) show_table_dictlist; %feature("kwargs") show_table_dictlist; %feature("docstring", "Shows a python dictionary in a results table. The dictionary has to have the form \"string\" : list. Arguments: dict -- A dictionary with strings as key values and lists of floating point numbers as values. caption -- An optional caption for the table. reverse -- If True, The table will be filled in column-major order, i.e. dictionary keys will become column titles. Setting it to False has not been implemented yet. Returns: True if successful.") show_table_dictlist; bool show_table_dictlist( PyObject* dict, const char* caption = "Python table", bool reverse = true ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_size_trace; %feature("kwargs") get_size_trace; %feature("docstring", "Retrieves the number of sample points of a trace. Arguments: trace -- ZERO-BASED index of the trace. Default value of -1 will use the currently displayed trace. Note that this is one less than what is displayed in the drop- down list. channel -- ZERO-BASED index of the channel. Default value of -1 will use the current channel. Returns: The number of sample points.") get_size_trace; int get_size_trace( int trace = -1, int channel = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_size_channel; %feature("kwargs") get_size_channel; %feature("docstring", "Retrieves the number of traces in a channel. Note that at present, stimfit only supports equal-sized channels, i.e. all channels within a file need to have the same number of traces. The channel argument is only for future extensions. Arguments: channel -- ZERO-BASED index of the channel. Default value of -1 will use the current channel. Returns: The number traces in a channel.") get_size_channel; int get_size_channel( int channel = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_maxdecay; %feature("docstring", "Retrieves the maximal slope of the decay between the peak cursors in the current trace. Uses the currently measured values, i.e. does not update measurements if the peak window cursors have changed. Returns: The maximal slope of the decay, -1.0 upon failure.") get_maxdecay; double get_maxdecay( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_maxrise; %feature("docstring", "Retrieves the maximal slope of the rise between the peak cursors in the current trace. Uses the currently measured values, i.e. does not update measurements if the peak window cursors have changed. Returns: The maximal slope of the rise, -1.0 upon failure.") get_maxrise; double get_maxrise( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_size_recording; %feature("docstring", "Retrieves the number of channels in a recording. Returns: The number of channels in a recording.") get_size_recording; int get_size_recording( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_sampling_interval; %feature("docstring", "Returns the sampling interval. Returns: The sampling interval.") get_sampling_interval; double get_sampling_interval( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_xunits; %feature("docstring", "Returns the x units of the specified section. X units are assumed to be the same for the entire file. Returns: The x units as a string.") get_xunits; const char* get_xunits( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_yunits; %feature("kwargs") get_yunits; %feature("docstring", "Returns the y units of the specified trace. Y units are not allowed to change between traces at present. Arguments: trace -- The zero-based index of the trace of interest. If < 0, the name of the active trace will be returned. channel -- The zero-based index of the channel of interest. If < 0, the active channel will be used. Returns: The x units as a string.") get_yunits; const char* get_yunits( int trace = -1, int channel = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_yunits; %feature("kwargs") set_yunits; %feature("docstring", "Sets the y unit string of the specified trace. Y units are not allowed to change between traces at present. Arguments: units -- The new y unit string. trace -- The zero-based index of the trace of interest. If < 0, the name of the active trace will be returned. channel -- The zero-based index of the channel of interest. If < 0, the active channel will be used. Returns: True if successful.") set_yunits; bool set_yunits( const char* units, int trace = -1, int channel = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_xunits; %feature("kwargs") set_xunits; %feature("docstring", "Sets the x unit string for the entire file. Arguments: units -- The new x unit string. Returns: True if successful.") set_xunits; bool set_xunits( const char* units ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_sampling_interval; %feature("docstring", "Sets a new sampling interval. Argument: si -- The new sampling interval. Returns: False upon failure.") set_sampling_interval; bool set_sampling_interval( double si ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) select_trace; %feature("kwargs") select_trace; %feature("docstring", "Selects a trace. Checks for out-of-range indices and stores the baseline along with the trace index. Arguments: trace -- ZERO-BASED index of the trace. Default value of -1 will select the currently displayed trace. Note that this is one less than what is displayed in the drop- down list. Returns: True if the trace could be selected, False otherwise.") select_trace; bool select_trace( int trace = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) select_all; %feature("docstring", "Selects all traces in the current file. Stores the baseline along with the trace index.") select_all; void select_all( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) unselect_all; %feature("docstring", "Unselects all previously selected traces in the current file.") unselect_all; void unselect_all( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) subtract_base; %feature("docstring", "Subtracts the baseline from the selected traces of the current file, then displays the subtracted traces in a new window. Returns: True if the subtraction was successful, False otherwise.") subtract_base; bool subtract_base( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) subtract_base; %feature("docstring", "Subtracts the baseline from the selected traces of the current file, then displays the subtracted traces in a new window. Returns: True if the subtraction was successful, False otherwise.") subtract_base; bool subtract_base( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) leastsq; %feature("kwargs") leastsq; %feature("docstring", "Fits a function to the data between the current fit cursors. Arguments: fselect -- Zero-based index of the function as it appears in the fit selection dialog. refresh -- To avoid flicker during batch analysis, this may be set to False so that the fitted function will not immediately be drawn. Returns: A dictionary with the best-fit parameters and the least-squared error, or a null pointer upon failure.") leastsq; PyObject* leastsq( int fselect, bool refresh = true ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_fit; %feature("kwargs") get_fit; %feature("docstring", "Get the waveform resulted from the fitting, if available. Arguments: trace -- The zero-based index of the trace of interest. If < 0, the name of the active trace will be returned. channel -- The zero-based index of the channel of interest. If < 0, the active channel will be used. Returns: A 2D Numpy array with the x-values of the fit in the first dimension, and the y-values in the second dimension. None if no fit is available.") get_fit; PyObject* get_fit( int trace = -1, int channel = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) leastsq_param_size; %feature("docstring", "Retrieves the number of parameters for a function. Arguments: fselect -- Zero-based index of the function as it appears in the fit selection dialog. Returns: The number of parameters for the function with index fselect, or a negative value upon failure.") leastsq_param_size; int leastsq_param_size( int fselect ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) check_doc; %feature("docstring", "Checks whether a file is open. Arguments: show_dialog -- True if an error dialog should be shown if no file is open. Returns: True if a file is open, False otherwise.") check_doc; bool check_doc( bool show_dialog=true ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_filename; %feature("docstring", "Returns the name of the current file.") get_filename; std::string get_filename( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) _gMatrix_resize; %feature("docstring", "Resizes the global matrix. Do not use directly. Arguments: channels -- New number of channels of the global matrix. sections -- New number of sections of the global matrix. ") _gMatrix_resize; void _gMatrix_resize( std::size_t channels, std::size_t sections ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) _gMatrix_at; %feature("docstring", "Sets the valarray at the specified position of the global matrix. Do not use directly. Arguments: invec -- The NumPy array to be used. channel -- The channel index within the global matrix. section -- The seciton index within the global matrix. ") _gMatrix_at; void _gMatrix_at( double* invec, int size, int channel, int section ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) _gNames_resize; %feature("docstring", "Resizes the global names. Do not use directly. Arguments: channels -- New number of channels of the global names. ") _gNames_resize; void _gNames_resize( std::size_t channels ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) _gNames_at; %feature("docstring", "Sets the channel name of the specifies channel. Do not use directly. Arguments: name -- The new channel name channel -- The channel index within the global names. ") _gNames_at; void _gNames_at( const char* name, int channel ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) file_open; %feature("docstring", "Opens a file. Arguments: filename -- The file to be opened. On Windows, use double back- slashes (\"\\\\\\\\\") between directories to avoid con- version to special characters such as \"\\\\t\" or \"\\\\n\". Example usage in Windows: file_open(\"C:\\\\\\data\\\\\\datafile.dat\") Example usage in Linux: file_open(\"/home/cs/data/datafile.dat\") This is surprisingly slow when called from python. Haven't figured out the reason yet. Returns: True if the file could be opened, False otherwise.") file_open; bool file_open( const char* filename ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) file_save; %feature("docstring", "Saves a file. Arguments: filename -- The file to be saved. On Windows, use double back- slashes (\"\\\\\\\\\") between directories to avoid con- version to special characters such as \"\\\\t\" or \"\\\\n\". Example usage in Windows: file_save(\"C:\\\\\\data\\\\\\datafile.dat\") Example usage in Linux: file_save(\"/home/cs/data/datafile.dat\") This is surprisingly slow when called from python. Haven't figured out the reason yet. Returns: True if the file could be saved, False otherwise.") file_save; bool file_save( const char* filename ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_recording_time; %feature("docstring", "Returns the time at which the recording was started as a string.") get_recording_time; const char* get_recording_time( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_recording_date; %feature("docstring", "Returns the date at which the recording was started as a string.") get_recording_date; const char* get_recording_date( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_recording_comment; %feature("docstring", "Returns a comment about the recording. ") get_recording_comment; std::string get_recording_comment( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_recording_date; %feature("docstring", "Sets a date about the recording. Argument: date -- A date string. Returns: True upon successful completion.") set_recording_date; bool set_recording_date( const char* date ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_recording_time; %feature("docstring", "Sets a time about the recording. Argument: time -- A time string. Returns: True upon successful completion.") set_recording_time; bool set_recording_time( const char* time ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_recording_comment; %feature("docstring", "Sets a comment about the recording. Argument: comment -- A comment string. Returns: True upon successful completion.") set_recording_comment; bool set_recording_comment( const char* comment ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_recording_comment; %feature("docstring", "Sets a comment about the recording. Argument: comment -- A comment string. Returns: True upon successful completion.") set_recording_comment; bool set_recording_comment( const char* comment ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) close_all; %feature("docstring", "Closes all open files. Returns: True if all files could be closed.") close_all; bool close_all( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) close_this; %feature("docstring", "Closes the currently active file. Returns: True if the file could be closed.") close_this; bool close_this( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_base; %feature("kwargs") get_base; %feature("docstring", "Returns the current baseline value. Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Arguments: active -- If True, returns the baseline in the active channel. If False returns the baseline within the reference channel. Returns: The current baseline.") get_base; double get_base( bool active = true); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_peak; %feature("docstring", "Returns the current peak value, measured from zero (!). Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Returns: The current peak value, measured from zero (again: !).") get_peak; double get_peak( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- #ifdef WITH_PSLOPE %feature("autodoc", 0) get_pslope; %feature("docstring", "Returns the slope, measured from slope cursor values defined in the cursors settings menu(!). This option is only available under GNU/Linux. Returns: The current slope value.") get_pslope; double get_pslope( ); #endif //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) peak_index; %feature("kwargs") peak_index; %feature("docstring", "Returns the zero-based index of the current peak position in the specified channel. Uses the currently measured values, i.e. does not update measurements if the peak window cursors have changed. Arguments: active -- If True, returns the current peak index of the active channel. Otherwise, returns the current peak index of the reference channel. Returns: The zero-based index in units of sampling points. May be interpolated if more than one point is used for the peak calculation. Returns a negative value upon failure.") peak_index; %callback("%s_cb"); double peak_index( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) maxrise_index; %feature("kwargs") maxrise_index; %feature("docstring", "Returns the zero-based index of the maximal slope of rise in the specified channel. Uses the currently measured values, i.e. does not update measurements if the peak window cursors have changed. Arguments: active -- If True, returns the current index of the maximal slope of rise within the active channel. Otherwise, returns the current index of the maximal slope of rise within the reference channel. Returns: The zero-based index of the maximal slope of rise in units of sampling points interpolated between adjacent sampling points. Returns a negative value upon failure.") maxrise_index; %callback("%s_cb"); double maxrise_index( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) maxdecay_index; %feature("docstring", "Returns the zero-based index of the maximal slope of decay in the current channel. Uses the currently measured values, i.e. does not update measurements if the peak window cursors have changed. Note that in contrast to maxrise_index, this function only works on the active channel. Returns: The zero-based index of the maximal slope of decay in units of sampling points interpolated between adjacent sampling points. Returns a negative value upon failure.") maxdecay_index; double maxdecay_index( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) foot_index; %feature("kwargs") foot_index; %feature("docstring", "Returns the zero-based index of the foot of an event in the active channel. The foot is the intersection of an interpolated line through the points of 20 and 80% rise with the baseline. Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Arguments: active -- If True, returns the current index of the foot within the active channel. Only implemented for the active channel at this time. Will return a negative value and show an error message if active == False. Returns: The zero-based index of the foot of an event in units of sampling points. Interpolates between sampling points. Returns a negative value upon failure.") foot_index; %callback("%s_cb"); double foot_index( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) t50left_index; %feature("kwargs") t50left_index; %feature("docstring", "Returns the zero-based index of the left half- maximal amplitude of an event in the specified channel. Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Arguments: active -- If True, returns the current index of the left half- maximal amplitude within the active channel. If False, returns the current index of the left half-maximal amplitude within the reference channel. Returns: The zero-based index of the left half-maximal amplitude in units of sampling points. Interpolates between sampling points. Returns a negative value upon failure.") t50left_index; %callback("%s_cb"); double t50left_index( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) t50right_index; %feature("kwargs") t50right_index; %feature("docstring", "Returns the zero-based index of the right half- maximal amplitude of an event in the active channel. Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Arguments: active -- If True, returns the current index of the right half- maximal amplitude within the active channel. Only implemented for the active channel at this time. Will return a negative value and show an error message if active == False. Returns: The zero-based index of the right half-maximal amplitude in units of sampling points. Interpolates between sampling points. Returns a negative value upon failure.") t50right_index; %callback("%s_cb"); double t50right_index( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_halfwidth; %feature("kwargs") get_halfwidth; %feature("docstring", "Returns the half-maximal amplitude of an event in the specified channel. Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Only implemented for the active channel. Arguments: active -- If True, returns the current half-maximal amplitude within the active channel. Returns: The half-maximal amplitude in units of x-units. Returns a negative value upon failure.") get_halfwidth; %callback("%s_cb"); double get_halfwidth( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) rtlow_index; %feature("kwargs") rtlow_index; %feature("docstring", "Returns the zero-based index of the lower rise- time of an event in the specified channel. Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Arguments: active -- If True, returns the current index within the active channel. If False, returns the current index within the reference channel. Returns: The zero-based index of the lower rise time in units of sampling points. Interpolates between sampling points. Returns a negative value upon failure.") rtlow_index; %callback("%s_cb"); double rtlow_index( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) rthigh_index; %feature("kwargs") rthigh_index; %feature("docstring", "Returns the zero-based index of the higher rise time of an event in the specified channel. Uses the currently measured values, i.e. does not update measurements if the peak or base window cursors have changed. Arguments: active -- If True, returns the current index within the active channel. If False, returns the current index within the reference channel. Returns: The zero-based index of the higher rise time in units of sampling points. Interpolates between sampling points. Returns a negative value upon failure.") rthigh_index; %callback("%s_cb"); double rthigh_index( bool active = true ); %nocallback; //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_threshold_time; %feature("kwargs") get_threshold_time; %feature("docstring", "Returns the crossing value of the threshold slope. Note that this value is not updated after changing the AP threshold. Call measure() or hit enter to update the cursors. Arguments: is_time -- If False (default), returns the zero-based index at which the threshold slope is crossed (e.g in mV). If True, returns the time point at which the threshold slope is crossed. A negative number is returned upon failure. ") get_threshold_time; double get_threshold_time( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_latency; %feature("docstring", "Returns the latency value (in x-units) determined by the latency cursors set in the cursors settings menu. Call measure() or hit enter to update the cursors. ") get_latency; double get_latency( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_risetime; %feature("docstring", "Returns the rise time (in x-units) determined by the linear interpolation between sampling points (e.g at 20% and 80% of the peak amplitude. ) Call measure() or hit enter to update the cursors. ") get_risetime; double get_risetime( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_risetime_factor; %feature("docstring", "Returns the lower proportion factor used to calculate the rise time (e.g 0.2 if we calculate the 20--80% rise time. ) ") get_risetime_factor; double get_risetime_factor( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_risetime_factor; %feature("kwargs") set_risetime_factor; %feature("docstring", "Sets the lower proportion factor to calculate the rise time (e.g 0.2 if we want to calculate the 20--80% rise time. ) It will update the rise time measurement. Arguments: factor -- the low proportion factor to calculate rise time Returns: False upon failure (such as factor lower than 0.05 or larger than 0.5) ") set_risetime_factor; bool set_risetime_factor(double factor); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_threshold_value; %feature("docstring", "Returns the value found at the threshold slope. Note that this value is not updated after changing the AP threshold. Call measure or hit enter to update the threshold. ") get_threshold_value; double get_threshold_value( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_fit_start; %feature("kwargs") get_fit_start; %feature("docstring", "Returns the zero-based index or the time point of the fit start cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position. ") get_fit_start; double get_fit_start( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_fit_end; %feature("kwargs") get_fit_end; %feature("docstring", "Returns the zero-based index or the time point of the fit end cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position. ") get_fit_end; double get_fit_end( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_fit_start; %feature("kwargs") set_fit_start; %feature("docstring", "Sets the fit start cursor to a new position. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_fit_start; bool set_fit_start( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_fit_end; %feature("kwargs") set_fit_end; %feature("docstring", "Sets the fit end cursor to a new position. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_fit_end; bool set_fit_end( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_peak_start; %feature("kwargs") get_peak_start; %feature("docstring", "Returns the zero-based index or the time point of the peak start cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position. ") get_peak_start; double get_peak_start( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_peak_end; %feature("kwargs") get_peak_end; %feature("docstring", "Returns the zero-based index or the time point of the peak end cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position. ") get_peak_end; double get_peak_end( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_peak_start; %feature("kwargs") set_peak_start; %feature("docstring", "Sets the peak start cursor to a new position. This will NOT update the peak calculation. You have to either call measure() or hit enter in the main window to achieve that. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_peak_start; bool set_peak_start( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_peak_end; %feature("kwargs") set_peak_end; %feature("docstring", "Sets the peak end cursor to a new position. This will NOT update the peak calculation. You have to either call measure() or hit enter in the main window to achieve that. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_peak_end; bool set_peak_end( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_peak_mean; %feature("docstring", "Sets the number of points used for the peak calculation. Arguments: pts -- A moving average (aka sliding, boxcar or running average) is used to determine the peak value. Pts specifies the number of sampling points used for the moving window. Passing a value of -1 will calculate the average of all sampling points within the peak window. Returns: False upon failure (such as out-of-range).") set_peak_mean; bool set_peak_mean( int pts ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_peak_mean; %feature("docstring", "Returns the number of sampling points used for the peak calculation. Returns: 0 upon failure (i.e no file opened). -1 means average of all sampling points within the peak window.") get_peak_mean; int get_peak_mean( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_peak_direction; %feature("docstring", "Sets the direction of the peak detection. Arguments: direction -- A string specifying the peak direction. Can be one of: \"up\", \"down\" or \"both\" Returns: False upon failure.") set_peak_direction; bool set_peak_direction( const char* direction ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_peak_direction; %feature("docstring", "Gets the current direction of the detection for the peak cursors. Returns: A string specifying the peak direction. Can be one of: \"up\", \"down\" or \"both\"") get_peak_direction; const char* get_peak_direction( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_latency_start; %feature("kwargs") set_latency_start; %feature("docstring", "Sets the first latency cursor to a new position. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_latency_start; bool set_latency_start( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_latency_start_mode; %feature("docstring", "Sets the mode of the latency start cursor. Arguments: direction -- A string specifying the mode for the latency start cursor. Can be one of \"manual\", \"peak\", \"rise\" or \"half\" Returns: False upon failure.") set_latency_start_mode; bool set_latency_start_mode( const char* mode ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_baseline_method; %feature("docstring", "Gets the method used to compute the baseline Returns: A string specifying the method to compute the baseline. Can be one of \"mean\" or \"median\"") get_baseline_method; const char* get_baseline_method( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_baseline_method; %feature("docstring", "Sets the method to compute the baseline. Arguments: method -- A string specifying the method to calculate the baseline. Can be one of \"mean\" or \"median\" Returns: False upon failure.") set_baseline_method; bool set_baseline_method( const char* method ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_latency_start_mode; %feature("docstring", "Gets the latency start mode Returns: A string specifying the latency start mode. Can be one of \"manual\", \"peak\", \"rise\" or \"half\"") get_latency_start_mode; const char* get_latency_start_mode( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_latency_end; %feature("kwargs") set_latency_end; %feature("docstring", "Sets the second latency cursor to a new position. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_latency_end; bool set_latency_end( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_latency_end_mode; %feature("docstring", "Sets the mode of the latency end cursor. Arguments: direction -- A string specifying the mode for the latency end cursor. Can be one of \"manual\", \"peak\", \"rise\", \"foot\" or \"half\" Returns: False upon failure.") set_latency_end_mode; bool set_latency_end_mode( const char* mode ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_latency_end_mode; %feature("docstring", "Gets the latency end mode Returns: A string specifying the latency end mode. Can be one of \"manual\", \"peak\", \"rise\", \"foot\" or \"half\"") get_latency_end_mode; const char* get_latency_end_mode( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_latency_start; %feature("kwargs") get_latency_start; %feature("docstring", "Returns the zero-based index or the time point of the latency start cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position.") get_latency_start; double get_latency_start( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_latency_end; %feature("kwargs") get_latency_end; %feature("docstring", "Returns the zero-based index or the time point of the latency end cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position.") get_latency_end; double get_latency_end( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_base_SD; %feature("docstring", "Returns the standard deviation of the baseline in the current (active) channel. Uses the currently measured values, i.e. does not update measurements if the baseline cursors have changed. Returns: 0.0 upon failure (i.e no file opened), otherwise, the standard deviation of the baseline.") get_base_SD; double get_base_SD( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_base_start; %feature("kwargs") get_base_start; %feature("docstring", "Returns the zero-based index or the time point of the base start cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position.") get_base_start; double get_base_start( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_base_end; %feature("kwargs") get_base_end; %feature("docstring", "Returns the zero-based index or the time point of the base end cursor. Arguments: is_time -- If False (default), returns the zero-based index. If True, returns the time from the beginning of the trace to the cursor position.") get_base_end; double get_base_end( bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_base_start; %feature("kwargs") set_base_start; %feature("docstring", "Sets the base start cursor to a new position. This will NOT update the baseline calculation. You have to either call measure() or hit enter in the main window to achieve that. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_base_start; bool set_base_start( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_base_end; %feature("kwargs") set_base_end; %feature("docstring", "Sets the base end cursor to a new position. This will NOT update the baseline calculation. You have to either call measure() or hit enter in the main window to achieve that. Arguments: pos -- The new cursor position, either in units of sampling points if is_time == False (default) or in units of time if is_time == True. is_time -- see above. Returns: False upon failure (such as out-of-range).") set_base_end; bool set_base_end( double pos, bool is_time = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_slope; %feature("docstring", "Sets the AP threshold to the value given by the slope and takes it as reference for AP kinetic measurements. Note that you have to either call measure() or hit enter to update calculations. Arguments: slope -- slope value in mV/ms Returns: False upon failure (such as out-of-range).") set_slope; bool set_slope( double slope); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) measure; %feature("docstring", "Updates all measurements (e.g. peak, baseline, latency) according to the current cursor settings. As if you had pressed \"Enter\" in the main window. Returns: False upon failure, True otherwise.") measure; bool measure( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_selected_indices; %feature("docstring", "Returns a tuple with the indices (ZERO-BASED) of the selected traces.") get_selected_indices; PyObject* get_selected_indices( ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_trace; %feature("docstring", "Sets the currently displayed trace to a new index. Subsequently updates all measurements (e.g. peak, base, latency, i.e. you don't need to call measure() yourself.) Arguments: trace -- The zero-based index of the new trace to be displayed. Returns: True upon success, false otherwise (such as out-of-range).") set_trace; bool set_trace( int trace ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_trace_index; %feature("docstring", "Returns the ZERO-BASED index of the currently displayed trace (this is one less than what is shown in the combo box). ") get_trace_index; int get_trace_index(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_channel_index; %feature("kwargs") get_channel_index; %feature("docstring", "Returns the ZERO-BASED index of the specified channel. Arguments: active -- If True, returns the index of the active (black) channel. If False, returns the index of the reference (red) channel. ") get_channel_index; int get_channel_index( bool active = true ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_channel_name; %feature("kwargs") get_channel_name; %feature("docstring", "Returns the name of the channel with the specified index. Arguments: index -- The zero-based index of the channel of interest. If < 0, the name of the active channel will be returned. Returns: the name of the channel with the specified index.") get_channel_name; const char* get_channel_name( int index = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_channel; %feature("docstring", "Sets the currently displayed channel to a new index. Subsequently updates all measurements (e.g. peak, base, latency, i.e. you don't need to call measure() yourself.) Arguments: channel -- The zero-based index of the new trace to be displayed. Returns: True upon success, false otherwise (such as out-of-range).") set_channel; bool set_channel( int channel); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_channel_name; %feature("kwargs") set_channel_name; %feature("docstring", "Sets the name of the channel with the specified index. Arguments: name -- The new name of the channel. index -- The zero-based index of the channel of interest. If < 0, the active channel will be used. Returns: True upon success.") set_channel_name; bool set_channel_name( const char* name, int index = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) get_trace_name; %feature("kwargs") get_trace_name; %feature("docstring", "Returns the name of the trace with the specified index. Arguments: trace -- The zero-based index of the trace of interest. If < 0, the name of the active trace will be returned. channel -- The zero-based index of the channel of interest. If < 0, the active channel will be used. Returns: the name of the trace with the specified index.") get_trace_name; const char* get_trace_name( int trace = -1, int channel = -1 ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) align_selected; %feature("kwargs") align_selected; %feature("docstring", "Aligns the selected traces to the index that is returned by the alignment function, and then creates a new window showing the aligned traces. This function requires to select the traces of interest and the presence of a second (i.e reference) channel. Arguments: alignment -- The alignment function to be used. Accepts any function returning a valid index within a trace. These are some predefined possibilities: maxrise_index (default; maximal slope during rising phase) peak_index (Peak of an event) foot_index (Beginning of an event) t50left_index t50right_index (Left/right half-maximal amplitude) active -- If True, the alignment function will be applied to the active channel. If False (default), it will be applied to the reference channel. zeropad -- Not yet implemented: If True, missing parts at the beginning or end of a trace will be padded with zeros after the alignment. If False (default), traces will be cropped so that all traces have equal sizes. ") align_selected; void align_selected( double (*alignment)( bool ), bool active = false ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) set_marker; %feature("docstring", "Sets a marker to the specified position in the current trace. Arguments: x -- The horizontal marker position in units of sampling points. y -- The vertical marker position in measurement units (e.g. mV). Returns: False upon failure (such as out-of-range).") set_marker; bool set_marker( double x, double y ); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) erase_markers; %feature("docstring", "Erases all markers in the current trace. Returns: False upon failure.") erase_marker; bool erase_markers(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) plot_xmin; %feature("docstring", "Returns x value of the left screen border") plot_xmin; double plot_xmin(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) plot_xmax; %feature("docstring", "Returns x value of the right screen border") plot_xmax; double plot_xmax(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) plot_ymin; %feature("docstring", "Returns y value of the bottom screen border") plot_ymin; double plot_ymin(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) plot_ymax; %feature("docstring", "Returns y value of the top screen border") plot_ymax; double plot_ymax(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) plot_y2min; %feature("docstring", "Returns y value of the bottom screen border for the reference channel") plot_y2min; double plot_y2min(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) plot_y2max; %feature("docstring", "Returns y value of the top screen border for the reference channel") plot_y2max; double plot_y2max(); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %feature("autodoc", 0) mpl_panel; %feature("kwargs") mpl_panel; %feature("docstring", "Returns a pointer to the parent window") mpl_panel; PyObject* mpl_panel(const std::vector& figsize = std::vector(_figsize, _figsize+2)); //-------------------------------------------------------------------- //-------------------------------------------------------------------- %pythoncode { class StfException(Exception): """ raises Exceptions for the Stfio module """ def __init__(self, error_msg): self.msg = error_msg def __str__(self): return repr(self.msg) def new_window_list( array_list ): """Creates a new window showing a sequence of 1D NumPy arrays, or a sequence of a sequence of 1D NumPy arrays. As opposed to new_window_matrix(), this has the advantage that the arrays need not have equal sizes. Arguments: array_list -- A sequence (e.g. list or tuple) of numpy arrays, or a sequence of a sequence of numpy arrays. Returns: True upon successful completion, false otherwise. """ try: it = iter(array_list) except TypeError: print( "Argument is not a sequence" ) return False try: it = iter(array_list[0]) except TypeError: print( "Argument is not a sequence of sequences." ) print( "You can either pass a sequence of 1D NumPy arrays," ) print( "Or a sequence of sequences of 1D NumPy arrays." ) return False is_3d = True try: it = iter(array_list[0][0]) except TypeError: is_3d = False n_channels = 1 if is_3d: n_channels = len(array_list) _gMatrix_resize( n_channels, len(array_list[0]) ) for (n_c, c) in enumerate(array_list): for (n_s, s) in enumerate(c): _gMatrix_at( s, n_c, n_s ) else: _gMatrix_resize( n_channels, len(array_list) ) for (n, a) in enumerate(array_list): _gMatrix_at( a, 0, n ) return _new_window_gMatrix( ) def stfio_open(stfio_rec): """Open an stfio recording object with Stimfit Arguments: stfio_rec -- An stfio recording object, e.g. opened with stfio.read("filename") Returns: True upon successful completion, false otherwise. """ n_channels = len(stfio_rec) _gMatrix_resize( n_channels, len(stfio_rec[0]) ) for n_c, c in enumerate(stfio_rec): for n_s, s in enumerate(c): _gMatrix_at( c[n_s].asarray(), n_c, n_s ) succ = _new_window_gMatrix( ) if not succ: return False for n_c, c in enumerate(stfio_rec): set_channel_name(c.name, n_c) set_yunits(c.yunits, n_c) set_recording_date(stfio_rec.date) set_recording_time(stfio_rec.time) set_recording_comment(stfio_rec.comment) set_xunits(stfio_rec.xunits) set_sampling_interval(stfio_rec.dt) measure() return True def cut_traces( pt ): """Cuts the selected traces at the sampling point pt, and shows the cut traces in a new window. Returns True upon success, False upon failure.""" if not get_selected_indices(): print( "Trace is not selected!" ) return False new_list = list() for n in get_selected_indices(): if not set_trace(n): return False if pt < get_size_trace(): new_list.append( get_trace()[:pt] ) new_list.append( get_trace()[pt:] ) else: print( "Cutting point %d is out of range" %pt ) if len(new_list) > 0: new_window_list( new_list ) return True def cut_traces_multi( pt_list ): """Cuts the selected traces at the sampling points in pt_list and shows the cut traces in a new window. Returns True upon success, False upon failure.""" if not get_selected_indices(): print( "Trace is not selected!" ) return False new_list = list() for n in get_selected_indices(): if not set_trace(n): return False old_pt = 0 for pt in pt_list: if pt < get_size_trace(): new_list.append( get_trace()[old_pt:pt] ) old_pt = pt else: print( "Cutting point %d is out of range" %pt ) if len(new_list) > 0: new_list.append( get_trace()[old_pt:] ) new_window_list( new_list ) return True def template_matching(template, mode="criterion", norm=True, lowpass=0.5, highpass=0.0001): import sys sys.stderr.write("template_matching is deprecated. Use detect_events instead.\n") return detect_events(template, mode, norm, lowpass, highpass) def detect_events(template, mode="criterion", norm=True, lowpass=0.5, highpass=0.0001): if not check_doc(): return None import stfio return stfio.detect_events(get_trace(), template, get_sampling_interval(), mode, norm, lowpass, highpass) def peak_detection(data, threshold, min_distance): import stfio return stfio.peak_detection(data, threshold, min_distance) class _cursor_pair(object): def __init__(self, get_start, set_start, get_end, set_end, get_value=None, index=None): self._get_start = get_start self._set_start = set_start self._get_end = get_end self._set_end = set_end self._get_value = get_value self._index = index def _get_cursors(self, is_time): if not check_doc(show_dialog=False): raise StfException("Couldn't find open file") return (self._get_start(is_time=is_time), self._get_end(is_time=is_time)) def _set_cursors(self, cursors, is_time): if not check_doc(show_dialog=False): raise StfException("Couldn't find open file") try: if len(cursors) != 2: raise ValueError("cursors has to have length 2 when setting the time value") except TypeError: raise TypeError("cursors has to be a tuple or list of length 2") if cursors[0] is not None: self._set_start(cursors[0], is_time=is_time) if cursors[1] is not None: self._set_end(cursors[1], is_time=is_time) @property def cursor_time(self): return self._get_cursors(True) @cursor_time.setter def cursor_time(self, cursors): self._set_cursors(cursors, True) @property def cursor_index(self): return self._get_cursors(False) @cursor_index.setter def cursor_index(self, cursors): self._set_cursors(cursors, False) @property def value(self): if self._get_value is None: raise AttributeError("Missing _get_value function") return self._get_value() @property def index(self): if self._index is None: raise AttributeError("Missing _index function") return self._index() base = _cursor_pair(get_base_start, set_base_start, get_base_end, set_base_end, get_base) peak = _cursor_pair(get_peak_start, set_peak_start, get_peak_end, set_peak_end, get_peak, peak_index) fit = _cursor_pair(get_fit_start, set_fit_start, get_fit_end, set_fit_end) latency = _cursor_pair( get_latency_start, set_latency_start, get_latency_end, set_latency_end, get_latency) } //-------------------------------------------------------------------- stimfit-0.16.7/src/stimfit/py/embedded_ipython.py0000664000175000017500000000364114750344764015544 #=========================================================================== # embedded_ipython.py # 2009.09.14 # Don't modify this file unless you know what you are doing!!! #=========================================================================== """ embedded_ipython.py starting code to embed wxPython into the stf application. """ import wx from IPython.frontend.wx.wx_frontend import WxController # from IPython.gui.wx.ipython_view import IPShellWidget import IPython.ipapi # test if stf_init was loaded try: import stf_init except ImportError: LOADED = " " except SyntaxError: LOADED = " Syntax error in custom initialization script stf_init.py" else: LOADED = " Successfully loaded custom initializaton script stf_init.py" class MyPanel(wx.Panel): """ The wxPython shell application """ def __init__(self, parent): # super makes the same as wx.Panel.__init__(self, parent, etc..) # but prepares for Python 3.0 among other things... super(MyPanel, self).__init__(parent, -1, \ style = wx.BORDER_NONE | wx.MAXIMIZE) # ipython_shell is the shell object # WxController provides a Wx frontend for the IPython interpreter # see in /usr/lib/pymodules/python2.5/IPython/frontend/wx # see an example in /usr/lib/modules/python2.5/IPython/gui/wx ipython_shell = WxController(self) # ipython_shell = IPShellWidget(self,background_color = "BLACK") # ipython_shell = IPShellWidget(self) ipython_shell.clear_screen() # the ip object will access the IPython functionality ip = IPython.ipapi.get() # Stimfit and NumPy are visible to the interactive sesion. # see embedded_init for details ip.ex('from embedded_init import *') sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(ipython_shell, 1, wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 10) self.SetSizer(sizer) stimfit-0.16.7/src/stimfit/py/heka.py0000664000175000017500000000530214750344764013145 import sys import numpy as np def read_heka(filename): ascfile = open(filename) nchannels = 0 nsweeps = 0 newsweep = True header = True channels = [] channelnames = [] channelunits = [] channeldt = [] istext=False sys.stdout.write("Reading") sys.stdout.flush() for line in ascfile: words = line.replace('\r','').replace('\n','').split(",") try: np = int(words[0]) istext=False except: istext = True if not header: newsweep=True else: prevline = words if not istext: if header: nchannels = (len(words)-1)/2 channels = [list() for i in range(nchannels)] for nc in range(nchannels): channelnames.append( prevline[nc*2+2].replace("\"",'').strip()[:-3]) channelunits.append( prevline[nc*2+2][prevline[nc*2+2].find('[')+1: \ prevline[nc*2+2].find(']')]) header=False if newsweep: for channel in channels: channel.append(list()) nsweeps += 1 sys.stdout.write(".") sys.stdout.flush() newsweep=False if len(channels[-1][-1])==0: dt0 = float(words[1]) if len(channels[-1][-1])==1: dt1 = float(words[1]) channeldt.append(dt1-dt0) for nc, channel in enumerate(channels): channel[-1].append(float(words[nc*2+2])) return channels, channelnames, channelunits, channeldt def read_heka_stf(filename): channels, channelnames, channelunits, channeldt = read_heka(filename) for nc, channel in enumerate(channels): if channelunits[nc]=="V": for ns, sweep in enumerate(channel): channels[nc][ns] = np.array(channels[nc][ns]) channels[nc][ns] *= 1.0e3 channelunits[nc]="mV" if channelunits[nc]=="A": for ns, sweep in enumerate(channel): channels[nc][ns] = np.array(channels[nc][ns]) channels[nc][ns] *= 1.0e12 channelunits[nc]="pA" import stf stf.new_window_list(channels) for nc, name in enumerate(channelnames): stf.set_channel_name(name, nc) for nc, units in enumerate(channelunits): for ns in range(stf.get_size_channel()): stf.set_yunits(units, ns, nc) stf.set_sampling_interval(channeldt[0]*1e3) if __name__=="__main__": read_heka("JK100205aa.asc") stimfit-0.16.7/src/stimfit/py/minidemo.py0000775000175000017500000000322414750344764014042 """ minidemo.py This script sets base, peak and fit cursors to perform events detection as decribed in the Stimfit manual [1] It creates a preliminary and final templates from a file 'minis.dat'. You can download the file here: http://stimfit.org/tutorial/minis.dat last revision: Wed Sep 5 09:38:41 CEST 2018 C. Schmidt-Hieber [1] https://neurodroid.github.io/stimfit/manual/event_extraction.html """ import stf from wx import MessageBox if stf.get_filename()[-9:] != 'minis.dat': MessageBox('Use minis.dat for this demo.', 'Warning') def preliminary(): """ Sets peak, base and fit cursors around a synaptic event and performs a biexponential fit to create the preliminary template for event detection. """ stf.base.cursor_index = (209600, 209900) stf.peak.cursor_index = (209900, 210500) stf.fit.cursor_index = (209900, 210400) stf.set_peak_mean(3) stf.measure() # update cursors return stf.leastsq(5) def final(): """ Sets peak, base and fit cursors around a synaptic event and performs a biexponetial fit to create the final template for event detection. """ stf.base.cursor_index = (000, 100) stf.peak.cursor_index = (100, 599) stf.fit.cursor_index = (100, 599) stf.set_peak_mean(3) stf.measure() # update cursors return stf.leastsq(5) def batch_cursors(): """ Sets peak, base and fit cursors around a synaptic event for the batch analysis of the extracted events. """ stf.base.cursor_index = (000, 100) stf.peak.cursor_index = (100, 598) stf.fit.cursor_index = (120, 598) stf.set_peak_mean(3) stf.measure() # update cursors stimfit-0.16.7/src/stimfit/py/hdf5tools.py0000775000175000017500000002172114750344764014152 import sys sys.argv = "" import tables import numpy as np class Recording(): def __init__(self, channels, comment, date, time): self.channels = channels self.comment = comment self.date = date self.time = time def __getitem__( self, i ): return self.channels[i] def get_list( self ): return [ [ s.data for s in c.sections ] for c in self.channels ] def __len__( self ): return len( self.channels ) class Channel(): def __init__(self, sections, name): self.sections = sections self.name = name def __len__( self ): return len( self.sections ) def __getitem__( self, i ): return self.sections[i] class Section(): def __init__(self, data, dt, xunits, yunits): self.data = data self.dt = dt self.xunits = xunits self.yunits = yunits def __len__( self ): return len( self.data ) def __getitem__( self, i ): return self.data[i] class RecordingDescription(tables.IsDescription): channels = tables.Int32Col() date = tables.StringCol(128) time = tables.StringCol(128) class ChannelDescription(tables.IsDescription): n_sections = tables.Int32Col() class SectionDescription(tables.IsDescription): dt = tables.Float64Col() xunits = tables.StringCol(16) yunits = tables.StringCol(16) def save_hdf5( rec, filename ): with tables.open_file(filename, mode = "w", title = "%s, converted to hdf5" % filename) as h5file: # write global file description root_table = h5file.create_table(h5file.root, "description", RecordingDescription, "Description of %s" % filename) root_row = root_table.row root_row['channels'] = len(rec) root_row['date'] = rec.date root_row['time'] = rec.time root_row.append() root_table.flush() # write comment comment_group = h5file.create_group("/", "comment", "multiline file comment") strarray = h5file.create_array(comment_group, "comment", [rec.comment,], "multiline file comment") # create group for channel names: chroot_group = h5file.create_group("/", "channels", "channel names") # loop through channels: for n_c in range(len(rec)): channel_name = rec[n_c].name if channel_name == "": channel_name = "ch%d" % (n_c) channel_group = h5file.create_group("/", channel_name, "channel%d" % (n_c)) # write channel name to root group: strarray = h5file.create_array(chroot_group, "ch%d" % n_c, [channel_name,], "channel name") channel_table = h5file.create_table(channel_group, "description", ChannelDescription, "Description of %s" % channel_name) channel_row = channel_table.row channel_row['n_sections'] = len(rec[n_c]) channel_row.append() channel_table.flush() if len(rec[n_c])==1: max_log10 = 0 else: max_log10 = int(np.log10(len(rec[n_c])-1)) for n_s in range(len(rec[n_c])): # construct a number with leading zeros: if n_s==0: n10 = 0 else: n10 = int(np.log10(n_s)) strZero = "" for n_z in range(n10,max_log10): strZero += "0" # construct a section name: section_name = "sec%d" % (n_s) # create a child group in the channel: section_group = h5file.create_group(channel_group, "section_%s%d" % (strZero, n_s), section_name) # add data and description: array = h5file.create_array(section_group, "data", np.array(rec[n_c][n_s].data, dtype=np.float32), "data in %s" % section_name) desc_table = h5file.create_table(section_group, "description", SectionDescription, "description of %s" % section_name) desc_row = desc_table.row desc_row['dt'] = rec[n_c][n_s].dt desc_row['xunits'] = rec[n_c][n_s].xunits desc_row['yunits'] = rec[n_c][n_s].yunits desc_row.append() desc_table.flush() return True def export_hdf5( filename="" ): """ Exports a file in hdf5 format using PyTables. """ stf = __import__("stf") if filename=="": filename = "%s.h5" % (stf.get_filename()) # loop through channels: channel_list = list() for n_c in range(stf.get_size_recording()): section_list = [ Section( stf.get_trace(n_s, n_c), stf.get_sampling_interval(), stf.get_xunits(), stf.get_yunits(n_s, n_c) ) \ for n_s in range(stf.get_size_channel(n_c)) ] channel_list.append( Channel( section_list, stf.get_channel_name() ) ) rec = Recording( channel_list, stf.get_recording_comment(), stf.get_recording_date(), stf.get_recording_time() ) save_hdf5( rec, filename ) return True def import_hdf5( filename ): """ Imports a file in hdf5 format stored by stimfit using PyTables, returns a Recording object. """ h5file = tables.open_file( filename, mode='r' ) # read global file description root_node = h5file.getNode("/", "description") date = root_node.col("date")[0] time = root_node.col("time")[0] n_channels = root_node.col("channels")[0] # read comment com = h5file.getNode("/", "comment") comment = "" for entry in h5file.walkNodes(com,classname='Array'): comment += "%s" % entry.read()[0] # read channel names channel_names = list() chan = h5file.getNode("/", "channels") for entry in h5file.walkNodes(chan, classname='Array'): channel_names.append( "%s" % entry.read()[0] ) # read data from channels: channel_list = list() for n_c in range(n_channels): channel_node = h5file.getNode("/", channel_names[n_c]) chdesc_node = h5file.getNode( channel_node, "description" ) n_sections = chdesc_node.col("n_sections")[0] # required number of zeros: if n_sections==1: max_log10 = 0 else: max_log10 = int(np.log10(n_sections-1)) # loop through sections: section_list = list() for n_s in range(n_sections): # construct a number with leading zeros: if n_s==0: n10 = 0 else: n10 = int(np.log10(n_s)) strZero = "" for n_z in range(n10,max_log10): strZero += "0" section_name = "section_%s%d" % ( strZero, n_s) section_node = h5file.getNode( channel_node, section_name ) secdesc_node = h5file.getNode( section_node, "description" ) dt = secdesc_node.col("dt")[0] xunits = secdesc_node.col("xunits")[0] yunits = secdesc_node.col("yunits")[0] data = h5file.getNode( section_node, "data").read() section_list.append( Section(data, dt, xunits, yunits) ) channel_list.append( Channel(section_list, channel_names[n_c]) ) h5file.close() return Recording( channel_list, comment, date, time ) def open_hdf5( filename ): """ Opens and shows an hdf5 file with stimfit """ rec = import_hdf5( filename ) stf = __import__("stf") stf._gNames_resize( len(rec.channels) ) for n_c in range(len(rec.channels)): stf._gNames_at( rec.channels[n_c].name, n_c ) stf.new_window_list( rec.get_list() ) n_channels = stf.get_size_recording() dt = rec.channels[0].sections[0].dt stf.set_sampling_interval( dt ) stf.set_recording_comment( rec.comment ) stf.set_recording_date( rec.date ) stf.set_recording_time( rec.time ) for n_c in range(stf.get_size_recording()): for n_s in range(stf.get_size_channel(n_c)): xunits = rec.channels[n_c].sections[n_s].xunits yunits = rec.channels[n_c].sections[n_s].yunits stf.set_xunits( xunits ) stf.set_yunits( yunits, n_s, n_c ) return True def show_rec( rec ): """ Shows recording object in a new stimfit window """ stf = __import__("stf") stf._gNames_resize( len(rec.channels) ) for n_c in range(len(rec.channels)): stf._gNames_at( rec.channels[n_c].name, n_c ) stf.new_window_list( rec.get_list() ) n_channels = stf.get_size_recording() dt = rec.channels[0].sections[0].dt stf.set_sampling_interval( dt ) stf.set_recording_comment( rec.comment ) stf.set_recording_date( rec.date ) stf.set_recording_time( rec.time ) for n_c in range(stf.get_size_recording()): for n_s in range(stf.get_size_channel(n_c)): xunits = rec.channels[n_c].sections[n_s].xunits yunits = rec.channels[n_c].sections[n_s].yunits stf.set_xunits( xunits ) stf.set_yunits( yunits, n_s, n_c ) return True def test(): export_hdf5() open_hdf5("/home/cs/data/EE07_04_11_2AC.dat.h5") stimfit-0.16.7/src/stimfit/py/Makefile.am0000775000175000017500000000430414750344764013723 if BUILD_PYTHON pkglib_LTLIBRARIES = libpystf.la $(srcdir)/pystf_wrap.cxx $(srcdir)/stf.py: $(srcdir)/pystf.i $(SWIG) $(SWIG_PYTHON_OPT) -o $@ $< cat $(srcdir)/gccwarn $(srcdir)/pystf_wrap.cxx > $(srcdir)/pystf_wrap_tmp.cxx mv $(srcdir)/pystf_wrap_tmp.cxx $(srcdir)/pystf_wrap.cxx nodist_libpystf_la_SOURCES = $(srcdir)/pystf_wrap.cxx libpystf_la_SOURCES = $(srcdir)/pystf.cxx # $(SWIG_SOURCES) noinst_HEADERS = pystf.h INCLUDES = $(LIBNUMPY_INCLUDES) $(LIBPYTHON_INCLUDES) $(LIBWXPYTHON_INCLUDES) libpystf_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src libpystf_la_CXXFLAGS = $(OPT_CXXFLAGS) $(WX_CXXFLAGS) libpystf_la_LDFLAGS = $(LIBPYTHON_LDFLAGS) $(LIBSTF_LDFLAGS) $(LIBBIOSIG_LDFLAGS) libpystf_la_LIBADD = ../libstimfit.la ../../libstfio/libstfio.la $(WX_LIBS) if WITH_BIOSIGLITE libpystf_la_LIBADD += ../../libbiosiglite/libbiosiglite.la endif EXTRA_DIST = pystf.i numpy.i ivtools.py mintools.py natools.py minidemo.py charlie.py mintools.py hdf5tools.py spells.py tdms.py embedded_init.py embedded_stf.py embedded_mpl.py embedded_ipython.py heka.py extensions.py gccwarn install-exec-hook: cd ${prefix}/lib/stimfit && ln -sf ${STF_PYTHON_LIBNAME} _stf.so rm -f ${prefix}/lib/stimfit/*.la rm -f ${prefix}/lib/stimfit/*.a cp -p $(srcdir)/ivtools.py ${prefix}/lib/stimfit cp -p $(srcdir)/mintools.py ${prefix}/lib/stimfit cp -p $(srcdir)/natools.py ${prefix}/lib/stimfit cp -p $(srcdir)/minidemo.py ${prefix}/lib/stimfit cp -p $(srcdir)/charlie.py ${prefix}/lib/stimfit cp -p $(srcdir)/hdf5tools.py ${prefix}/lib/stimfit cp -p $(srcdir)/stf.py ${prefix}/lib/stimfit cp -p $(srcdir)/spells.py ${prefix}/lib/stimfit cp -p $(srcdir)/tdms.py ${prefix}/lib/stimfit cp -p $(srcdir)/embedded_init.py ${prefix}/lib/stimfit cp -p $(srcdir)/embedded_stf.py ${prefix}/lib/stimfit cp -p $(srcdir)/embedded_mpl.py ${prefix}/lib/stimfit cp -p $(srcdir)/embedded_ipython.py ${prefix}/lib/stimfit cp -p $(srcdir)/heka.py ${prefix}/lib/stimfit cp -p $(srcdir)/extensions.py ${prefix}/lib/stimfit cp -p $(srcdir)/../../pystfio/stfio_plot.py ${prefix}/lib/stimfit chmod -x ${prefix}/lib/stimfit/*.py uninstall-hook: rm -rf ${prefix}/lib/stimfit clean_local: rm -f $(srcdir)/pystf_wrap.cxx $(srcdir)/stf.py endif stimfit-0.16.7/src/stimfit/py/Makefile.in0000664000175000017500000006761314764352410013735 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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@ 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@ @BUILD_PYTHON_TRUE@@WITH_BIOSIGLITE_TRUE@am__append_1 = ../../libbiosiglite/libbiosiglite.la subdir = src/stimfit/py ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acsite.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__noinst_HEADERS_DIST) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/stfconf.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)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = @BUILD_PYTHON_TRUE@libpystf_la_DEPENDENCIES = ../libstimfit.la \ @BUILD_PYTHON_TRUE@ ../../libstfio/libstfio.la \ @BUILD_PYTHON_TRUE@ $(am__DEPENDENCIES_1) $(am__append_1) am__libpystf_la_SOURCES_DIST = $(srcdir)/pystf.cxx @BUILD_PYTHON_TRUE@am_libpystf_la_OBJECTS = libpystf_la-pystf.lo @BUILD_PYTHON_TRUE@nodist_libpystf_la_OBJECTS = \ @BUILD_PYTHON_TRUE@ libpystf_la-pystf_wrap.lo libpystf_la_OBJECTS = $(am_libpystf_la_OBJECTS) \ $(nodist_libpystf_la_OBJECTS) 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 = libpystf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(libpystf_la_CXXFLAGS) \ $(CXXFLAGS) $(libpystf_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON_TRUE@am_libpystf_la_rpath = -rpath $(pkglibdir) 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@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libpystf_la-pystf.Plo \ ./$(DEPDIR)/libpystf_la-pystf_wrap.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 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 = $(libpystf_la_SOURCES) $(nodist_libpystf_la_SOURCES) DIST_SOURCES = $(am__libpystf_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__noinst_HEADERS_DIST = pystf.h HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # 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)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ GT_CPPFLAGS = @GT_CPPFLAGS@ GT_CXXFLAGS = @GT_CXXFLAGS@ GT_LDFLAGS = @GT_LDFLAGS@ GT_LIBS = @GT_LIBS@ HDF5_CFLAGS = @HDF5_CFLAGS@ HDF5_LIBS = @HDF5_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBIOSIG_LDFLAGS = @LIBBIOSIG_LDFLAGS@ LIBHDF5_LDFLAGS = @LIBHDF5_LDFLAGS@ LIBLAPACK_LDFLAGS = @LIBLAPACK_LDFLAGS@ LIBNUMPY_INCLUDES = @LIBNUMPY_INCLUDES@ LIBOBJS = @LIBOBJS@ LIBPYTHON_INCLUDES = @LIBPYTHON_INCLUDES@ LIBPYTHON_LDFLAGS = @LIBPYTHON_LDFLAGS@ LIBS = @LIBS@ LIBSTF_LDFLAGS = @LIBSTF_LDFLAGS@ LIBTOOL = @LIBTOOL@ LIBWXPYTHON_INCLUDES = @LIBWXPYTHON_INCLUDES@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MACSETFILE = @MACSETFILE@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ 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@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSTLINK_COMMAND = @POSTLINK_COMMAND@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIST_PKG = @PYTHON_DIST_PKG@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ PYTHON_NUMPY_INCLUDE = @PYTHON_NUMPY_INCLUDE@ PYTHON_PRE_DIST_PKG = @PYTHON_PRE_DIST_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ PYTHON_WXPYTHON_INCLUDE = @PYTHON_WXPYTHON_INCLUDE@ PY_AC_VERSION = @PY_AC_VERSION@ RANLIB = @RANLIB@ REZ = @REZ@ SED = @SED@ SETFILE = @SETFILE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STFIO_PYTHON_LIBNAME = @STFIO_PYTHON_LIBNAME@ STF_PYTHON_LIBNAME = @STF_PYTHON_LIBNAME@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ VERSION = @VERSION@ WX_CPPFLAGS = @WX_CPPFLAGS@ WX_CXXFLAGS = @WX_CXXFLAGS@ WX_LIBS = @WX_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ 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@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ 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@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @BUILD_PYTHON_TRUE@pkglib_LTLIBRARIES = libpystf.la @BUILD_PYTHON_TRUE@nodist_libpystf_la_SOURCES = $(srcdir)/pystf_wrap.cxx @BUILD_PYTHON_TRUE@libpystf_la_SOURCES = $(srcdir)/pystf.cxx # $(SWIG_SOURCES) @BUILD_PYTHON_TRUE@noinst_HEADERS = pystf.h @BUILD_PYTHON_TRUE@INCLUDES = $(LIBNUMPY_INCLUDES) $(LIBPYTHON_INCLUDES) $(LIBWXPYTHON_INCLUDES) @BUILD_PYTHON_TRUE@libpystf_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src @BUILD_PYTHON_TRUE@libpystf_la_CXXFLAGS = $(OPT_CXXFLAGS) $(WX_CXXFLAGS) @BUILD_PYTHON_TRUE@libpystf_la_LDFLAGS = $(LIBPYTHON_LDFLAGS) $(LIBSTF_LDFLAGS) $(LIBBIOSIG_LDFLAGS) @BUILD_PYTHON_TRUE@libpystf_la_LIBADD = ../libstimfit.la \ @BUILD_PYTHON_TRUE@ ../../libstfio/libstfio.la $(WX_LIBS) \ @BUILD_PYTHON_TRUE@ $(am__append_1) @BUILD_PYTHON_TRUE@EXTRA_DIST = pystf.i numpy.i ivtools.py mintools.py natools.py minidemo.py charlie.py mintools.py hdf5tools.py spells.py tdms.py embedded_init.py embedded_stf.py embedded_mpl.py embedded_ipython.py heka.py extensions.py gccwarn all: all-am .SUFFIXES: .SUFFIXES: .cxx .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/stimfit/py/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/stimfit/py/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || 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)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_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}; \ } libpystf.la: $(libpystf_la_OBJECTS) $(libpystf_la_DEPENDENCIES) $(EXTRA_libpystf_la_DEPENDENCIES) $(AM_V_CXXLD)$(libpystf_la_LINK) $(am_libpystf_la_rpath) $(libpystf_la_OBJECTS) $(libpystf_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpystf_la-pystf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpystf_la-pystf_wrap.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cxx.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 $@ $< .cxx.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) '$<'` .cxx.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 $@ $< libpystf_la-pystf.lo: $(srcdir)/pystf.cxx @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystf_la_CPPFLAGS) $(CPPFLAGS) $(libpystf_la_CXXFLAGS) $(CXXFLAGS) -MT libpystf_la-pystf.lo -MD -MP -MF $(DEPDIR)/libpystf_la-pystf.Tpo -c -o libpystf_la-pystf.lo `test -f '$(srcdir)/pystf.cxx' || echo '$(srcdir)/'`$(srcdir)/pystf.cxx @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpystf_la-pystf.Tpo $(DEPDIR)/libpystf_la-pystf.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(srcdir)/pystf.cxx' object='libpystf_la-pystf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystf_la_CPPFLAGS) $(CPPFLAGS) $(libpystf_la_CXXFLAGS) $(CXXFLAGS) -c -o libpystf_la-pystf.lo `test -f '$(srcdir)/pystf.cxx' || echo '$(srcdir)/'`$(srcdir)/pystf.cxx libpystf_la-pystf_wrap.lo: $(srcdir)/pystf_wrap.cxx @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystf_la_CPPFLAGS) $(CPPFLAGS) $(libpystf_la_CXXFLAGS) $(CXXFLAGS) -MT libpystf_la-pystf_wrap.lo -MD -MP -MF $(DEPDIR)/libpystf_la-pystf_wrap.Tpo -c -o libpystf_la-pystf_wrap.lo `test -f '$(srcdir)/pystf_wrap.cxx' || echo '$(srcdir)/'`$(srcdir)/pystf_wrap.cxx @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpystf_la-pystf_wrap.Tpo $(DEPDIR)/libpystf_la-pystf_wrap.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(srcdir)/pystf_wrap.cxx' object='libpystf_la-pystf_wrap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpystf_la_CPPFLAGS) $(CPPFLAGS) $(libpystf_la_CXXFLAGS) $(CXXFLAGS) -c -o libpystf_la-pystf_wrap.lo `test -f '$(srcdir)/pystf_wrap.cxx' || echo '$(srcdir)/'`$(srcdir)/pystf_wrap.cxx mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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" 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 distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @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 check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am 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." @BUILD_PYTHON_FALSE@install-exec-hook: @BUILD_PYTHON_FALSE@uninstall-hook: clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libpystf_la-pystf.Plo -rm -f ./$(DEPDIR)/libpystf_la-pystf_wrap.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ 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-pkglibLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook 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 ./$(DEPDIR)/libpystf_la-pystf.Plo -rm -f ./$(DEPDIR)/libpystf_la-pystf_wrap.Plo -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-pkglibLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir 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-exec-hook install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-pkglibLTLIBRARIES \ install-ps install-ps-am install-strip 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-hook \ uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile @BUILD_PYTHON_TRUE@$(srcdir)/pystf_wrap.cxx $(srcdir)/stf.py: $(srcdir)/pystf.i @BUILD_PYTHON_TRUE@ $(SWIG) $(SWIG_PYTHON_OPT) -o $@ $< @BUILD_PYTHON_TRUE@ cat $(srcdir)/gccwarn $(srcdir)/pystf_wrap.cxx > $(srcdir)/pystf_wrap_tmp.cxx @BUILD_PYTHON_TRUE@ mv $(srcdir)/pystf_wrap_tmp.cxx $(srcdir)/pystf_wrap.cxx @BUILD_PYTHON_TRUE@install-exec-hook: @BUILD_PYTHON_TRUE@ cd ${prefix}/lib/stimfit && ln -sf ${STF_PYTHON_LIBNAME} _stf.so @BUILD_PYTHON_TRUE@ rm -f ${prefix}/lib/stimfit/*.la @BUILD_PYTHON_TRUE@ rm -f ${prefix}/lib/stimfit/*.a @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/ivtools.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/mintools.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/natools.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/minidemo.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/charlie.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/hdf5tools.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/stf.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/spells.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/tdms.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/embedded_init.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/embedded_stf.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/embedded_mpl.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/embedded_ipython.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/heka.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/extensions.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ cp -p $(srcdir)/../../pystfio/stfio_plot.py ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@ chmod -x ${prefix}/lib/stimfit/*.py @BUILD_PYTHON_TRUE@uninstall-hook: @BUILD_PYTHON_TRUE@ rm -rf ${prefix}/lib/stimfit @BUILD_PYTHON_TRUE@clean_local: @BUILD_PYTHON_TRUE@ rm -f $(srcdir)/pystf_wrap.cxx $(srcdir)/stf.py # 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: stimfit-0.16.7/src/stimfit/py/charlie.py0000775000175000017500000001276214750344764013657 """ Calculates resistances 2008-05-06, C. Schmidt-Hieber Indices are zero-based! """ import numpy as np # stimfit python module: import stf # import iv tools: import ivtools def resistance( base_start, base_end, peak_start, peak_end, amplitude ): """Calculates the resistance from a series of voltage clamp traces. Keyword arguments: base_start -- Starting index (zero-based) of the baseline cursors. base_end -- End index (zero-based) of the baseline cursors. peak_start -- Starting index (zero-based) of the peak cursors. peak_end -- End index (zero-based) of the peak cursors. amplitude -- Amplitude of the voltage command. Returns: The resistance. """ if (stf.check_doc() == False): print('Couldn\'t find an open file; aborting now.') return 0 # A temporary array to calculate the average: set = np.empty( (stf.get_size_channel(), stf.get_size_trace()) ) for n in range( 0, stf.get_size_channel() ): # Add this trace to set: set[n] = stf.get_trace( n ) # calculate average and create a new section from it: stf.new_window( np.average(set,0) ) # set peak cursors: if ( not(stf.set_peak_mean(-1)) ): return False # -1 means all points within peak window. if ( not(stf.set_peak_start(peak_start)) ): return False if ( not(stf.set_peak_end(peak_end)) ): return False # set base cursors: if ( not(stf.set_base_start(base_start)) ): return False if ( not(stf.set_base_end(base_end)) ): return False # measure everything: stf.measure() # calculate r_seal and return: return amplitude / (stf.get_peak()-stf.get_base()) def r_seal( amplitude=50 ): """Calculates the seal resistance from a series of voltage clamp traces. Keyword arguments: amplitude -- Amplitude of the voltage command. Defaults to 50 mV. Returns: The seal resistance. """ return resistance( 0, 199, 1050, 1199, amplitude ) def r_in( amplitude=-5 ): """Calculates the input resistance from a series of voltage clamp traces. Keyword arguments: amplitude -- Amplitude of the voltage command. Defaults to -5 mV. Returns: The input resistance. """ return resistance( 0, 999, 10700, 10999, amplitude ) def glu_iv( pulses = 13, subtract_base=True ): """Calculates an iv from a repeated series of fast application and voltage pulses. Keyword arguments: pulses -- Number of pulses for the iv. subtract_base -- If True (default), baseline will be subtracted. Returns: True if successful. """ # Some ugly definitions for the time being # Cursors are in ms here. gFitEnd = 330.6 # fit end cursor is variable gFSelect = 0 # Monoexp gDictSize = stf.leastsq_param_size( gFSelect ) + 2 # Parameters, chisqr, peak value gBaseStart = 220.5 # Start and end of the baseline before the control pulse, in ms gBaseEnd = 223.55 gPeakStart = 223.55 # Start and end of the peak cursors for the control pulse, in ms gPeakEnd = 253.55 if ( gDictSize < 0 ): print('Couldn\'t retrieve function id=%d, aborting now.'%gFSelect) return False if ( not(stf.check_doc()) ): print('Couldn\'t find an open file; aborting now.') return False # analyse iv, subtract baseline if requested: ivtools.analyze_iv( pulses ) if ( subtract_base == True ): if ( not(stf.set_base_start( gBaseStart, True )) ): return False if ( not(stf.set_base_end( gBaseEnd, True )) ): return False stf.measure() stf.select_all() stf.subtract_base() # set cursors: if ( not(stf.set_peak_start( gPeakStart, True )) ): return False if ( not(stf.set_peak_end( gPeakEnd, True )) ): return False if ( not(stf.set_base_start( gBaseStart, True )) ): return False if ( not(stf.set_base_end( gBaseEnd, True )) ): return False if ( not(stf.set_fit_end( gFitEnd, True )) ): return False if ( not(stf.set_peak_mean( 3 )) ): return False if ( not(stf.set_peak_direction( "both" )) ): return False # A list for dictionary keys and values: dict_keys = [] dict_values = np.empty( (gDictSize, stf.get_size_channel()) ) firstpass = True for n in range( 0, stf.get_size_channel() ): if ( stf.set_trace( n ) == False ): print('Couldn\'t set a new trace; aborting now.') return False print('Analyzing trace %d of %d'%( n+1, stf.get_size_channel() ) ) # set the fit window cursors: if ( not(stf.set_fit_start( stf.peak_index() )) ): return False # Least-squares fitting: p_dict = stf.leastsq( gFSelect ) if ( p_dict == 0 ): print('Couldn\'t perform a fit; aborting now.') return False # Create an empty list: tempdict_entry = [] row = 0 for k, v in p_dict.iteritems(): if ( firstpass == True ): dict_keys.append( k ) dict_values[row][n] = v row = row+1 if ( firstpass ): dict_keys.append( "Peak amplitude" ) dict_values[row][n] = stf.get_peak()-stf.get_base() firstpass = False retDict = dict() # Create the dictionary for the table: entry = 0 for elem in dict_keys: retDict[ elem ] = dict_values[entry].tolist() entry = entry+1 return stf.show_table_dictlist( retDict ) stimfit-0.16.7/src/stimfit/py/numpy.i0000664000175000017500000031100414752207205013172 /* -*- C -*- (not really, but good for syntax highlighting) */ /* * Copyright (c) 2005-2015, NumPy Developers. * 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 NumPy Developers nor the names of any * 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. */ #ifdef SWIGPYTHON %{ #ifndef SWIG_FILE_WITH_INIT #define NO_IMPORT_ARRAY #endif #include "stdio.h" #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include %} /**********************************************************************/ %fragment("NumPy_Backward_Compatibility", "header") { %#if NPY_API_VERSION < NPY_1_7_API_VERSION %#define NPY_ARRAY_DEFAULT NPY_DEFAULT %#define NPY_ARRAY_FARRAY NPY_FARRAY %#define NPY_FORTRANORDER NPY_FORTRAN %#endif } /**********************************************************************/ /* The following code originally appeared in * enthought/kiva/agg/src/numeric.i written by Eric Jones. It was * translated from C++ to C by John Hunter. Bill Spotz has modified * it to fix some minor bugs, upgrade from Numeric to numpy (all * versions), add some comments and functionality, and convert from * direct code insertion to SWIG fragments. */ %fragment("NumPy_Macros", "header") { /* Macros to extract array attributes. */ %#if NPY_API_VERSION < NPY_1_7_API_VERSION %#define is_array(a) ((a) && PyArray_Check((PyArrayObject*)a)) %#define array_type(a) (int)(PyArray_TYPE((PyArrayObject*)a)) %#define array_numdims(a) (((PyArrayObject*)a)->nd) %#define array_dimensions(a) (((PyArrayObject*)a)->dimensions) %#define array_size(a,i) (((PyArrayObject*)a)->dimensions[i]) %#define array_strides(a) (((PyArrayObject*)a)->strides) %#define array_stride(a,i) (((PyArrayObject*)a)->strides[i]) %#define array_data(a) (((PyArrayObject*)a)->data) %#define array_descr(a) (((PyArrayObject*)a)->descr) %#define array_flags(a) (((PyArrayObject*)a)->flags) %#define array_clearflags(a,f) (((PyArrayObject*)a)->flags) &= ~f %#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f %#define array_is_fortran(a) (PyArray_ISFORTRAN((PyArrayObject*)a)) %#else %#define is_array(a) ((a) && PyArray_Check(a)) %#define array_type(a) PyArray_TYPE((PyArrayObject*)a) %#define array_numdims(a) PyArray_NDIM((PyArrayObject*)a) %#define array_dimensions(a) PyArray_DIMS((PyArrayObject*)a) %#define array_strides(a) PyArray_STRIDES((PyArrayObject*)a) %#define array_stride(a,i) PyArray_STRIDE((PyArrayObject*)a,i) %#define array_size(a,i) PyArray_DIM((PyArrayObject*)a,i) %#define array_data(a) PyArray_DATA((PyArrayObject*)a) %#define array_descr(a) PyArray_DESCR((PyArrayObject*)a) %#define array_flags(a) PyArray_FLAGS((PyArrayObject*)a) %#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f) %#define array_clearflags(a,f) PyArray_CLEARFLAGS((PyArrayObject*)a,f) %#define array_is_fortran(a) (PyArray_IS_F_CONTIGUOUS((PyArrayObject*)a)) %#endif %#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a)) %#define array_is_native(a) (PyArray_ISNOTSWAPPED((PyArrayObject*)a)) } /**********************************************************************/ %fragment("NumPy_Utilities", "header") { /* Given a PyObject, return a string describing its type. */ const char* pytype_string(PyObject* py_obj) { if (py_obj == NULL ) return "C NULL value"; if (py_obj == Py_None ) return "Python None" ; if (PyCallable_Check(py_obj)) return "callable" ; if (PyBytes_Check( py_obj)) return "string" ; if (PyLong_Check( py_obj)) return "int" ; if (PyFloat_Check( py_obj)) return "float" ; if (PyDict_Check( py_obj)) return "dict" ; if (PyList_Check( py_obj)) return "list" ; if (PyTuple_Check( py_obj)) return "tuple" ; return "unknown type"; } /* Given a NumPy typecode, return a string describing the type. */ const char* typecode_string(int typecode) { static const char* type_names[25] = {"bool", "byte", "unsigned byte", "short", "unsigned short", "int", "unsigned int", "long", "unsigned long", "long long", "unsigned long long", "float", "double", "long double", "complex float", "complex double", "complex long double", "object", "string", "unicode", "void", "ntypes", "notype", "char", "unknown"}; return typecode < 24 ? type_names[typecode] : type_names[24]; } /* Make sure input has correct numpy type. This now just calls PyArray_EquivTypenums(). */ int type_match(int actual_type, int desired_type) { return PyArray_EquivTypenums(actual_type, desired_type); } void free_cap(PyObject * cap) { void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME); if (array != NULL) free(array); } } /**********************************************************************/ %fragment("NumPy_Object_to_Array", "header", fragment="NumPy_Backward_Compatibility", fragment="NumPy_Macros", fragment="NumPy_Utilities") { /* Given a PyObject pointer, cast it to a PyArrayObject pointer if * legal. If not, set the python error string appropriately and * return NULL. */ PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode) { PyArrayObject* ary = NULL; if (is_array(input) && (typecode == NPY_NOTYPE || PyArray_EquivTypenums(array_type(input), typecode))) { ary = (PyArrayObject*) input; } else if is_array(input) { const char* desired_type = typecode_string(typecode); const char* actual_type = typecode_string(array_type(input)); PyErr_Format(PyExc_TypeError, "Array of type '%s' required. Array of type '%s' given", desired_type, actual_type); ary = NULL; } else { const char* desired_type = typecode_string(typecode); const char* actual_type = pytype_string(input); PyErr_Format(PyExc_TypeError, "Array of type '%s' required. A '%s' was given", desired_type, actual_type); ary = NULL; } return ary; } /* Convert the given PyObject to a NumPy array with the given * typecode. On success, return a valid PyArrayObject* with the * correct type. On failure, the python error string will be set and * the routine returns NULL. */ PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode, int* is_new_object) { PyArrayObject* ary = NULL; PyObject* py_obj; if (is_array(input) && (typecode == NPY_NOTYPE || PyArray_EquivTypenums(array_type(input),typecode))) { ary = (PyArrayObject*) input; *is_new_object = 0; } else { py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT); /* If NULL, PyArray_FromObject will have set python error value.*/ ary = (PyArrayObject*) py_obj; *is_new_object = 1; } return ary; } /* Given a PyArrayObject, check to see if it is contiguous. If so, * return the input pointer and flag it as not a new object. If it is * not contiguous, create a new PyArrayObject using the original data, * flag it as a new object and return the pointer. */ PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object, int min_dims, int max_dims) { PyArrayObject* result; if (array_is_contiguous(ary)) { result = ary; *is_new_object = 0; } else { result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary, array_type(ary), min_dims, max_dims); *is_new_object = 1; } return result; } /* Given a PyArrayObject, check to see if it is Fortran-contiguous. * If so, return the input pointer, but do not flag it as not a new * object. If it is not Fortran-contiguous, create a new * PyArrayObject using the original data, flag it as a new object * and return the pointer. */ PyArrayObject* make_fortran(PyArrayObject* ary, int* is_new_object) { PyArrayObject* result; if (array_is_fortran(ary)) { result = ary; *is_new_object = 0; } else { Py_INCREF(array_descr(ary)); result = (PyArrayObject*) PyArray_FromArray(ary, array_descr(ary), %#if NPY_API_VERSION < NPY_1_7_API_VERSION NPY_FORTRANORDER); %#else NPY_ARRAY_F_CONTIGUOUS); %#endif *is_new_object = 1; } return result; } /* Convert a given PyObject to a contiguous PyArrayObject of the * specified type. If the input object is not a contiguous * PyArrayObject, a new one will be created and the new object flag * will be set. */ PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input, int typecode, int* is_new_object) { int is_new1 = 0; int is_new2 = 0; PyArrayObject* ary2; PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode, &is_new1); if (ary1) { ary2 = make_contiguous(ary1, &is_new2, 0, 0); if ( is_new1 && is_new2) { Py_DECREF(ary1); } ary1 = ary2; } *is_new_object = is_new1 || is_new2; return ary1; } /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the * specified type. If the input object is not a Fortran-ordered * PyArrayObject, a new one will be created and the new object flag * will be set. */ PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input, int typecode, int* is_new_object) { int is_new1 = 0; int is_new2 = 0; PyArrayObject* ary2; PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode, &is_new1); if (ary1) { ary2 = make_fortran(ary1, &is_new2); if (is_new1 && is_new2) { Py_DECREF(ary1); } ary1 = ary2; } *is_new_object = is_new1 || is_new2; return ary1; } } /* end fragment */ /**********************************************************************/ %fragment("NumPy_Array_Requirements", "header", fragment="NumPy_Backward_Compatibility", fragment="NumPy_Macros") { /* Test whether a python object is contiguous. If array is * contiguous, return 1. Otherwise, set the python error string and * return 0. */ int require_contiguous(PyArrayObject* ary) { int contiguous = 1; if (!array_is_contiguous(ary)) { PyErr_SetString(PyExc_TypeError, "Array must be contiguous. A non-contiguous array was given"); contiguous = 0; } return contiguous; } /* Test whether a python object is (C_ or F_) contiguous. If array is * contiguous, return 1. Otherwise, set the python error string and * return 0. */ int require_c_or_f_contiguous(PyArrayObject* ary) { int contiguous = 1; if (!(array_is_contiguous(ary) || array_is_fortran(ary))) { PyErr_SetString(PyExc_TypeError, "Array must be contiguous (C_ or F_). A non-contiguous array was given"); contiguous = 0; } return contiguous; } /* Require that a numpy array is not byte-swapped. If the array is * not byte-swapped, return 1. Otherwise, set the python error string * and return 0. */ int require_native(PyArrayObject* ary) { int native = 1; if (!array_is_native(ary)) { PyErr_SetString(PyExc_TypeError, "Array must have native byteorder. " "A byte-swapped array was given"); native = 0; } return native; } /* Require the given PyArrayObject to have a specified number of * dimensions. If the array has the specified number of dimensions, * return 1. Otherwise, set the python error string and return 0. */ int require_dimensions(PyArrayObject* ary, int exact_dimensions) { int success = 1; if (array_numdims(ary) != exact_dimensions) { PyErr_Format(PyExc_TypeError, "Array must have %d dimensions. Given array has %d dimensions", exact_dimensions, array_numdims(ary)); success = 0; } return success; } /* Require the given PyArrayObject to have one of a list of specified * number of dimensions. If the array has one of the specified number * of dimensions, return 1. Otherwise, set the python error string * and return 0. */ int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n) { int success = 0; int i; char dims_str[255] = ""; char s[255]; for (i = 0; i < n && !success; i++) { if (array_numdims(ary) == exact_dimensions[i]) { success = 1; } } if (!success) { for (i = 0; i < n-1; i++) { snprintf(s, sizeof(s), "%d, ", exact_dimensions[i]); strcat(dims_str,s); } snprintf(s, sizeof(s), " or %d", exact_dimensions[n-1]); strcat(dims_str,s); PyErr_Format(PyExc_TypeError, "Array must have %s dimensions. Given array has %d dimensions", dims_str, array_numdims(ary)); } return success; } /* Require the given PyArrayObject to have a specified shape. If the * array has the specified shape, return 1. Otherwise, set the python * error string and return 0. */ int require_size(PyArrayObject* ary, npy_intp* size, int n) { int i; int success = 1; size_t len; char desired_dims[255] = "["; char s[255]; char actual_dims[255] = "["; for(i=0; i < n;i++) { if (size[i] != -1 && size[i] != array_size(ary,i)) { success = 0; } } if (!success) { for (i = 0; i < n; i++) { if (size[i] == -1) { snprintf(s, sizeof(s), "*,"); } else { snprintf(s, sizeof(s), "%ld,", (long int)size[i]); } strcat(desired_dims,s); } len = strlen(desired_dims); desired_dims[len-1] = ']'; for (i = 0; i < n; i++) { snprintf(s, sizeof(s), "%ld,", (long int)array_size(ary,i)); strcat(actual_dims,s); } len = strlen(actual_dims); actual_dims[len-1] = ']'; PyErr_Format(PyExc_TypeError, "Array must have shape of %s. Given array has shape of %s", desired_dims, actual_dims); } return success; } /* Require the given PyArrayObject to be Fortran ordered. If the * the PyArrayObject is already Fortran ordered, do nothing. Else, * set the Fortran ordering flag and recompute the strides. */ int require_fortran(PyArrayObject* ary) { int success = 1; int nd = array_numdims(ary); int i; npy_intp * strides = array_strides(ary); if (array_is_fortran(ary)) return success; int n_non_one = 0; /* Set the Fortran ordered flag */ const npy_intp *dims = array_dimensions(ary); for (i=0; i < nd; ++i) n_non_one += (dims[i] != 1) ? 1 : 0; if (n_non_one > 1) array_clearflags(ary,NPY_ARRAY_CARRAY); array_enableflags(ary,NPY_ARRAY_FARRAY); /* Recompute the strides */ strides[0] = strides[nd-1]; for (i=1; i < nd; ++i) strides[i] = strides[i-1] * array_size(ary,i-1); return success; } } /* Combine all NumPy fragments into one for convenience */ %fragment("NumPy_Fragments", "header", fragment="NumPy_Backward_Compatibility", fragment="NumPy_Macros", fragment="NumPy_Utilities", fragment="NumPy_Object_to_Array", fragment="NumPy_Array_Requirements") { } /* End John Hunter translation (with modifications by Bill Spotz) */ /* %numpy_typemaps() macro * * This macro defines a family of 75 typemaps that allow C arguments * of the form * * 1. (DATA_TYPE IN_ARRAY1[ANY]) * 2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) * 3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) * * 4. (DATA_TYPE IN_ARRAY2[ANY][ANY]) * 5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) * 6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) * 7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) * 8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) * * 9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) * 10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * 11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * 12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) * 13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * 14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) * * 15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) * 16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) * 17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) * 18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) * 19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) * 20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) * * 21. (DATA_TYPE INPLACE_ARRAY1[ANY]) * 22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) * 23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) * * 24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) * 25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) * 26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) * 27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) * 28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) * * 29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) * 30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * 31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * 32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) * 33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * 34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) * * 35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) * 36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) * 37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) * 38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) * 39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) * 40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) * * 41. (DATA_TYPE ARGOUT_ARRAY1[ANY]) * 42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) * 43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) * * 44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) * * 45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) * * 46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) * * 47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) * 48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) * * 49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) * 50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) * 51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) * 52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) * * 53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) * 54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) * 55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) * 56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) * * 57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) * 58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4) * 59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) * 60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4) * * 61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) * 62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) * * 63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) * 64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) * 65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) * 66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) * * 67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) * 68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3) * 69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) * 70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3) * * 71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) * 72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) * 73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) * 74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) * * 75. (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) * * where "DATA_TYPE" is any type supported by the NumPy module, and * "DIM_TYPE" is any int-like type suitable for specifying dimensions. * The difference between "ARRAY" typemaps and "FARRAY" typemaps is * that the "FARRAY" typemaps expect Fortran ordering of * multidimensional arrays. In python, the dimensions will not need * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1" * typemaps). The IN_ARRAYs can be a numpy array or any sequence that * can be converted to a numpy array of the specified type. The * INPLACE_ARRAYs must be numpy arrays of the appropriate type. The * ARGOUT_ARRAYs will be returned as new numpy arrays of the * appropriate type. * * These typemaps can be applied to existing functions using the * %apply directive. For example: * * %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)}; * double prod(double* series, int length); * * %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2) * {(int rows, int cols, double* matrix )}; * void floor(int rows, int cols, double* matrix, double f); * * %apply (double IN_ARRAY3[ANY][ANY][ANY]) * {(double tensor[2][2][2] )}; * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY]) * {(double low[2][2][2] )}; * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY]) * {(double upp[2][2][2] )}; * void luSplit(double tensor[2][2][2], * double low[2][2][2], * double upp[2][2][2] ); * * or directly with * * double prod(double* IN_ARRAY1, int DIM1); * * void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f); * * void luSplit(double IN_ARRAY3[ANY][ANY][ANY], * double ARGOUT_ARRAY3[ANY][ANY][ANY], * double ARGOUT_ARRAY3[ANY][ANY][ANY]); */ %define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE) /************************/ /* Input Array Typemaps */ /************************/ /* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE IN_ARRAY1[ANY]) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE IN_ARRAY1[ANY]) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[1] = { $1_dim0 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 1) || !require_size(array, size, 1)) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(freearg) (DATA_TYPE IN_ARRAY1[ANY]) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[1] = { -1 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 1) || !require_size(array, size, 1)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); } %typemap(freearg) (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[1] = {-1}; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 1) || !require_size(array, size, 1)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DATA_TYPE*) array_data(array); } %typemap(freearg) (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE IN_ARRAY2[ANY][ANY]) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE IN_ARRAY2[ANY][ANY]) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[2] = { $1_dim0, $1_dim1 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 2) || !require_size(array, size, 2)) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(freearg) (DATA_TYPE IN_ARRAY2[ANY][ANY]) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[2] = { -1, -1 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 2) || !require_size(array, size, 2)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); } %typemap(freearg) (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[2] = { -1, -1 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 2) || !require_size(array, size, 2)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DATA_TYPE*) array_data(array); } %typemap(freearg) (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[2] = { -1, -1 }; array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 2) || !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); } %typemap(freearg) (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[2] = { -1, -1 }; array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 2) || !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DATA_TYPE*) array_data(array); } %typemap(freearg) (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 3) || !require_size(array, size, 3)) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(freearg) (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[3] = { -1, -1, -1 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 3) || !require_size(array, size, 3)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); } %typemap(freearg) (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { /* for now, only concerned with lists */ $1 = PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL) { npy_intp size[2] = { -1, -1 }; PyArrayObject* temp_array; Py_ssize_t i; int is_new_object; /* length of the list */ $2 = PyList_Size($input); /* the arrays */ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); is_new_object_array = (int *)calloc($2,sizeof(int)); if (array == NULL || object_array == NULL || is_new_object_array == NULL) { SWIG_fail; } for (i=0; i<$2; i++) { temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object); /* the new array must be stored so that it can be destroyed in freearg */ object_array[i] = temp_array; is_new_object_array[i] = is_new_object; if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail; /* store the size of the first array in the list, then use that for comparison. */ if (i == 0) { size[0] = array_size(temp_array,0); size[1] = array_size(temp_array,1); } if (!require_size(temp_array, size, 2)) SWIG_fail; array[i] = (DATA_TYPE*) array_data(temp_array); } $1 = (DATA_TYPE**) array; $3 = (DIM_TYPE) size[0]; $4 = (DIM_TYPE) size[1]; } %typemap(freearg) (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { Py_ssize_t i; if (array$argnum!=NULL) free(array$argnum); /*freeing the individual arrays if needed */ if (object_array$argnum!=NULL) { if (is_new_object_array$argnum!=NULL) { for (i=0; i<$2; i++) { if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i]) { Py_DECREF(object_array$argnum[i]); } } free(is_new_object_array$argnum); } free(object_array$argnum); } } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, * DATA_TYPE* IN_ARRAY3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[3] = { -1, -1, -1 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 3) || !require_size(array, size, 3)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DATA_TYPE*) array_data(array); } %typemap(freearg) (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[3] = { -1, -1, -1 }; array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 3) || !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); } %typemap(freearg) (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, * DATA_TYPE* IN_FARRAY3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[3] = { -1, -1, -1 }; array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 3) || !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DATA_TYPE*) array_data(array); } %typemap(freearg) (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3}; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 4) || !require_size(array, size, 4)) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(freearg) (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3, DIM_TYPE DIM4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[4] = { -1, -1, -1, -1 }; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 4) || !require_size(array, size, 4)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); $5 = (DIM_TYPE) array_size(array,3); } %typemap(freearg) (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3, DIM_TYPE DIM4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { /* for now, only concerned with lists */ $1 = PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL) { npy_intp size[3] = { -1, -1, -1 }; PyArrayObject* temp_array; Py_ssize_t i; int is_new_object; /* length of the list */ $2 = PyList_Size($input); /* the arrays */ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); is_new_object_array = (int *)calloc($2,sizeof(int)); if (array == NULL || object_array == NULL || is_new_object_array == NULL) { SWIG_fail; } for (i=0; i<$2; i++) { temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object); /* the new array must be stored so that it can be destroyed in freearg */ object_array[i] = temp_array; is_new_object_array[i] = is_new_object; if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail; /* store the size of the first array in the list, then use that for comparison. */ if (i == 0) { size[0] = array_size(temp_array,0); size[1] = array_size(temp_array,1); size[2] = array_size(temp_array,2); } if (!require_size(temp_array, size, 3)) SWIG_fail; array[i] = (DATA_TYPE*) array_data(temp_array); } $1 = (DATA_TYPE**) array; $3 = (DIM_TYPE) size[0]; $4 = (DIM_TYPE) size[1]; $5 = (DIM_TYPE) size[2]; } %typemap(freearg) (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { Py_ssize_t i; if (array$argnum!=NULL) free(array$argnum); /*freeing the individual arrays if needed */ if (object_array$argnum!=NULL) { if (is_new_object_array$argnum!=NULL) { for (i=0; i<$2; i++) { if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i]) { Py_DECREF(object_array$argnum[i]); } } free(is_new_object_array$argnum); } free(object_array$argnum); } } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, * DATA_TYPE* IN_ARRAY4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[4] = { -1, -1, -1 , -1}; array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 4) || !require_size(array, size, 4)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DIM_TYPE) array_size(array,3); $5 = (DATA_TYPE*) array_data(array); } %typemap(freearg) (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3, DIM_TYPE DIM4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[4] = { -1, -1, -1, -1 }; array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 4) || !require_size(array, size, 4) | !require_fortran(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); $5 = (DIM_TYPE) array_size(array,3); } %typemap(freearg) (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, * DATA_TYPE* IN_FARRAY4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) { $1 = is_array($input) || PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) (PyArrayObject* array=NULL, int is_new_object=0) { npy_intp size[4] = { -1, -1, -1 , -1 }; array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, &is_new_object); if (!array || !require_dimensions(array, 4) || !require_size(array, size, 4) || !require_fortran(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DIM_TYPE) array_size(array,3); $5 = (DATA_TYPE*) array_data(array); } %typemap(freearg) (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) { if (is_new_object$argnum && array$argnum) { Py_DECREF(array$argnum); } } /***************************/ /* In-Place Array Typemaps */ /***************************/ /* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE INPLACE_ARRAY1[ANY]) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE INPLACE_ARRAY1[ANY]) (PyArrayObject* array=NULL) { npy_intp size[1] = { $1_dim0 }; array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = ($1_ltype) array_data(array); } /* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) (PyArrayObject* array=NULL, int i=1) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,1) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = 1; for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i); } /* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) (PyArrayObject* array=NULL, int i=0) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,1) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = 1; for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i); $2 = (DATA_TYPE*) array_data(array); } /* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) (PyArrayObject* array=NULL) { npy_intp size[2] = { $1_dim0, $1_dim1 }; array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = ($1_ltype) array_data(array); } /* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,2) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,2) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DATA_TYPE*) array_data(array); } /* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,2) || !require_contiguous(array) || !require_native(array) || !require_fortran(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,2) || !require_contiguous(array) || !require_native(array) || !require_fortran(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DATA_TYPE*) array_data(array); } /* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) (PyArrayObject* array=NULL) { npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 }; array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = ($1_ltype) array_data(array); } /* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,3) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); } /* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { $1 = PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL) { npy_intp size[2] = { -1, -1 }; PyArrayObject* temp_array; Py_ssize_t i; /* length of the list */ $2 = PyList_Size($input); /* the arrays */ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); if (array == NULL || object_array == NULL) { SWIG_fail; } for (i=0; i<$2; i++) { temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE); /* the new array must be stored so that it can be destroyed in freearg */ object_array[i] = temp_array; if ( !temp_array || !require_dimensions(temp_array, 2) || !require_contiguous(temp_array) || !require_native(temp_array) || !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE) ) SWIG_fail; /* store the size of the first array in the list, then use that for comparison. */ if (i == 0) { size[0] = array_size(temp_array,0); size[1] = array_size(temp_array,1); } if (!require_size(temp_array, size, 2)) SWIG_fail; array[i] = (DATA_TYPE*) array_data(temp_array); } $1 = (DATA_TYPE**) array; $3 = (DIM_TYPE) size[0]; $4 = (DIM_TYPE) size[1]; } %typemap(freearg) (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { if (array$argnum!=NULL) free(array$argnum); if (object_array$argnum!=NULL) free(object_array$argnum); } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, * DATA_TYPE* INPLACE_ARRAY3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,3) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DATA_TYPE*) array_data(array); } /* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,3) || !require_contiguous(array) || !require_native(array) || !require_fortran(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, * DATA_TYPE* INPLACE_FARRAY3) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,3) || !require_contiguous(array) || !require_native(array) || !require_fortran(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DATA_TYPE*) array_data(array); } /* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) (PyArrayObject* array=NULL) { npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 }; array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = ($1_ltype) array_data(array); } /* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3, DIM_TYPE DIM4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,4) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); $5 = (DIM_TYPE) array_size(array,3); } /* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3, DIM_TYPE DIM4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { $1 = PySequence_Check($input); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL) { npy_intp size[3] = { -1, -1, -1 }; PyArrayObject* temp_array; Py_ssize_t i; /* length of the list */ $2 = PyList_Size($input); /* the arrays */ array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); if (array == NULL || object_array == NULL) { SWIG_fail; } for (i=0; i<$2; i++) { temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE); /* the new array must be stored so that it can be destroyed in freearg */ object_array[i] = temp_array; if ( !temp_array || !require_dimensions(temp_array, 3) || !require_contiguous(temp_array) || !require_native(temp_array) || !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE) ) SWIG_fail; /* store the size of the first array in the list, then use that for comparison. */ if (i == 0) { size[0] = array_size(temp_array,0); size[1] = array_size(temp_array,1); size[2] = array_size(temp_array,2); } if (!require_size(temp_array, size, 3)) SWIG_fail; array[i] = (DATA_TYPE*) array_data(temp_array); } $1 = (DATA_TYPE**) array; $3 = (DIM_TYPE) size[0]; $4 = (DIM_TYPE) size[1]; $5 = (DIM_TYPE) size[2]; } %typemap(freearg) (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { if (array$argnum!=NULL) free(array$argnum); if (object_array$argnum!=NULL) free(object_array$argnum); } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, * DATA_TYPE* INPLACE_ARRAY4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,4) || !require_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DIM_TYPE) array_size(array,3); $5 = (DATA_TYPE*) array_data(array); } /* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, * DIM_TYPE DIM3, DIM_TYPE DIM4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,4) || !require_contiguous(array) || !require_native(array) || !require_fortran(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = (DIM_TYPE) array_size(array,0); $3 = (DIM_TYPE) array_size(array,1); $4 = (DIM_TYPE) array_size(array,2); $5 = (DIM_TYPE) array_size(array,3); } /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, * DATA_TYPE* INPLACE_FARRAY4) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) (PyArrayObject* array=NULL) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_dimensions(array,4) || !require_contiguous(array) || !require_native(array) || !require_fortran(array)) SWIG_fail; $1 = (DIM_TYPE) array_size(array,0); $2 = (DIM_TYPE) array_size(array,1); $3 = (DIM_TYPE) array_size(array,2); $4 = (DIM_TYPE) array_size(array,3); $5 = (DATA_TYPE*) array_data(array); } /*************************/ /* Argout Array Typemaps */ /*************************/ /* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY]) */ %typemap(in,numinputs=0, fragment="NumPy_Backward_Compatibility,NumPy_Macros") (DATA_TYPE ARGOUT_ARRAY1[ANY]) (PyObject* array = NULL) { npy_intp dims[1] = { $1_dim0 }; array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); if (!array) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(argout) (DATA_TYPE ARGOUT_ARRAY1[ANY]) { $result = SWIG_AppendOutput($result,(PyObject*)array$argnum); } /* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) */ %typemap(in,numinputs=1, fragment="NumPy_Fragments") (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) (PyObject* array = NULL) { npy_intp dims[1]; if (!PyLong_Check($input)) { const char* typestring = pytype_string($input); PyErr_Format(PyExc_TypeError, "Int dimension expected. '%s' given.", typestring); SWIG_fail; } $2 = (DIM_TYPE) PyLong_AsSsize_t($input); if ($2 == -1 && PyErr_Occurred()) SWIG_fail; dims[0] = (npy_intp) $2; array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); if (!array) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); } %typemap(argout) (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) { $result = SWIG_AppendOutput($result,(PyObject*)array$argnum); } /* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) */ %typemap(in,numinputs=1, fragment="NumPy_Fragments") (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) (PyObject* array = NULL) { npy_intp dims[1]; if (!PyLong_Check($input)) { const char* typestring = pytype_string($input); PyErr_Format(PyExc_TypeError, "Int dimension expected. '%s' given.", typestring); SWIG_fail; } $1 = (DIM_TYPE) PyLong_AsSsize_t($input); if ($1 == -1 && PyErr_Occurred()) SWIG_fail; dims[0] = (npy_intp) $1; array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); if (!array) SWIG_fail; $2 = (DATA_TYPE*) array_data(array); } %typemap(argout) (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) { $result = SWIG_AppendOutput($result,(PyObject*)array$argnum); } /* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) */ %typemap(in,numinputs=0, fragment="NumPy_Backward_Compatibility,NumPy_Macros") (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) (PyObject* array = NULL) { npy_intp dims[2] = { $1_dim0, $1_dim1 }; array = PyArray_SimpleNew(2, dims, DATA_TYPECODE); if (!array) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(argout) (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) { $result = SWIG_AppendOutput($result,(PyObject*)array$argnum); } /* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) */ %typemap(in,numinputs=0, fragment="NumPy_Backward_Compatibility,NumPy_Macros") (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) (PyObject* array = NULL) { npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 }; array = PyArray_SimpleNew(3, dims, DATA_TYPECODE); if (!array) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(argout) (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) { $result = SWIG_AppendOutput($result,(PyObject*)array$argnum); } /* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) */ %typemap(in,numinputs=0, fragment="NumPy_Backward_Compatibility,NumPy_Macros") (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) (PyObject* array = NULL) { npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 }; array = PyArray_SimpleNew(4, dims, DATA_TYPECODE); if (!array) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(argout) (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) { $result = SWIG_AppendOutput($result,(PyObject*)array$argnum); } /*****************************/ /* Argoutview Array Typemaps */ /*****************************/ /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp) { $1 = &data_temp; $2 = &dim_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) { npy_intp dims[1] = { *$2 }; PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEW_ARRAY1) (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim_temp; $2 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) { npy_intp dims[1] = { *$1 }; PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) { npy_intp dims[2] = { *$2, *$3 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_ARRAY2) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) { npy_intp dims[2] = { *$1, *$2 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) { npy_intp dims[2] = { *$2, *$3 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) { npy_intp dims[2] = { *$1, *$2 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) { npy_intp dims[3] = { *$2, *$3, *$4 }; PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) { npy_intp dims[3] = { *$1, *$2, *$3 }; PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) { npy_intp dims[3] = { *$2, *$3, *$4 }; PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEW_FARRAY3) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) { npy_intp dims[3] = { *$1, *$2, *$3 }; PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; $5 = &dim4_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) { npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_ARRAY4) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &dim4_temp; $5 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4) { npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; $5 = &dim4_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) { npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_FARRAY4) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &dim4_temp; $5 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4) { npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; $result = SWIG_AppendOutput($result,obj); } /*************************************/ /* Managed Argoutview Array Typemaps */ /*************************************/ /* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp) { $1 = &data_temp; $2 = &dim_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) { npy_intp dims[1] = { *$2 }; PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEWM_ARRAY1) (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim_temp; $2 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) { npy_intp dims[1] = { *$1 }; PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$2), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) { npy_intp dims[2] = { *$2, *$3 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_ARRAY2) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) { npy_intp dims[2] = { *$1, *$2 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$3), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) { npy_intp dims[2] = { *$2, *$3 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_FARRAY2) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) { npy_intp dims[2] = { *$1, *$2 }; PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$3), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) { npy_intp dims[3] = { *$2, *$3, *$4 }; PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_ARRAY3) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3) { npy_intp dims[3] = { *$1, *$2, *$3 }; PyObject* obj= PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$4), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) { npy_intp dims[3] = { *$2, *$3, *$4 }; PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_FARRAY3) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3) { npy_intp dims[3] = { *$1, *$2, *$3 }; PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$4), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; $5 = &dim4_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) { npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &dim4_temp; $5 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Utilities") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) { npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); PyArrayObject* array = (PyArrayObject*) obj; if (!array) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) */ %typemap(in,numinputs=0) (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) { $1 = &data_temp; $2 = &dim1_temp; $3 = &dim2_temp; $4 = &dim3_temp; $5 = &dim4_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) { npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) */ %typemap(in,numinputs=0) (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4) (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) { $1 = &dim1_temp; $2 = &dim2_temp; $3 = &dim3_temp; $4 = &dim4_temp; $5 = &data_temp; } %typemap(argout, fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) { npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); PyArrayObject* array = (PyArrayObject*) obj; if (!array || !require_fortran(array)) SWIG_fail; PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap); %#if NPY_API_VERSION < NPY_1_7_API_VERSION PyArray_BASE(array) = cap; %#else PyArray_SetBaseObject(array,cap); %#endif $result = SWIG_AppendOutput($result,obj); } /**************************************/ /* In-Place Array Typemap - flattened */ /**************************************/ /* Typemap suite for (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, fragment="NumPy_Macros") (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) { $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), DATA_TYPECODE); } %typemap(in, fragment="NumPy_Fragments") (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) (PyArrayObject* array=NULL, int i=1) { array = obj_to_array_no_conversion($input, DATA_TYPECODE); if (!array || !require_c_or_f_contiguous(array) || !require_native(array)) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); $2 = 1; for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i); } %enddef /* %numpy_typemaps() macro */ /* *************************************************************** */ /* Concrete instances of the %numpy_typemaps() macro: Each invocation * below applies all of the typemaps above to the specified data type. */ %numpy_typemaps(signed char , NPY_BYTE , int) %numpy_typemaps(unsigned char , NPY_UBYTE , int) %numpy_typemaps(short , NPY_SHORT , int) %numpy_typemaps(unsigned short , NPY_USHORT , int) %numpy_typemaps(int , NPY_INT , int) %numpy_typemaps(unsigned int , NPY_UINT , int) %numpy_typemaps(long , NPY_LONG , int) %numpy_typemaps(unsigned long , NPY_ULONG , int) %numpy_typemaps(long long , NPY_LONGLONG , int) %numpy_typemaps(unsigned long long, NPY_ULONGLONG, int) %numpy_typemaps(float , NPY_FLOAT , int) %numpy_typemaps(double , NPY_DOUBLE , int) %numpy_typemaps(int8_t , NPY_INT8 , int) %numpy_typemaps(int16_t , NPY_INT16 , int) %numpy_typemaps(int32_t , NPY_INT32 , int) %numpy_typemaps(int64_t , NPY_INT64 , int) %numpy_typemaps(uint8_t , NPY_UINT8 , int) %numpy_typemaps(uint16_t , NPY_UINT16 , int) %numpy_typemaps(uint32_t , NPY_UINT32 , int) %numpy_typemaps(uint64_t , NPY_UINT64 , int) /* *************************************************************** * The follow macro expansion does not work, because C++ bool is 4 * bytes and NPY_BOOL is 1 byte * * %numpy_typemaps(bool, NPY_BOOL, int) */ /* *************************************************************** * On my Mac, I get the following warning for this macro expansion: * 'swig/python detected a memory leak of type 'long double *', no destructor found.' * * %numpy_typemaps(long double, NPY_LONGDOUBLE, int) */ #ifdef __cplusplus %include %numpy_typemaps(std::complex, NPY_CFLOAT , int) %numpy_typemaps(std::complex, NPY_CDOUBLE, int) #endif #endif /* SWIGPYTHON */ stimfit-0.16.7/src/stimfit/py/mintools.py0000775000175000017500000000200414750344764014100 """ 2008-04-11, C. Schmidt-Hieber Some helper functions for least-squares mimization using SciPy """ from scipy.optimize import leastsq import numpy as np import stf def fexpbde(p,x): tpeak = p[3]*p[1]*np.log(p[3]/p[1])/(p[3]-p[1]) adjust = 1.0/((1.0-np.exp(-tpeak/p[3]))-(1.0-np.exp(-tpeak/p[1]))); e1=np.exp((p[0]-x)/p[1]); e2=np.exp((p[0]-x)/p[3]); # normalize the amplitude so that the peak really is the peak: ret = adjust*p[2]*e1 - adjust*p[2]*e2 + stf.get_base(); start_index = 0 for elem in x: if ( elem < p[0] ): start_index = start_index+1 else: break ret[ 0 : start_index ] = stf.get_base() return ret def leastsq_stf(p,y,lsfunc,x): return y - lsfunc(p,x) def stf_fit( p0, lsfunc ): data = stf.get_trace()[ stf.get_fit_start() : stf.get_fit_end() ] dt = stf.get_sampling_interval() x = np.arange(0, len(data)*dt, dt) plsq = leastsq(leastsq_stf, p0, args=(data, lsfunc, x)) return plsq[0] stimfit-0.16.7/src/stimfit/py/spells.py0000664000175000017500000004327214750344764013547 """ spells.py Python recipes to solve frequently requested tasks with Stimfit. You can find a complete description of these functions in the Stimfit online documentation (http://www.stimfit.org/doc/sphinx/index.html) Check "The Stimfit Book of Spells" for details. Authors: Jose Guzman, Alois Schloegl and Christoph Schmidt-Hieber Last change: Tue Dec 16 10:50:15 CET 2014 """ import numpy as np # stimfit python module: import stf import wx # see APFrame class import wx.grid # see APFrame class from math import ceil, floor def resistance( base_start, base_end, peak_start, peak_end, amplitude): """Calculates the resistance from a series of voltage clamp traces. Keyword arguments: base_start -- Starting index (zero-based) of the baseline cursors. base_end -- End index (zero-based) of the baseline cursors. peak_start -- Starting index (zero-based) of the peak cursors. peak_end -- End index (zero-based) of the peak cursors. amplitude -- Amplitude of the voltage command. Returns: The resistance. """ if not stf.check_doc(): print('Couldn\'t find an open file; aborting now.') return 0 #A temporary array to calculate the average: array = np.empty( (stf.get_size_channel(), stf.get_size_trace()) ) for n in range( 0, stf.get_size_channel() ): # Add this trace to set: array[n] = stf.get_trace( n ) # calculate average and create a new section from it: stf.new_window( np.average(set, 0) ) # set peak cursors: # -1 means all points within peak window. if not stf.set_peak_mean(-1): return 0 if not stf.set_peak_start(peak_start): return 0 if not stf.set_peak_end(peak_end): return 0 # set base cursors: if not stf.set_base_start(base_start): return 0 if not stf.set_base_end(base_end): return 0 # measure everything: stf.measure() # calculate r_seal and return: return amplitude / (stf.get_peak()-stf.get_base()) def rmean(binwidth, trace=-1, channel=-1): """ Calculates a running mean of a single trace Arguments: binwidth -- size of the bin in sampling points (pt). Obviously, it should be smaller than the length of the trace. trace: -- ZERO-BASED index of the trace within the channel. Note that this is one less than what is shown in the drop-down box. The default value of -1 returns the currently displayed trace. channel -- ZERO-BASED index of the channel. This is independent of whether a channel is active or not. The default value of -1 returns the currently active channel. Returns: A smoothed traced in a new stf window. """ # loads the current trace of the channel in a 1D Numpy Array sweep = stf.get_trace(trace, channel) # creates a destination python list to append the data dsweep = np.empty((len(sweep))) # running mean algorithm for i in range(len(sweep)): if (len(sweep)-i) > binwidth: # append to list the running mean of `binwidth` values # np.mean(sweep) calculates the mean of list dsweep[i] = np.mean( sweep[i:(binwidth+i)] ) else: # use all remaining points for the average: dsweep[i] = np.mean( sweep[i:] ) stf.new_window(dsweep) def get_amplitude(base, peak, delta, trace=None): """ Calculates the amplitude deviation (peak-base) in units of the Y-axis Arguments: base -- Starting point (in ms) of the baseline cursor. peak -- Starting point (in ms) of the peak cursor. delta -- Time interval to calculate baseline/find the peak. trace -- Zero-based index of the trace to be processed, if None then current trace is computed. Returns: A float with the variation of the amplitude. False if Example: get_amplitude(980,1005,10,i) returns the variation of the Y unit of the trace i between peak value (10050+10) msec and baseline (980+10) msec """ # sets the current trace or the one given in trace if trace is None: sweep = stf.get_trace_index() else: if type(trace) != int: print('trace argument admits only intergers') return False sweep = trace # set base cursors: if not(stf.set_base_start(base, True)): return False # out-of range if not(stf.set_base_end(base+delta, True)): return False # set peak cursors: if not(stf.set_peak_start(peak, True)): return False # out-of range if not(stf.set_peak_end(peak+delta, True)): return False # update measurements stf.set_trace(sweep) amplitude = stf.get_peak()-stf.get_base() return amplitude def cut_sweeps(start, delta, sequence=None): """ Cuts a sequence of traces and present them in a new window. Arguments: start -- starting point (in ms) to cut. delta -- time interval (in ms) to cut sequence -- list of indices to be cut. If None, every trace in the channel will be cut. Returns: A new window with the traced cut. Examples: cut_sweeps(200,300) cut the traces between t=200 ms and t=500 ms within the whole channel. cut_sweeps(200,300,range(30,60)) the same as above, but only between traces 30 and 60. cut_sweeps(200,300,stf.get_selected_indices()) cut between 200 ms and 500 ms only in the selected traces. """ # select every trace in the channel if not selection is given in sequence if sequence is None: sequence = range(stf.get_size_channel()) # transform time into sampling points dt = stf.get_sampling_interval() pstart = int( round(start/dt) ) pdelta = int( round(delta/dt) ) # creates a destination python list dlist = [ stf.get_trace(i)[pstart:(pstart+pdelta)] for i in sequence ] return stf.new_window_list(dlist) def count_events(start, delta, threshold=0, up=True, trace=None, mark=True): """ Counts the number of events (e.g action potentials (AP)) in the current trace. Arguments: start -- starting time (in ms) to look for events. delta -- time interval (in ms) to look for events. threshold -- (optional) detection threshold (default = 0). up -- (optional) True (default) will look for upward events, False downwards. trace -- (optional) zero-based index of the trace in the current channel, if None, the current trace is selected. mark -- (optional) if True (default), set a mark at the point of threshold crossing Returns: An integer with the number of events. Examples: count_events(500,1000) returns the number of events found between t=500 ms and t=1500 ms above 0 in the current trace and shows a stf marker. count_events(500,1000,0,False,-10,i) returns the number of events found below -10 in the trace i and shows the corresponding stf markers. """ # sets the current trace or the one given in trace. if trace is None: sweep = stf.get_trace_index() else: if type(trace) !=int: print('trace argument admits only integers') return False sweep = trace # set the trace described in sweep stf.set_trace(sweep) # transform time into sampling points dt = stf.get_sampling_interval() pstart = int( round(start/dt) ) pdelta = int( round(delta/dt) ) # select the section of interest within the trace selection = stf.get_trace()[pstart:(pstart+pdelta)] # algorithm to detect events event_counter, i = 0, 0 # set counter and index to zero # choose comparator according to direction: if up: comp = lambda a, b: a > b else: comp = lambda a, b: a < b # run the loop while i < len(selection): if comp(selection[i], threshold): event_counter += 1 if mark: stf.set_marker(pstart+i, selection[i]) while i < len(selection) and comp(selection[i], threshold): i += 1 # skip until value is below/above threshold else: i += 1 return event_counter class Spike(object): """ A collection of methods to calculate AP properties from threshold (see Stuart et al., 1997). Note that all calculations are performed in the active/current channel!!! """ def __init__(self,threshold): """ Create a Spike instance with sampling rate and threshold measurements are performed in the current/active channel!!! Arguments: threshold -- slope threshold to measure AP kinetics """ self._thr = threshold # set all the necessary AP parameters at construction self._updateattributes() def _updateattributes(self): """ update base, peak, t50, max_rise and tamplitude """ self.base = self.get_base() # in Stimfit is baseline self.peak = self.get_peak() # in Stimfit peak (from threshold) self.t50 = self.get_t50() # in Stimfit t50 self.max_rise = self.get_max_rise() # in Stimfit Slope (rise) self.thr = self.get_threshold_value() # in Stimit Threshold # attributes necessary to calculate latencies self.tonset = self.get_threshold_time() self.tpeak = self.get_tamplitude() self.t50_left = self.get_t50left() def update(self): """ update current trace sampling rate, cursors position and measurements (peak, baseline & AP kinetics) according to the threshold value set at construction or when the object is called with a threshold argument. """ # set slope stf.set_slope(self._thr) # on stf v0.93 or above # update sampling rate self._dt = stf.get_sampling_interval() # update cursors and AP kinetics (peak and half-width) stf.measure() def __call__(self, threshold=None ): """ update AP kinetic parameters to a new threshold in the current trace/channel threshold (optional) -- the new threshold value Examples : dend = Spike(40) # set the spike threshold at 40mV/ms dend(20) # now we set the spike threshold at 20mV/ms The AP parameters will be thereby updated in the current trace/channel. This method allow us to use the same object to calculate AP latencies in different traces. """ if threshold is not None: self._thr = threshold # set a new threshold self.update() # update dt and sampling rate self._updateattributes() def get_base(self): """ Get baseline according to cursor possition in the given current channel/trace """ self.update() return stf.get_trace(trace = -1 ,channel = -1)[stf.get_base_start():stf.get_base_end()+1].mean() def get_peak(self): """ calculate peak measured from threshold in the current trace, (see Stuart et al (1997) """ stf.set_peak_mean(1) # a single point for the peak value stf.set_peak_direction("up") # peak direction up self.update() peak = stf.get_peak()-stf.get_threshold_value() return peak def get_t50(self): """ calculates the half-widht in ms in the current trace""" self.update() # current t50's difference to calculate half-width (t50) return (stf.t50right_index()-stf.t50left_index())*self._dt def get_max_rise(self): """ maximum rate of rise (dV/dt) of AP in the current trace, which depends on the available Na+ conductance, see Mainen et al, 1995, Schmidt-Hieber et al, 2008 """ self.update() pmaxrise = stf.maxrise_index() # in active channel trace = stf.get_trace(trace = -1, channel =-1) # current trace dV = trace[int(ceil(pmaxrise))]-trace[(int(floor(pmaxrise)))] return dV/self._dt def get_tamplitude(self): """ return the time a the peak in the current trace""" #stf.peak_index() does not update cursors!!! self.update() return stf.peak_index()*self._dt def get_t50left(self): """ return the time at the half-width """ self.update() return stf.t50left_index()*self._dt def show_threshold(self): """ return the threshold value (in mV/ms) set at construction or when the object was called""" return self._thr def get_threshold_value(self): """ return the value (in y-units) at the threshold """ self.update() # stf.get_threshold_value does not update return stf.get_threshold_value() def get_threshold_time(self): """ return the value (in x-units) at the threshold """ self.update() return stf.get_threshold_time('True') # TODO # how to get the name of the object as string # Latencies according to Schmidt-Hieber need revision!!! class APFrame(wx.Frame): def __init__(self, soma, dend): """ creates a grid and fill it with AP kinetics from soma and dendrites Arguments: soma_AP -- Spike object for the soma dend_AP -- Spike object for the dendrite see Spike() class for more details """ # first check that both soma and dend are Spike() instances if not isinstance(soma,Spike) or not isinstance(dend,Spike): print('wrong argument, did you create a Spike object???') return 0 # initialize the wxframe wx.Frame.__init__(self, None, \ title = "AP parameters (from threshold)", size = (740,135)) # wxgrid columns self.col = ["Threshold\n (mV/ms)", "Onset\n (ms)", "Onset\n (mV)", "Baseline\n (mV)", "AP Peak\n (mV)", "AP Peak\n (ms)", "Half-width\n (ms)","Vmax\n (mV/ms)"] # wxgrid rows self.row = ["Soma", "Dend", "latency"] # Grid grid = wx.grid.Grid(self) grid.CreateGrid(len(self.row), len(self.col)) # Set grid labels for i in range(len(self.col)): grid.SetColLabelValue(i, self.col[i]) for i in range(len(self.row)): grid.SetRowLabelValue(i, self.row[i]) # Create a list with the AP parameters for the dendrite somalist = [soma.show_threshold(), soma.tonset, soma.thr, soma.base, soma.peak, soma.tpeak, soma.t50, soma.max_rise] # Fill soma values in the grid for i in range(len(self.col)): grid.SetCellValue(0,i, "%.4f"%somalist[i]) # Create a list with the AP parameters for the dendrite dendlist = [dend.show_threshold(), dend.tonset, dend.thr, dend.base, dend.peak, dend.tpeak, dend.t50, dend.max_rise] # Fill dend values in the grid for i in range(len(self.col)): grid.SetCellValue(1,i, "%.4f"%dendlist[i]) # Calculate latencies with different methods # onset latency grid.SetCellValue(2,1, "%.4f"%(dend.tonset - soma.tonset)) # peak latency grid.SetCellValue(2,5, "%.4f"%(dend.tpeak - soma.tpeak)) # half-width latency grid.SetCellValue(2,6, "%.4f"%(dend.t50_left -soma.t50_left)) def latency(soma, dend): """ Shows a results table with the latencies between the somatic and dendritic object Arguments: soma -- Spike Object of a trace containing the somatic AP dend -- Spike Object of a trace containing the dendritic AP see Spike() class for more details """ frame = APFrame(soma, dend) frame.Show() def count_aps(): """ Shows a result table with the number of action potentials (i.e events whose potential is above 0 mV) in selected traces. If no trace is selected, then the current trace is analyzed. Returns: False if document is not open. """ if not stf.check_doc(): print("Open file first") return False if len( stf.get_selected_indices() )==0: sel_trace = [ stf.get_trace_index()] else: sel_trace = stf.get_selected_indices() mytable = dict() for trace in sel_trace: tstart = 0 tend = stf.get_size_trace(trace)*stf.get_sampling_interval() threshold = 0 spikes = count_events(tstart, tend, threshold, True, trace, True) mytable["Trace %.3d" %trace] = spikes stf.show_table(mytable) return True def loadnrn( file ): """ Load a NEURON datafile and opens a new Stimfit window with a trace with the default units (e.g ms and mV) Arguments: file -- (string) file to be read """ time, trace = np.loadtxt(fname = file, skiprows = 2, unpack =1) dt = time[1] # the second temporal sampling point is the sampling stf.new_window( trace ) stf.set_sampling_interval( dt ) def loadtxt(freq=400): """ Loads an ASCII file with extension *.GoR. This file contains ratiometric fluorescent measurements (i.e Green over Red fluorescence) saved in one column. This function opens a new Stimfit window and sets the x-units to "ms" and y-units to "Delta G over R". Arguments: freq -- (float) the sampling rate (in Hz) for fluorescence acquistion. the default value is 400 Hz """ fname = wx.FileSelector("Import Ca transients" , default_extension="Ratiometric" , default_path="." , wildcard = "Ratiometric fluorescence (*.GoR)|*.GoR" , flags = wx.OPEN | wx.FILE_MUST_EXIST) stf.new_window( np.loadtxt(fname) ) stf.set_xunits('ms') stf.set_yunits('Delta G/R') stf.set_sampling_interval(1.0/freq*1000) # acquisition at 400 Hz stimfit-0.16.7/src/stimfit/py/embedded_mpl.py0000775000175000017500000001001714750344764014640 #=========================================================================== # embedded_mpl.py # 2011.02.05 # Don't modify this file unless you know what you are doing!!! #=========================================================================== """ embedded_mpl.py starting code to embed a matplotlib wx figure into the stf application. """ import sys if 'linux' in sys.platform: import wxversion try: wxversion.select('2.8') except: pass import wx import matplotlib if sys.version_info[0] < 3: matplotlib.use('WXAgg') from matplotlib.backends.backend_wxagg import \ FigureCanvasWxAgg as FigCanvas, \ NavigationToolbar2WxAgg as NavigationToolbar from matplotlib.figure import Figure import matplotlib.mlab as mlab import numpy as np try: import stfio_plot except: from stfio import plot as stfio_plot class MplPanel(wx.Panel): """The matplotlib figure""" def __init__(self, parent, figsize=(8.0, 6.0)): super(MplPanel, self).__init__(parent, -1) self.fig = Figure(figsize, dpi=72) self.canvas = FigCanvas(self, -1, self.fig) # Since we have only one plot, we can use add_axes # instead of add_subplot, but then the subplot # configuration tool in the navigation toolbar wouldn't # work. # self.axes = self.fig.add_subplot(111) # Create the navigation toolbar, tied to the canvas # self.toolbar = NavigationToolbar(self.canvas) # # Layout with box sizers # self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas, 1, wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT, 10) self.vbox.Add(self.toolbar, 0, wx.EXPAND) self.SetSizer(self.vbox) def plot_screen(self): import stf tsl = [] try: l = stf.get_selected_indices() for idx in l: tsl.append(stfio_plot.Timeseries(stf.get_trace(idx), stf.get_sampling_interval(), yunits = stf.get_yunits(), color='0.2')) fit = stf.get_fit(idx) if fit is not None: self.axes.plot(fit[0], fit[1], color='0.4', alpha=0.5, lw=5.0) except: pass tsl.append(stfio_plot.Timeseries(stf.get_trace(), stf.get_sampling_interval(), yunits = stf.get_yunits())) if stf.get_size_recording()>1: tsl2 = [stfio_plot.Timeseries(stf.get_trace(trace=-1, channel=stf.get_channel_index(False)), stf.get_sampling_interval(), yunits = stf.get_yunits(trace=-1, channel=stf.get_channel_index(False)), color='r', linestyle='-r')] stfio_plot.plot_traces(tsl, traces2=tsl2, ax=self.axes, textcolor2 = 'r', xmin=stf.plot_xmin(), xmax=stf.plot_xmax(), ymin=stf.plot_ymin(), ymax=stf.plot_ymax(), y2min=stf.plot_y2min(), y2max=stf.plot_y2max()) else: stfio_plot.plot_traces(tsl, ax=self.axes, xmin=stf.plot_xmin(), xmax=stf.plot_xmax(), ymin=stf.plot_ymin(), ymax=stf.plot_ymax()) fit = stf.get_fit() if fit is not None: self.axes.plot(fit[0], fit[1], color='0.2', alpha=0.5, lw=5.0) def plot_spectrum(self): import stf Pow, freq = mlab.psd(stf.get_trace(), Fs=(1.0/stf.get_sampling_interval())*1e3, detrend=mlab.detrend_linear) self.axes.plot(freq, 10*np.log10(Pow)) self.axes.set_xlabel("Frequency (Hz)") self.axes.set_ylabel("Power spectral density (dB/Hz)") stimfit-0.16.7/src/stimfit/py/tdms.py0000664000175000017500000000026414750344764013206 import numpy as np import stf import stfio def tdms_open(fn): record = stfio.read_tdms(fn) if record is None: return None return record['data'], record['dt'] stimfit-0.16.7/src/stimfit/stf.cpp0000664000175000017500000000620214750344764012533 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file stf.cpp * \author Christoph Schmidt-Hieber * \date 2011-10-01 * \brief General functions for stf * * * Implements some general functions within the stf namespace */ #include "stf.h" #if 0 wxString stf::sectionToString(const Section& section) { wxString retString; retString << (int)section.size() << wxT("\n"); for (int n=0;n<(int)section.size();++n) { retString << section.GetXScale()*n << wxT("\t") << section[n] << wxT("\n"); } return retString; } wxString stf::CreatePreview(const wxString& fName) { ifstreamMan ASCIIfile( fName ); // Stop reading if we are either at the end or at line 100: wxString preview; ASCIIfile.myStream.ReadAll( &preview ); return preview; } #endif stf::wxProgressInfo::wxProgressInfo(const std::string& title, const std::string& message, int maximum, bool verbose) : ProgressInfo(title, message, maximum, verbose), pd(stf::std2wx(title), stf::std2wx(message), maximum, NULL, wxPD_SMOOTH | wxPD_AUTO_HIDE | wxPD_APP_MODAL ) { } bool stf::wxProgressInfo::Update(int value, const std::string& newmsg, bool* skip) { return pd.Update(value, stf::std2wx(newmsg), skip); } std::string stf::wx2std(const wxString& wxs) { #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) return wxs.ToStdString(); #else return std::string(wxs.mb_str()); #endif } wxString stf::std2wx(const std::string& sst) { #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) /* Problems with direct constructor; copying each character for the time being. return wxString(sst); */ wxString wxs; std::string::const_iterator it; for (it = sst.begin(); it != sst.end(); ++it) { if (*it < 0) wxs += ' '; else wxs += (char)*it; } return wxs; #else return wxString(sst.c_str(), wxConvUTF8); #endif } stf::SectionAttributes::SectionAttributes() : eventList(),pyMarkers(),isFitted(false), isIntegrated(false),fitFunc(NULL),bestFitP(0),quad_p(0),storeFitBeg(0),storeFitEnd(0), storeIntBeg(0),storeIntEnd(0),bestFit(0,0) {} stf::SectionPointer::SectionPointer(Section* pSec, const stf::SectionAttributes& sa) : pSection(pSec), sec_attr(sa) {} stf::Event::Event(std::size_t start, std::size_t peak, std::size_t size, wxCheckBox* cb) : eventStartIndex(start), eventPeakIndex(peak), eventSize(size), checkBox(cb) { checkBox->Show(true); checkBox->SetValue(true); } stf::Event::~Event() { } stimfit-0.16.7/src/stimfit/Makefile.am0000775000175000017500000000200514750344764013267 pkglib_LTLIBRARIES = libstimfit.la libstimfit_la_SOURCES = ./stf.cpp \ ./gui/app.cpp ./gui/unopt.cpp ./gui/doc.cpp ./gui/copygrid.cpp ./gui/graph.cpp \ ./gui/printout.cpp ./gui/parentframe.cpp ./gui/childframe.cpp ./gui/view.cpp ./gui/table.cpp ./gui/zoom.cpp \ ./gui/dlgs/convertdlg.cpp ./gui/dlgs/cursorsdlg.cpp ./gui/dlgs/eventdlg.cpp \ ./gui/dlgs/fitseldlg.cpp ./gui/dlgs/smalldlgs.cpp \ ./gui/usrdlg/usrdlg.cpp libstimfit_la_CPPFLAGS = libstimfit_la_CXXFLAGS = $(OPT_CXXFLAGS) $(WX_CXXFLAGS) libstimfit_la_LDFLAGS = $(LIBPYTHON_LDFLAGS) $(LIBSTF_LDFLAGS) libstimfit_la_LIBADD = $(WX_LIBS) ../libstfio/libstfio.la ../libstfnum/libstfnum.la if WITH_BIOSIGLITE libstimfit_la_LIBADD += ../libbiosiglite/libbiosiglite.la endif # the application source, library search path, and link libraries if BUILD_PYTHON PYTHON_ADDINCLUDES = $(LIBNUMPY_INCLUDES) $(LIBPYTHON_INCLUDES) $(LIBWXPYTHON_INCLUDES) else PYTHON_ADDINCLUDES = endif INCLUDES = $(PYTHON_ADDINCLUDES) stimfit-0.16.7/src/stimfit/Makefile.in0000664000175000017500000013703514764352410013301 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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@ 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@ @WITH_BIOSIGLITE_TRUE@am__append_1 = ../libbiosiglite/libbiosiglite.la subdir = src/stimfit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acsite.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/stfconf.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)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = libstimfit_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ ../libstfio/libstfio.la ../libstfnum/libstfnum.la \ $(am__append_1) am_libstimfit_la_OBJECTS = libstimfit_la-stf.lo libstimfit_la-app.lo \ libstimfit_la-unopt.lo libstimfit_la-doc.lo \ libstimfit_la-copygrid.lo libstimfit_la-graph.lo \ libstimfit_la-printout.lo libstimfit_la-parentframe.lo \ libstimfit_la-childframe.lo libstimfit_la-view.lo \ libstimfit_la-table.lo libstimfit_la-zoom.lo \ libstimfit_la-convertdlg.lo libstimfit_la-cursorsdlg.lo \ libstimfit_la-eventdlg.lo libstimfit_la-fitseldlg.lo \ libstimfit_la-smalldlgs.lo libstimfit_la-usrdlg.lo libstimfit_la_OBJECTS = $(am_libstimfit_la_OBJECTS) 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 = libstimfit_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) $(libstimfit_la_LDFLAGS) \ $(LDFLAGS) -o $@ 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@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libstimfit_la-app.Plo \ ./$(DEPDIR)/libstimfit_la-childframe.Plo \ ./$(DEPDIR)/libstimfit_la-convertdlg.Plo \ ./$(DEPDIR)/libstimfit_la-copygrid.Plo \ ./$(DEPDIR)/libstimfit_la-cursorsdlg.Plo \ ./$(DEPDIR)/libstimfit_la-doc.Plo \ ./$(DEPDIR)/libstimfit_la-eventdlg.Plo \ ./$(DEPDIR)/libstimfit_la-fitseldlg.Plo \ ./$(DEPDIR)/libstimfit_la-graph.Plo \ ./$(DEPDIR)/libstimfit_la-parentframe.Plo \ ./$(DEPDIR)/libstimfit_la-printout.Plo \ ./$(DEPDIR)/libstimfit_la-smalldlgs.Plo \ ./$(DEPDIR)/libstimfit_la-stf.Plo \ ./$(DEPDIR)/libstimfit_la-table.Plo \ ./$(DEPDIR)/libstimfit_la-unopt.Plo \ ./$(DEPDIR)/libstimfit_la-usrdlg.Plo \ ./$(DEPDIR)/libstimfit_la-view.Plo \ ./$(DEPDIR)/libstimfit_la-zoom.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 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 = $(libstimfit_la_SOURCES) DIST_SOURCES = $(libstimfit_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) # 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)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ GT_CPPFLAGS = @GT_CPPFLAGS@ GT_CXXFLAGS = @GT_CXXFLAGS@ GT_LDFLAGS = @GT_LDFLAGS@ GT_LIBS = @GT_LIBS@ HDF5_CFLAGS = @HDF5_CFLAGS@ HDF5_LIBS = @HDF5_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBIOSIG_LDFLAGS = @LIBBIOSIG_LDFLAGS@ LIBHDF5_LDFLAGS = @LIBHDF5_LDFLAGS@ LIBLAPACK_LDFLAGS = @LIBLAPACK_LDFLAGS@ LIBNUMPY_INCLUDES = @LIBNUMPY_INCLUDES@ LIBOBJS = @LIBOBJS@ LIBPYTHON_INCLUDES = @LIBPYTHON_INCLUDES@ LIBPYTHON_LDFLAGS = @LIBPYTHON_LDFLAGS@ LIBS = @LIBS@ LIBSTF_LDFLAGS = @LIBSTF_LDFLAGS@ LIBTOOL = @LIBTOOL@ LIBWXPYTHON_INCLUDES = @LIBWXPYTHON_INCLUDES@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MACSETFILE = @MACSETFILE@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ 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@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSTLINK_COMMAND = @POSTLINK_COMMAND@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIST_PKG = @PYTHON_DIST_PKG@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ PYTHON_NUMPY_INCLUDE = @PYTHON_NUMPY_INCLUDE@ PYTHON_PRE_DIST_PKG = @PYTHON_PRE_DIST_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ PYTHON_WXPYTHON_INCLUDE = @PYTHON_WXPYTHON_INCLUDE@ PY_AC_VERSION = @PY_AC_VERSION@ RANLIB = @RANLIB@ REZ = @REZ@ SED = @SED@ SETFILE = @SETFILE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STFIO_PYTHON_LIBNAME = @STFIO_PYTHON_LIBNAME@ STF_PYTHON_LIBNAME = @STF_PYTHON_LIBNAME@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ VERSION = @VERSION@ WX_CPPFLAGS = @WX_CPPFLAGS@ WX_CXXFLAGS = @WX_CXXFLAGS@ WX_LIBS = @WX_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ 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@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ 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@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = libstimfit.la libstimfit_la_SOURCES = ./stf.cpp \ ./gui/app.cpp ./gui/unopt.cpp ./gui/doc.cpp ./gui/copygrid.cpp ./gui/graph.cpp \ ./gui/printout.cpp ./gui/parentframe.cpp ./gui/childframe.cpp ./gui/view.cpp ./gui/table.cpp ./gui/zoom.cpp \ ./gui/dlgs/convertdlg.cpp ./gui/dlgs/cursorsdlg.cpp ./gui/dlgs/eventdlg.cpp \ ./gui/dlgs/fitseldlg.cpp ./gui/dlgs/smalldlgs.cpp \ ./gui/usrdlg/usrdlg.cpp libstimfit_la_CPPFLAGS = libstimfit_la_CXXFLAGS = $(OPT_CXXFLAGS) $(WX_CXXFLAGS) libstimfit_la_LDFLAGS = $(LIBPYTHON_LDFLAGS) $(LIBSTF_LDFLAGS) libstimfit_la_LIBADD = $(WX_LIBS) ../libstfio/libstfio.la \ ../libstfnum/libstfnum.la $(am__append_1) @BUILD_PYTHON_FALSE@PYTHON_ADDINCLUDES = # the application source, library search path, and link libraries @BUILD_PYTHON_TRUE@PYTHON_ADDINCLUDES = $(LIBNUMPY_INCLUDES) $(LIBPYTHON_INCLUDES) $(LIBWXPYTHON_INCLUDES) INCLUDES = $(PYTHON_ADDINCLUDES) all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/stimfit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/stimfit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || 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)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_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}; \ } libstimfit.la: $(libstimfit_la_OBJECTS) $(libstimfit_la_DEPENDENCIES) $(EXTRA_libstimfit_la_DEPENDENCIES) $(AM_V_CXXLD)$(libstimfit_la_LINK) -rpath $(pkglibdir) $(libstimfit_la_OBJECTS) $(libstimfit_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-app.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-childframe.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-convertdlg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-copygrid.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-cursorsdlg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-doc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-eventdlg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-fitseldlg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-graph.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-parentframe.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-printout.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-smalldlgs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-stf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-table.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-unopt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-usrdlg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-view.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstimfit_la-zoom.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cpp.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 $@ $< .cpp.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) '$<'` .cpp.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 $@ $< libstimfit_la-stf.lo: ./stf.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-stf.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-stf.Tpo -c -o libstimfit_la-stf.lo `test -f './stf.cpp' || echo '$(srcdir)/'`./stf.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-stf.Tpo $(DEPDIR)/libstimfit_la-stf.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./stf.cpp' object='libstimfit_la-stf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-stf.lo `test -f './stf.cpp' || echo '$(srcdir)/'`./stf.cpp libstimfit_la-app.lo: ./gui/app.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-app.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-app.Tpo -c -o libstimfit_la-app.lo `test -f './gui/app.cpp' || echo '$(srcdir)/'`./gui/app.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-app.Tpo $(DEPDIR)/libstimfit_la-app.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/app.cpp' object='libstimfit_la-app.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-app.lo `test -f './gui/app.cpp' || echo '$(srcdir)/'`./gui/app.cpp libstimfit_la-unopt.lo: ./gui/unopt.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-unopt.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-unopt.Tpo -c -o libstimfit_la-unopt.lo `test -f './gui/unopt.cpp' || echo '$(srcdir)/'`./gui/unopt.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-unopt.Tpo $(DEPDIR)/libstimfit_la-unopt.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/unopt.cpp' object='libstimfit_la-unopt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-unopt.lo `test -f './gui/unopt.cpp' || echo '$(srcdir)/'`./gui/unopt.cpp libstimfit_la-doc.lo: ./gui/doc.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-doc.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-doc.Tpo -c -o libstimfit_la-doc.lo `test -f './gui/doc.cpp' || echo '$(srcdir)/'`./gui/doc.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-doc.Tpo $(DEPDIR)/libstimfit_la-doc.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/doc.cpp' object='libstimfit_la-doc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-doc.lo `test -f './gui/doc.cpp' || echo '$(srcdir)/'`./gui/doc.cpp libstimfit_la-copygrid.lo: ./gui/copygrid.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-copygrid.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-copygrid.Tpo -c -o libstimfit_la-copygrid.lo `test -f './gui/copygrid.cpp' || echo '$(srcdir)/'`./gui/copygrid.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-copygrid.Tpo $(DEPDIR)/libstimfit_la-copygrid.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/copygrid.cpp' object='libstimfit_la-copygrid.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-copygrid.lo `test -f './gui/copygrid.cpp' || echo '$(srcdir)/'`./gui/copygrid.cpp libstimfit_la-graph.lo: ./gui/graph.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-graph.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-graph.Tpo -c -o libstimfit_la-graph.lo `test -f './gui/graph.cpp' || echo '$(srcdir)/'`./gui/graph.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-graph.Tpo $(DEPDIR)/libstimfit_la-graph.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/graph.cpp' object='libstimfit_la-graph.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-graph.lo `test -f './gui/graph.cpp' || echo '$(srcdir)/'`./gui/graph.cpp libstimfit_la-printout.lo: ./gui/printout.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-printout.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-printout.Tpo -c -o libstimfit_la-printout.lo `test -f './gui/printout.cpp' || echo '$(srcdir)/'`./gui/printout.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-printout.Tpo $(DEPDIR)/libstimfit_la-printout.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/printout.cpp' object='libstimfit_la-printout.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-printout.lo `test -f './gui/printout.cpp' || echo '$(srcdir)/'`./gui/printout.cpp libstimfit_la-parentframe.lo: ./gui/parentframe.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-parentframe.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-parentframe.Tpo -c -o libstimfit_la-parentframe.lo `test -f './gui/parentframe.cpp' || echo '$(srcdir)/'`./gui/parentframe.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-parentframe.Tpo $(DEPDIR)/libstimfit_la-parentframe.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/parentframe.cpp' object='libstimfit_la-parentframe.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-parentframe.lo `test -f './gui/parentframe.cpp' || echo '$(srcdir)/'`./gui/parentframe.cpp libstimfit_la-childframe.lo: ./gui/childframe.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-childframe.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-childframe.Tpo -c -o libstimfit_la-childframe.lo `test -f './gui/childframe.cpp' || echo '$(srcdir)/'`./gui/childframe.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-childframe.Tpo $(DEPDIR)/libstimfit_la-childframe.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/childframe.cpp' object='libstimfit_la-childframe.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-childframe.lo `test -f './gui/childframe.cpp' || echo '$(srcdir)/'`./gui/childframe.cpp libstimfit_la-view.lo: ./gui/view.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-view.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-view.Tpo -c -o libstimfit_la-view.lo `test -f './gui/view.cpp' || echo '$(srcdir)/'`./gui/view.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-view.Tpo $(DEPDIR)/libstimfit_la-view.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/view.cpp' object='libstimfit_la-view.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-view.lo `test -f './gui/view.cpp' || echo '$(srcdir)/'`./gui/view.cpp libstimfit_la-table.lo: ./gui/table.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-table.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-table.Tpo -c -o libstimfit_la-table.lo `test -f './gui/table.cpp' || echo '$(srcdir)/'`./gui/table.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-table.Tpo $(DEPDIR)/libstimfit_la-table.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/table.cpp' object='libstimfit_la-table.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-table.lo `test -f './gui/table.cpp' || echo '$(srcdir)/'`./gui/table.cpp libstimfit_la-zoom.lo: ./gui/zoom.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-zoom.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-zoom.Tpo -c -o libstimfit_la-zoom.lo `test -f './gui/zoom.cpp' || echo '$(srcdir)/'`./gui/zoom.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-zoom.Tpo $(DEPDIR)/libstimfit_la-zoom.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/zoom.cpp' object='libstimfit_la-zoom.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-zoom.lo `test -f './gui/zoom.cpp' || echo '$(srcdir)/'`./gui/zoom.cpp libstimfit_la-convertdlg.lo: ./gui/dlgs/convertdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-convertdlg.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-convertdlg.Tpo -c -o libstimfit_la-convertdlg.lo `test -f './gui/dlgs/convertdlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/convertdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-convertdlg.Tpo $(DEPDIR)/libstimfit_la-convertdlg.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/dlgs/convertdlg.cpp' object='libstimfit_la-convertdlg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-convertdlg.lo `test -f './gui/dlgs/convertdlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/convertdlg.cpp libstimfit_la-cursorsdlg.lo: ./gui/dlgs/cursorsdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-cursorsdlg.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-cursorsdlg.Tpo -c -o libstimfit_la-cursorsdlg.lo `test -f './gui/dlgs/cursorsdlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/cursorsdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-cursorsdlg.Tpo $(DEPDIR)/libstimfit_la-cursorsdlg.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/dlgs/cursorsdlg.cpp' object='libstimfit_la-cursorsdlg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-cursorsdlg.lo `test -f './gui/dlgs/cursorsdlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/cursorsdlg.cpp libstimfit_la-eventdlg.lo: ./gui/dlgs/eventdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-eventdlg.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-eventdlg.Tpo -c -o libstimfit_la-eventdlg.lo `test -f './gui/dlgs/eventdlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/eventdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-eventdlg.Tpo $(DEPDIR)/libstimfit_la-eventdlg.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/dlgs/eventdlg.cpp' object='libstimfit_la-eventdlg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-eventdlg.lo `test -f './gui/dlgs/eventdlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/eventdlg.cpp libstimfit_la-fitseldlg.lo: ./gui/dlgs/fitseldlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-fitseldlg.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-fitseldlg.Tpo -c -o libstimfit_la-fitseldlg.lo `test -f './gui/dlgs/fitseldlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/fitseldlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-fitseldlg.Tpo $(DEPDIR)/libstimfit_la-fitseldlg.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/dlgs/fitseldlg.cpp' object='libstimfit_la-fitseldlg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-fitseldlg.lo `test -f './gui/dlgs/fitseldlg.cpp' || echo '$(srcdir)/'`./gui/dlgs/fitseldlg.cpp libstimfit_la-smalldlgs.lo: ./gui/dlgs/smalldlgs.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-smalldlgs.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-smalldlgs.Tpo -c -o libstimfit_la-smalldlgs.lo `test -f './gui/dlgs/smalldlgs.cpp' || echo '$(srcdir)/'`./gui/dlgs/smalldlgs.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-smalldlgs.Tpo $(DEPDIR)/libstimfit_la-smalldlgs.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/dlgs/smalldlgs.cpp' object='libstimfit_la-smalldlgs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-smalldlgs.lo `test -f './gui/dlgs/smalldlgs.cpp' || echo '$(srcdir)/'`./gui/dlgs/smalldlgs.cpp libstimfit_la-usrdlg.lo: ./gui/usrdlg/usrdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -MT libstimfit_la-usrdlg.lo -MD -MP -MF $(DEPDIR)/libstimfit_la-usrdlg.Tpo -c -o libstimfit_la-usrdlg.lo `test -f './gui/usrdlg/usrdlg.cpp' || echo '$(srcdir)/'`./gui/usrdlg/usrdlg.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstimfit_la-usrdlg.Tpo $(DEPDIR)/libstimfit_la-usrdlg.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./gui/usrdlg/usrdlg.cpp' object='libstimfit_la-usrdlg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstimfit_la_CPPFLAGS) $(CPPFLAGS) $(libstimfit_la_CXXFLAGS) $(CXXFLAGS) -c -o libstimfit_la-usrdlg.lo `test -f './gui/usrdlg/usrdlg.cpp' || echo '$(srcdir)/'`./gui/usrdlg/usrdlg.cpp mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs 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" 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 distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @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 check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am 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-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/libstimfit_la-app.Plo -rm -f ./$(DEPDIR)/libstimfit_la-childframe.Plo -rm -f ./$(DEPDIR)/libstimfit_la-convertdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-copygrid.Plo -rm -f ./$(DEPDIR)/libstimfit_la-cursorsdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-doc.Plo -rm -f ./$(DEPDIR)/libstimfit_la-eventdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-fitseldlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-graph.Plo -rm -f ./$(DEPDIR)/libstimfit_la-parentframe.Plo -rm -f ./$(DEPDIR)/libstimfit_la-printout.Plo -rm -f ./$(DEPDIR)/libstimfit_la-smalldlgs.Plo -rm -f ./$(DEPDIR)/libstimfit_la-stf.Plo -rm -f ./$(DEPDIR)/libstimfit_la-table.Plo -rm -f ./$(DEPDIR)/libstimfit_la-unopt.Plo -rm -f ./$(DEPDIR)/libstimfit_la-usrdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-view.Plo -rm -f ./$(DEPDIR)/libstimfit_la-zoom.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ 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-pkglibLTLIBRARIES 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 ./$(DEPDIR)/libstimfit_la-app.Plo -rm -f ./$(DEPDIR)/libstimfit_la-childframe.Plo -rm -f ./$(DEPDIR)/libstimfit_la-convertdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-copygrid.Plo -rm -f ./$(DEPDIR)/libstimfit_la-cursorsdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-doc.Plo -rm -f ./$(DEPDIR)/libstimfit_la-eventdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-fitseldlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-graph.Plo -rm -f ./$(DEPDIR)/libstimfit_la-parentframe.Plo -rm -f ./$(DEPDIR)/libstimfit_la-printout.Plo -rm -f ./$(DEPDIR)/libstimfit_la-smalldlgs.Plo -rm -f ./$(DEPDIR)/libstimfit_la-stf.Plo -rm -f ./$(DEPDIR)/libstimfit_la-table.Plo -rm -f ./$(DEPDIR)/libstimfit_la-unopt.Plo -rm -f ./$(DEPDIR)/libstimfit_la-usrdlg.Plo -rm -f ./$(DEPDIR)/libstimfit_la-view.Plo -rm -f ./$(DEPDIR)/libstimfit_la-zoom.Plo -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-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir 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-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip 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-pkglibLTLIBRARIES .PRECIOUS: Makefile # 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: stimfit-0.16.7/src/stimfit/gui/0000775000175000017500000000000014764352501012070 5stimfit-0.16.7/src/stimfit/gui/table.h0000775000175000017500000000501214750344764013260 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file table.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfTable. Derived from wxGridTableBase. */ #ifndef _TABLE_H #define _TABLE_H #include "../stf.h" /*! \addtogroup wxstf * @{ */ //! Adapts stfnum::Table to be used by wxStfGrid class wxStfTable : public wxGridTableBase { public: //! Constructor /*! \param table_ The associated stfnum::Table */ wxStfTable(const stfnum::Table& table_) : table(table_) {} //! Get the number of rows. /*! \return The number of rows. */ virtual int GetNumberRows() {return (int)table.nRows()+1;} //! Get the number of columns. /*! \return The number of columns. */ virtual int GetNumberCols() {return (int)table.nCols()+1;} //! Check whether a cell is empty. /*! \param row The row number of the cell. * \param col The column number of the cell. * \return true if the cell is empty, false otherwise. */ virtual bool IsEmptyCell(int row,int col); //! Retrieve a cell entry. /*! \param row The row number of the cell. * \param col The column number of the cell. * \return The cell entry as a string. */ virtual wxString GetValue( int row, int col ); //! Set a cell entry. /*! \param row The row number of the cell. * \param col The column number of the cell. * \param value The new cell entry. */ virtual void SetValue( int row, int col, const wxString& value ); //! Retrieve values from selected cells. /*! \param selection The selected cells. * \return The selection as a single string. */ wxString GetSelection(const wxGridCellCoordsArray& selection); private: stfnum::Table table; }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/graph.h0000775000175000017500000004017614750344764013304 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file graph.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfGraph. */ #ifndef _GRAPH_H #define _GRAPH_H /*! \addtogroup wxstf * @{ */ // forward declarations: class wxStfView; class wxStfDoc; class wxStfParentFrame; class wxStfCheckBox; class wxEnhMetaFile; #include "./zoom.h" enum plottype { active, reference, background }; //! Handles drawing of traces and keyboard or mouse input. /*! Derived from wxScrolledWindow, although no scrolling is implemented * at this time. All the trace scaling and drawing happens here. Mouse * and keyboard input is handled here as well. */ class StfDll wxStfGraph : public wxScrolledWindow { public: //! Constructor. /*! \param v is a pointer to the attached wxView. * \param frame is a pointer to the attached child frame. * \param pos and \param size indicate the initial position and size of this frame. * \param style is the window style. */ wxStfGraph(wxView *v, wxStfChildFrame *frame, const wxPoint& pos, const wxSize& size, long style); //! The central drawing function. Used for drawing to any output device, such as a printer or a screen. /*! \param dc is the device context used for drawing (can be a printer, a screen or a file). */ virtual void OnDraw(wxDC& dc); //! Copies the drawing to the clipboard as a windows metafile. /*! Metafiles are only implemented in Windows. Some applications * allow you to paste as an enhanced metafile (usually through * "Edit -> Paste special..."); choose this option for best results. */ void Snapshotwmf(); //! Handles mouse events. /*! The different possibilities (e.g. left or right click) split up * within this function. * \param event The mouse event. Contains information such as whether * the left or right button was clicked. */ void OnMouseEvent(wxMouseEvent& event); //! Handles keyboard input. /*! Key modifiers (e.g. Shift or Ctrl) ar handled within this function. * \param event The keyboard event. Contains information about the key * that was pressed. */ void OnKeyDown(wxKeyEvent& event); //! Change trace /*! Takes care of refreshing everything when a new trace is shown * \param trace Index of next trace to be displayed */ void ChangeTrace(std::size_t trace); //! Show and analyse next trace. /*! Called when either the "next trace"-button is clicked or the right * arrow cursor key is pressed. Wraps around when last trace is reached. */ void OnNext(); //! Show and analyse previous trace. /*! Called when either the "previous trace"-button is clicked or the left * arrow cursor key is pressed. Wraps around when first trace is reached. */ void OnPrevious(); //! Show and analyse last trace. /*! Called when the "last trace"-button is clicked. */ void OnLast(); //! Show and analyse first trace. /*! Called when the "first trace"-button is clicked. */ void OnFirst(); //! Moves the traces up by 20 px. /*! Called when either the up arrow cursor key is pressed * or the "Move traces up"-button is clicked. */ void OnUp(); //! Moves the traces down by 20 px. /*! Called when either the down arrow cursor key is pressed * or the "Move traces down"-button is clicked. */ void OnDown(); //! Moves the traces right by 20 px. /*! Called when either the right arrow cursor key and Ctrl are pressed * at the same time or the "Move traces right"-button is clicked. */ void OnRight(); //! Moves the traces left by 20 px. /*! Called when either the left arrow cursor key and Ctrl are pressed * at the same time or the "Move traces left"-button is clicked. */ void OnLeft(); //! Enlarges the x-scale by a factor of 2. /*! This is currently never called and might be removed in the future. */ void OnXenlhi(); //! Enlarges the x-scale by a factor of 1.1. /*! Called when either the "+" key and Ctrl are pressed * at the same time or the "Enlarge x-scale"-button is clicked. */ void OnXenllo(); //! Shrinks the x-scale by a factor of 1.1. /*! Called when either the "-" key and Ctrl are pressed * at the same time or the "Shrink x-scale"-button is clicked. */ void OnXshrinklo(); //! Shrinks the x-scale by a factor of 2. /*! This is currently never called and might be removed in the future. */ void OnXshrinkhi(); //! Enlarges the y-scale by a factor of 2. /*! This is currently never called and might be removed in the future. */ void OnYenlhi(); //! Enlarges the y-scale by a factor of 1.1. /*! Called when either the "+" key is pressed * or the "Enlarge x-scale"-button is clicked. */ void OnYenllo(); //! Shrinks the y-scale by a factor of 1.1. /*! Called when either the "-" key is pressed * or the "Shrink x-scale"-button is clicked. */ void OnYshrinklo(); //! Shrinks the y-scale by a factor of 2. /*! This is currently never called and might be removed in the future. */ void OnYshrinkhi(); //! Adjust y-positioning so that the baselines of channel 1 and 2 are at the same y-position. void Ch2base(); //! Adjust y-positioning so that channel 1 and 2 are at the same absolute y-position. void Ch2pos(); //! Adjust y-scale so that channel 1 and 2 have the same y-scale. void Ch2zoom(); //! Combines Ch2zoom() and Ch2base(). /*! This is a separate function so that the graph is not * refreshed between adjusting the y-scale and the baseline. */ void Ch2basezoom(); //! advance / decrement the active channel by one void ChanScroll(int direction); #if 0 //! Swaps the active and the reference channel. void SwapChannels(); #endif //! Fits the graph to the window. /*! Fits the graph to 100% of the width and 50% of the height * of the window and centers it. * \param refresh Set to true if the graph should be refreshed after fitting it to the window. */ void Fittowindow(bool refresh); //! Destroys all event check boxes void ClearEvents(); //! Set to true if the graph is drawn on a printer. /*! \param value boolean determining whether the graph is printed. */ void set_isPrinted(bool value); //! Sets the printing scale to the specified value. /*! \param value The new printing scale. */ void set_printScale(double value) {printScale=value;} //! Sets the size of the printout to the epcified rectangle. /*! \param value The new printing rectangle. */ void set_printRect(wxRect value) {printRect=value;} //! Set to true if the results table and the cursors should be printed. /*! \param value boolean determining whether everything should be printed. */ void set_noGimmicks(bool value) {no_gimmicks=value;} //! Prints every n-th point. /*! \param value Determines that every n-th point should be printed. */ void set_downsampling(int value) { downsampling = (value < 1 ? 1 : value); } //! Indicates whether everything (cursors, results table, etc.) is printed out. /*! \return true if everything is printed out. */ bool get_noGimmicks() const {return no_gimmicks;} //! Returns the y-position of a right click when in event-detection mode. /*! \return the index of the trace that the right-click position corresponds to. */ int get_eventPos() const { return eventPos; } //! Returns the current zoom struct. /*! \return the current zoom struct. */ // Zoom get_zoom() { return Doc()->at(Doc()->GetCurChIndex()).GetZoom(); } //! Sets the current zoom struct. /*! \param zoom_ The current zoom struct. */ // void set_zoom(const Zoom& zoom_) { Doc()->at(Doc()->GetCurChIndex()).GetZoomW()=zoom_; } //! The view attached to this wxStfGraph. wxStfView *view; //! Returns x value of the left screen border /*! \return x value of the left screen border */ double get_plot_xmin() const; //! Returns x value of the right screen border /*! \return x value of the right screen border */ double get_plot_xmax() const; //! Returns y value of the bottom screen border /*! \return y value of the bottom screen border */ double get_plot_ymin() const; //! Returns y value of the top screen border /*! \return y value of the top screen border */ double get_plot_ymax() const; //! Returns y value of the bottom screen border for the reference channel /*! \return y value of the bottom screen border for the reference channel */ double get_plot_y2min() const; //! Returns y value of the top screen border for the reference channel /*! \return y value of the top screen border for the reference channel */ double get_plot_y2max() const; private: wxStfChildFrame* pFrame; bool isZoomRect; //True if zoom window is set bool no_gimmicks; //True if no extra rulers/lines and circles shall be displayed bool isPrinted; //True when the View is drawn to a printer bool isLatex; bool firstPass; bool isSyncx; //Zoom struct // Zoom zoom; //Zoom struct to retain StdOut // Zoom zoomOld; //Zoom struct for PrintOut // Zoom zoomPrint; //Variables for the scaling of the print out wxRect printRect; //Printout graphic variables static const int boebbelStd=6;//Size of circles for display output int boebbel, //Size of circles (for peak, 2080rise time, etc.) boebbelPrint; //Size of circles for scalable print out double printScale; int printSizePen1,//Size of pens for scalable print out printSizePen2, printSizePen4, downsampling, eventPos; // ll... means lower limit, ul... means upper limit double llz_x, ulz_x, llz_y, ulz_y, llz_y2,ulz_y2; //Three lines of text containing the results wxString results1, results2, results3,results4, results5, results6; //Pens are declared here instead of locally to accelerate OnDraw() //Drawing (pen) styles for the different graphical standard output wxPen standardPen, standardPen2, standardPen3, scalePen, scalePen2, peakPen, peakLimitPen, basePen, baseLimitPen, decayLimitPen, ZoomRectPen, fitPen, fitSelectedPen, selectPen, averagePen, rtPen, hdPen, rdPen, slopePen, latencyPen, alignPen, measPen, eventPen, PSlopePen; /*CSH*/ //Drawing (pen) styles for the different graphical standard output wxPen standardPrintPen, standardPrintPen2, standardPrintPen3, scalePrintPen, scalePrintPen2,measPrintPen, peakPrintPen, peakLimitPrintPen, basePrintPen, baseLimitPrintPen, decayLimitPrintPen, fitPrintPen, fitSelectedPrintPen, selectPrintPen, averagePrintPen, rtPrintPen, hdPrintPen, rdPrintPen, slopePrintPen, resultsPrintPen, latencyPrintPen, PSlopePrintPen; wxBrush baseBrush, zeroBrush; wxPoint lastLDown; YZoom yzoombg; #if (__cplusplus < 201103) boost::shared_ptr m_zoomContext; boost::shared_ptr m_eventContext; #else std::shared_ptr m_zoomContext; std::shared_ptr m_eventContext; #endif void InitPlot(); void PlotSelected(wxDC& DC); void PlotAverage(wxDC& DC); void DrawZoomRect(wxDC& DC); void PlotGimmicks(wxDC& DC); void PlotEvents(wxDC& DC); void DrawCrosshair( wxDC& DC, const wxPen& pen, const wxPen& printPen, int crosshairSize, double xch, double ych); void PlotTrace( wxDC* pDC, const Vector_double& trace, plottype pt=active, int bgno=0 ); void DoPlot( wxDC* pDC, const Vector_double& trace, int start, int end, int step, plottype pt=active, int bgno=0 ); void PrintScale(wxRect& WindowRect); void PrintTrace( wxDC* pDC, const Vector_double& trace, plottype ptype=active); void DoPrint( wxDC* pDC, const Vector_double& trace, int start, int end, plottype ptype=active); void DrawCircle(wxDC* pDC, double x, double y, const wxPen& pen, const wxPen& printPen); void DrawVLine(wxDC* pDC, double x, const wxPen& pen, const wxPen& printPen); void DrawHLine(wxDC* pDC, double y, const wxPen& pen, const wxPen& printPen); void eventArrow(wxDC* pDC, int eventIndex); void DrawFit(wxDC* pDC); void PlotFit( wxDC* pDC, const stf::SectionPointer& Sec ); void DrawIntegral(wxDC* pDC); void CreateScale(wxDC* pDC); // Function receives the x-coordinate of a point and returns // its formatted value according to the current Zoom settings long xFormat(double); long xFormat(long); long xFormat(int); long xFormat(std::size_t); // The same for the y coordinates long yFormat(double); long yFormat(long); long yFormat(int); long yFormatD(double f) { return yFormat(f); } // The same for the y coordinates of the second channel long yFormat2(double); long yFormat2(long); long yFormat2(int); long yFormatD2(double f) { return yFormat2(f); } // The same for the y coordinates of the background channel long yFormatB(double); long yFormatB(long); long yFormatB(int); long yFormatDB(double f) { return yFormatB(f); } void FittorectY(YZoom& yzoom, const wxRect& rect, double min, double max, double screen_part); void FitToWindowSecCh(bool refresh); void LButtonDown(wxMouseEvent& event); void RButtonDown(wxMouseEvent& event); void LButtonUp(wxMouseEvent& event); // shorthand: wxStfDoc* Doc() { if (view != NULL) return view->Doc(); else return NULL; } wxStfDoc* DocC() const { if (view != NULL) return view->DocC(); else return NULL; } void ChangeXScale(double factor); void ChangeYScale(double factor); wxStfParentFrame* ParentFrame(); void OnZoomHV(wxCommandEvent& event); void OnZoomH(wxCommandEvent& event); void OnZoomV(wxCommandEvent& event); #if defined __WXMAC__ && !(wxCHECK_VERSION(2, 9, 0)) void OnPaint(wxPaintEvent &event); #endif long SPX() const { return DocC()->GetXZoom().startPosX; } long& SPXW() { return DocC()->GetXZoomW().startPosX; } long SPY() const { return DocC()->GetYZoom(DocC()->GetCurChIndex()).startPosY; } long& SPYW() { return DocC()->GetYZoomW(DocC()->GetCurChIndex()).startPosY; } long SPY2() const { return DocC()->GetYZoom(DocC()->GetSecChIndex()).startPosY; } long& SPY2W() { return DocC()->GetYZoomW(DocC()->GetSecChIndex()).startPosY; } double XZ() const { return DocC()->GetXZoom().xZoom; } double& XZW() { return DocC()->GetXZoomW().xZoom; } double YZ() const { return DocC()->GetYZoom(DocC()->GetCurChIndex()).yZoom; } double& YZW() { return DocC()->GetYZoomW(DocC()->GetCurChIndex()).yZoom; } double YZ2() const { return DocC()->GetYZoom(DocC()->GetSecChIndex()).yZoom; } double& YZ2W() { return DocC()->GetYZoomW(DocC()->GetSecChIndex()).yZoom; } DECLARE_EVENT_TABLE() }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/childframe.h0000775000175000017500000001621314750344764014274 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file childframe.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfChildFrame. */ #ifndef _CHILDFRAME_H #define _CHILDFRAME_H /*! \addtogroup wxstf * @{ */ #include #include #include #include #include "./../stf.h" // Define a new frame class wxStfGraph; class wxStfTable; class wxStfGrid; //! Default perspective string. /*! Can be loaded to restore the default AUI perspective. */ const wxString defaultPersp = wxT("layout2| \ name=Results;caption=Results;state=2044;dir=1;layer=0;row=0;pos=1;prop=167270; \ bestw=200;besth=184;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1| \ name=Selection;caption=Trace selection;state=2044;dir=1;layer=0;row=0;pos=0;prop=32730; \ bestw=128;besth=64;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1| \ name=Traces;caption=Traces;state=18428;dir=5;layer=0;row=0;pos=0;prop=100000; \ bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|"); #if wxUSE_DRAG_AND_DROP class wxStfFileDrop : public wxFileDropTarget { protected: virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames); }; #endif //! Provides the child frame for displaying documents on separate windows. /*! This class can only be used for MDI child frames. It is part of the document/view * framework supported by wxWidgets. */ class StfDll wxStfChildFrame : public wxStfChildType { DECLARE_CLASS( wxStfChildFrame ) public: //! Constructor /*! \param doc Pointer to the attached document. * \param view Pointer to the attached view. * \param parent Pointer to the parent frame. * \param id Window id. * \param title Window title string. * \param pos Initial window position. * \param size Initial window size. * \param style Window style. * \param name Name of this frame. */ wxStfChildFrame( wxDocument* doc, wxView* view, wxStfParentType* parent, wxWindowID id, const wxString& title, const wxPoint& pos = wxPoint(48,48), const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE, const wxString& name = wxT("frame") ); //! Destructor ~wxStfChildFrame(); //! Adds a table to the results notebook /*! \param table The table to be added. * \param caption The title of the new table in the notebook. */ void ShowTable(const stfnum::Table& table,const wxString& caption); //! Retrieves the current trace from the trace selection combo box. /*! \return The 0-based index of the currently selected trace. */ std::size_t GetCurTrace() const; //! Sets the current trace from the trace selection combo box. /*! \return The 0-based index of the trace to be selected. */ void SetCurTrace(std::size_t); //! Creates the trace selection menu. /*! \param value The number of traces. */ void CreateMenuTraces(std::size_t value); //! Creates the channel selection combo boxes. /*! \param channelNames The channel names for the combo box drop-down list. */ void CreateComboChannels( const wxArrayString& channelNames ); //! Refreshes the trace selection string. /*! \param value The number of selected traces. */ void SetSelected(std::size_t value); //! Sets the channels in the combo boxes. Checks and corrects equal channels in both boxes. /*! \param act Index of the active channel. * \param inact Index of the reference channel. */ void SetChannels( std::size_t act, std::size_t inact ); //! Updates the channels according to the current combo boy selection. void UpdateChannels( ); //! Updates the results table. /*! Called from wxStfApp::OnPeakcalcexecMsg() to update the results table. * Don't call this directly; use wxStfApp::OnPeakcalcexecMsg() instead. */ void UpdateResults(); //! Retrieve the wxAuiManager. /*! \return A pointer to the wxAuiManager. */ wxAuiManager* GetMgr() {return &m_mgr;} //! Retrieve the wxStfGrid that contains the results table. /*! \return A pointer to the grid. */ wxStfGrid* GetCopyGrid() {return m_table;} //! Write the current AUI perspective to the configuration void Saveperspective(); //! Load the saved AUI perspective from the configuration void Loadperspective(); //! Restore the default AUI perspective. void Restoreperspective(); //! Indicates whether all selected traces should be plotted. /*! \return true if they should be plotted, false otherwise. */ bool ShowSelected() const {return pShowSelected->IsChecked();} //! Indicates whether the second channel should be plotted. /*! \return true if it should be plotted, false otherwise. */ bool ShowSecond();// const {return pShowSecond->IsChecked();} //! Indicates whether all channels should be plotted. /*! \return true if they should be plotted, false otherwise. */ bool ShowAll() const {return pShowAll->IsChecked();} //! Activated the current graph void ActivateGraph(); void OnActivate(wxActivateEvent &event); //! Override default GetMenuBar /*! \return the menu bar if non-NULL; otherwise, the parent's menu bar */ virtual wxMenuBar *GetMenuBar() const; private: wxStfParentType* m_parent; wxAuiManager m_mgr; wxAuiNotebook* m_notebook; long m_notebook_style; wxPanel *m_traceCounter; wxPanel *m_channelCounter; wxStaticText *pSize; wxComboBox *pActChannel, *pInactChannel; wxSpinCtrl *trace_spinctrl; wxStfGrid* m_table; wxCheckBox *pZeroIndex, *pShowSelected, *pShowSecond, *pShowAll; std::size_t sizemax; wxAuiNotebook* CreateNotebook(); wxPanel* CreateTraceCounter(); wxPanel* CreateChannelCounter(); wxStfGrid* CreateTable(); void OnMenuHighlight(wxMenuEvent& event); void OnShowselected(wxCommandEvent& event); void OnZeroIndex(wxCommandEvent& event); void OnSpinCtrlTraces(wxSpinEvent& event); void OnComboActChannel(wxCommandEvent& event); void OnComboInactChannel(wxCommandEvent& event); DECLARE_EVENT_TABLE() }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/copygrid.cpp0000775000175000017500000003334314750344764014354 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // copygrid.cpp // Derived from wxGrid to allow copying to clipboard // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/grid.h" #include "wx/clipbrd.h" #include "./app.h" #include "./doc.h" #include "./parentframe.h" #include "./childframe.h" #include "./view.h" #include "./graph.h" #include "./copygrid.h" IMPLEMENT_CLASS(wxStfGrid, wxGrid) BEGIN_EVENT_TABLE(wxStfGrid, wxGrid) EVT_MENU(ID_COPYINTABLE,wxStfGrid::Copy) EVT_MENU(ID_VIEW_MEASURE,wxStfGrid::ViewCrosshair) EVT_MENU(ID_VIEW_BASELINE,wxStfGrid::ViewBaseline) EVT_MENU(ID_VIEW_BASESD,wxStfGrid::ViewBaseSD) EVT_MENU(ID_VIEW_THRESHOLD,wxStfGrid::ViewThreshold) EVT_MENU(ID_VIEW_PEAKZERO,wxStfGrid::ViewPeakzero) EVT_MENU(ID_VIEW_PEAKBASE,wxStfGrid::ViewPeakbase) EVT_MENU(ID_VIEW_PEAKTHRESHOLD,wxStfGrid::ViewPeakthreshold) EVT_MENU(ID_VIEW_RTLOHI,wxStfGrid::ViewRTLoHi) EVT_MENU(ID_VIEW_INNERRISETIME,wxStfGrid::ViewInnerRiseTime) EVT_MENU(ID_VIEW_OUTERRISETIME,wxStfGrid::ViewOuterRiseTime) EVT_MENU(ID_VIEW_T50,wxStfGrid::ViewT50) EVT_MENU(ID_VIEW_RD,wxStfGrid::ViewRD) EVT_MENU(ID_VIEW_SLOPERISE,wxStfGrid::ViewSloperise) EVT_MENU(ID_VIEW_SLOPEDECAY,wxStfGrid::ViewSlopedecay) EVT_MENU(ID_VIEW_LATENCY,wxStfGrid::ViewLatency) #ifdef WITH_PSLOPE EVT_MENU(ID_VIEW_PSLOPE,wxStfGrid::ViewPSlope) #endif EVT_MENU(ID_VIEW_CURSORS,wxStfGrid::ViewCursors) EVT_GRID_CELL_RIGHT_CLICK(wxStfGrid::OnRClick) EVT_GRID_LABEL_RIGHT_CLICK(wxStfGrid::OnLabelRClick) EVT_KEY_DOWN( wxStfGrid::OnKeyDown ) END_EVENT_TABLE() wxStfGrid::wxStfGrid( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxGrid(parent,id,pos,size,style,name), selection(wxT("")) { m_context.reset(new wxMenu()); m_context->Append(ID_COPYINTABLE, wxT("Copy selection")); m_labelContext.reset(new wxMenu()); m_labelContext->AppendCheckItem(ID_VIEW_MEASURE,wxT("Crosshair")); m_labelContext->AppendCheckItem(ID_VIEW_BASELINE,wxT("Baseline")); m_labelContext->AppendCheckItem(ID_VIEW_BASESD,wxT("Base SD")); m_labelContext->AppendCheckItem(ID_VIEW_THRESHOLD,wxT("Threshold")); m_labelContext->AppendCheckItem(ID_VIEW_PEAKZERO,wxT("Peak (from 0)")); m_labelContext->AppendCheckItem(ID_VIEW_PEAKBASE,wxT("Peak (from base)")); m_labelContext->AppendCheckItem(ID_VIEW_PEAKTHRESHOLD,wxT("Peak (from threshold)")); m_labelContext->AppendCheckItem(ID_VIEW_RTLOHI,wxT("RT (Lo-Hi%)")); m_labelContext->AppendCheckItem(ID_VIEW_INNERRISETIME,wxT("inner Rise Time (experimental)")); m_labelContext->AppendCheckItem(ID_VIEW_OUTERRISETIME,wxT("outer Rise Time (experimental)")); m_labelContext->AppendCheckItem(ID_VIEW_T50,wxT("t50")); m_labelContext->AppendCheckItem(ID_VIEW_RD,wxT("Rise/Decay")); m_labelContext->AppendCheckItem(ID_VIEW_SLOPERISE,wxT("Slope (rise)")); m_labelContext->AppendCheckItem(ID_VIEW_SLOPEDECAY,wxT("Slope (decay)")); m_labelContext->AppendCheckItem(ID_VIEW_LATENCY,wxT("Latency")); #ifdef WITH_PSLOPE m_labelContext->AppendCheckItem(ID_VIEW_PSLOPE,wxT("PSlope")); #endif m_labelContext->AppendSeparator(); m_labelContext->AppendCheckItem(ID_VIEW_CURSORS,wxT("Cursors")); } void wxStfGrid::Copy(wxCommandEvent& WXUNUSED(event)) { if (!IsSelection()) { wxGetApp().ErrorMsg( wxT("Select cells first") ); return; } // Write some text to the clipboard // These data objects are held by the clipboard, // so do not delete them in the app. selection.Clear(); bool newline=true; for (int nRow=0;nRowOpen()) { wxTheClipboard->SetData( new wxTextDataObject(selection) ); wxTheClipboard->Close(); } } void wxStfGrid::OnRClick(wxGridEvent& event) { event.Skip(); PopupMenu(m_context.get()); } void wxStfGrid::OnLabelRClick(wxGridEvent& event) { event.Skip(); // Update checkmarks: m_labelContext->Check(ID_VIEW_MEASURE,wxGetApp().GetActiveDoc()->GetViewCrosshair()); m_labelContext->Check(ID_VIEW_BASELINE,wxGetApp().GetActiveDoc()->GetViewBaseline()); m_labelContext->Check(ID_VIEW_BASESD,wxGetApp().GetActiveDoc()->GetViewBaseSD()); m_labelContext->Check(ID_VIEW_THRESHOLD,wxGetApp().GetActiveDoc()->GetViewThreshold()); m_labelContext->Check(ID_VIEW_PEAKZERO,wxGetApp().GetActiveDoc()->GetViewPeakZero()); m_labelContext->Check(ID_VIEW_PEAKBASE,wxGetApp().GetActiveDoc()->GetViewPeakBase()); m_labelContext->Check(ID_VIEW_PEAKTHRESHOLD,wxGetApp().GetActiveDoc()->GetViewPeakThreshold()); m_labelContext->Check(ID_VIEW_RTLOHI,wxGetApp().GetActiveDoc()->GetViewRTLoHi()); m_labelContext->Check(ID_VIEW_INNERRISETIME,wxGetApp().GetActiveDoc()->GetViewInnerRiseTime()); m_labelContext->Check(ID_VIEW_OUTERRISETIME,wxGetApp().GetActiveDoc()->GetViewOuterRiseTime()); m_labelContext->Check(ID_VIEW_T50,wxGetApp().GetActiveDoc()->GetViewT50()); m_labelContext->Check(ID_VIEW_RD,wxGetApp().GetActiveDoc()->GetViewRD()); m_labelContext->Check(ID_VIEW_SLOPERISE,wxGetApp().GetActiveDoc()->GetViewSlopeRise()); m_labelContext->Check(ID_VIEW_SLOPEDECAY,wxGetApp().GetActiveDoc()->GetViewSlopeDecay()); m_labelContext->Check(ID_VIEW_LATENCY,wxGetApp().GetActiveDoc()->GetViewLatency()); #ifdef WITH_PSLOPE m_labelContext->Check(ID_VIEW_PSLOPE,wxGetApp().GetActiveDoc()->GetViewPSlope()); #endif m_labelContext->Check(ID_VIEW_CURSORS,wxGetApp().GetActiveDoc()->GetViewCursors()); PopupMenu(m_labelContext.get()); } void wxStfGrid::OnKeyDown(wxKeyEvent& event) { // Handle CTRL + 'c' //event.Skip(); switch (event.GetKeyCode()) { case 67: case 99: { if (event.ControlDown()) { wxCommandEvent dEvent; Copy(dEvent); } break; } default: // pipe everything else to the graph if (wxGetApp().GetActiveView()!=NULL && wxGetApp().GetActiveView()->GetGraph()!=NULL) wxGetApp().GetActiveView()->GetGraph()->OnKeyDown(event); } } void wxStfGrid::ViewResults() { // Update checkmarks: m_labelContext->Check(ID_VIEW_MEASURE,wxGetApp().GetActiveDoc()->GetViewCrosshair()); m_labelContext->Check(ID_VIEW_BASELINE,wxGetApp().GetActiveDoc()->GetViewBaseline()); m_labelContext->Check(ID_VIEW_BASESD,wxGetApp().GetActiveDoc()->GetViewBaseSD()); m_labelContext->Check(ID_VIEW_THRESHOLD,wxGetApp().GetActiveDoc()->GetViewThreshold()); m_labelContext->Check(ID_VIEW_PEAKZERO,wxGetApp().GetActiveDoc()->GetViewPeakZero()); m_labelContext->Check(ID_VIEW_PEAKBASE,wxGetApp().GetActiveDoc()->GetViewPeakBase()); m_labelContext->Check(ID_VIEW_PEAKTHRESHOLD,wxGetApp().GetActiveDoc()->GetViewPeakThreshold()); m_labelContext->Check(ID_VIEW_RTLOHI,wxGetApp().GetActiveDoc()->GetViewRTLoHi()); m_labelContext->Check(ID_VIEW_INNERRISETIME,wxGetApp().GetActiveDoc()->GetViewInnerRiseTime()); m_labelContext->Check(ID_VIEW_OUTERRISETIME,wxGetApp().GetActiveDoc()->GetViewOuterRiseTime()); m_labelContext->Check(ID_VIEW_T50,wxGetApp().GetActiveDoc()->GetViewT50()); m_labelContext->Check(ID_VIEW_RD,wxGetApp().GetActiveDoc()->GetViewRD()); m_labelContext->Check(ID_VIEW_SLOPERISE,wxGetApp().GetActiveDoc()->GetViewSlopeRise()); m_labelContext->Check(ID_VIEW_SLOPEDECAY,wxGetApp().GetActiveDoc()->GetViewSlopeDecay()); m_labelContext->Check(ID_VIEW_LATENCY,wxGetApp().GetActiveDoc()->GetViewLatency()); #ifdef WITH_PSLOPE m_labelContext->Check(ID_VIEW_PSLOPE,wxGetApp().GetActiveDoc()->GetViewPSlope()); #endif m_labelContext->Check(ID_VIEW_CURSORS,wxGetApp().GetActiveDoc()->GetViewCursors()); PopupMenu(m_labelContext.get()); } void wxStfGrid::ViewCrosshair(wxCommandEvent& event) { event.Skip(); // Toggle on or off: wxGetApp().GetActiveDoc()->SetViewCrosshair(m_labelContext->IsChecked(ID_VIEW_MEASURE)); SetCheckmark(wxT("ViewCrosshair"),ID_VIEW_MEASURE); } void wxStfGrid::ViewBaseline(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewBaseline(m_labelContext->IsChecked(ID_VIEW_BASELINE)); SetCheckmark(wxT("ViewBaseline"),ID_VIEW_BASELINE); } void wxStfGrid::ViewBaseSD(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewBaseSD(m_labelContext->IsChecked(ID_VIEW_BASESD)); SetCheckmark(wxT("ViewBaseSD"),ID_VIEW_BASESD); } void wxStfGrid::ViewThreshold(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewThreshold(m_labelContext->IsChecked(ID_VIEW_THRESHOLD)); SetCheckmark(wxT("ViewThreshold"),ID_VIEW_THRESHOLD); } void wxStfGrid::ViewPeakzero(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewPeakZero(m_labelContext->IsChecked(ID_VIEW_PEAKZERO)); SetCheckmark(wxT("ViewPeakzero"),ID_VIEW_PEAKZERO); } void wxStfGrid::ViewPeakbase(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewPeakBase(m_labelContext->IsChecked(ID_VIEW_PEAKBASE)); SetCheckmark(wxT("ViewPeakbase"),ID_VIEW_PEAKBASE); } void wxStfGrid::ViewPeakthreshold(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewPeakThreshold(m_labelContext->IsChecked(ID_VIEW_PEAKTHRESHOLD)); SetCheckmark(wxT("ViewPeakthreshold"),ID_VIEW_PEAKTHRESHOLD); } void wxStfGrid::ViewRTLoHi(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewRTLoHi(m_labelContext->IsChecked(ID_VIEW_RTLOHI)); SetCheckmark(wxT("ViewRTLoHi"),ID_VIEW_RTLOHI); } void wxStfGrid::ViewInnerRiseTime(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewInnerRiseTime(m_labelContext->IsChecked(ID_VIEW_INNERRISETIME)); SetCheckmark(wxT("ViewInnerRiseTime"),ID_VIEW_INNERRISETIME); } void wxStfGrid::ViewOuterRiseTime(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewOuterRiseTime(m_labelContext->IsChecked(ID_VIEW_OUTERRISETIME)); SetCheckmark(wxT("ViewOuterRiseTime"),ID_VIEW_OUTERRISETIME); } void wxStfGrid::ViewT50(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewT50(m_labelContext->IsChecked(ID_VIEW_T50)); SetCheckmark(wxT("ViewT50"),ID_VIEW_T50); } void wxStfGrid::ViewRD(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewRD(m_labelContext->IsChecked(ID_VIEW_RD)); SetCheckmark(wxT("ViewRD"),ID_VIEW_RD); } void wxStfGrid::ViewSloperise(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewSlopeRise(m_labelContext->IsChecked(ID_VIEW_SLOPERISE)); SetCheckmark(wxT("ViewSloperise"),ID_VIEW_SLOPERISE); } void wxStfGrid::ViewSlopedecay(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewSlopeDecay(m_labelContext->IsChecked(ID_VIEW_SLOPEDECAY)); SetCheckmark(wxT("ViewSlopedecay"),ID_VIEW_SLOPEDECAY); } void wxStfGrid::ViewLatency(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewLatency(m_labelContext->IsChecked(ID_VIEW_LATENCY)); SetCheckmark(wxT("ViewLatency"),ID_VIEW_LATENCY); } #ifdef WITH_PSLOPE void wxStfGrid::ViewPSlope(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewPSlope(m_labelContext->IsChecked(ID_VIEW_PSLOPE)); SetCheckmark(wxT("ViewPSlope"),ID_VIEW_PSLOPE); } #endif void wxStfGrid::ViewCursors(wxCommandEvent& event) { event.Skip(); wxGetApp().GetActiveDoc()->SetViewCursors(m_labelContext->IsChecked(ID_VIEW_CURSORS)); SetCheckmark(wxT("ViewCursors"),ID_VIEW_CURSORS); } void wxStfGrid::SetCheckmark(const wxString& RegEntry, int id) { // Toggle on or off: if (m_labelContext->IsChecked(id)) { wxGetApp().wxWriteProfileInt(wxT("Settings"),RegEntry,1); } else { wxGetApp().wxWriteProfileInt(wxT("Settings"),RegEntry,0); } // Update table: wxStfChildFrame* pChild=(wxStfChildFrame*)(wxGetApp().GetMainFrame()->GetActiveChild()); pChild->UpdateResults(); } stimfit-0.16.7/src/stimfit/gui/dlgs/0000775000175000017500000000000014764352501013021 5stimfit-0.16.7/src/stimfit/gui/dlgs/smalldlgs.h0000775000175000017500000006022014750344764015106 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file smalldlgs.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares several small dialogs. */ #ifndef _SMALLDLGS_H #define _SMALLDLGS_H /*! \addtogroup wxstf * @{ */ #include #include #include #include "./../../stf.h" //! Dialog showing file information. class wxStfFileInfoDlg : public wxDialog { DECLARE_EVENT_TABLE() private: wxStdDialogButtonSizer* m_sdbSizer; public: //! Constructor /*! \param parent Pointer to parent window. * \param szGeneral General information. * \param szFile File variables information. * \param szSection Section variable information. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfFileInfoDlg( wxWindow* parent, const std::string& szGeneral, const std::string& szFile, const std::string& szSection, int id = wxID_ANY, wxString title = wxT("File information"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); }; //! Dialog for selecting channels class wxStfChannelSelDlg : public wxDialog { DECLARE_EVENT_TABLE() private: int m_selChannel1, m_selChannel2; wxStdDialogButtonSizer* m_sdbSizer; wxComboBox *m_comboBoxCh1,*m_comboBoxCh2; void OnComboCh1( wxCommandEvent& event ); void OnComboCh2( wxCommandEvent& event ); //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param channelNames A vector containing the channel names. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfChannelSelDlg( wxWindow* parent, const std::vector& channelNames= std::vector(0), int id = wxID_ANY, wxString title = wxT("Select channels"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); //! Get selection for channel 1 /*! \return The index of the first (active) channel */ int GetSelCh1() const {return m_selChannel1;} //! Get selection for channel 2 /*! \return The index of the second (reference) channel */ int GetSelCh2() const {return m_selChannel2;} }; //! Dialog for selecting alignment mode class wxStfAlignDlg : public wxDialog { DECLARE_EVENT_TABLE() private: int m_alignRise; bool m_useReference, m_hasReference; wxCheckBox* m_checkBox; wxRadioBox* m_radioBox; wxStdDialogButtonSizer* m_sdbSizer; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfAlignDlg( wxWindow* parent, bool hasReference, int id = wxID_ANY, wxString title = wxT("Alignment mode"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Indicates whether the average should be aligned to the steepest rise. /*! \return true if it should be aligned to the steepest rise, false if it should be * aligned to the peak. */ int AlignRise() const {return m_alignRise;} //! Indicates whether the reference channel should be used for alignment /*! \return true if the reference channel should be used, false if the active * channel should be used */ bool UseReference() const {return m_useReference;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; //! Dialog for selecting a filter function class wxStfFilterSelDlg : public wxDialog { DECLARE_EVENT_TABLE() private: int m_filterSelect; wxRadioBox* m_radioBox; wxStdDialogButtonSizer* m_sdbSizer; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfFilterSelDlg( wxWindow* parent, int id = wxID_ANY, wxString title = wxT("Filter function"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the selected filter function. /*! \return The index of the selected filter function. */ int GetFilterSelect() const {return m_filterSelect;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; //! Dialog for selecting a transform function class wxStfTransformDlg : public wxDialog { DECLARE_EVENT_TABLE() private: int m_fSelect; wxRadioBox* m_radioBox; wxStdDialogButtonSizer* m_sdbSizer; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfTransformDlg( wxWindow* parent, int id = wxID_ANY, wxString title = wxT("Choose function"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the selected transform function. /*! \return The index of the selected transform function. */ int GetFSelect() const {return m_fSelect;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; //! Dialog showing information about a fit. class wxStfFitInfoDlg : public wxDialog { DECLARE_EVENT_TABLE() private: wxStdDialogButtonSizer* m_sdbSizer; public: //! Constructor /*! \param parent Pointer to parent window. * \param info A string containing information about the fit. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfFitInfoDlg( wxWindow* parent, const wxString& info, int id = wxID_ANY, wxString title = wxT("Fit information"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); }; //! small struct representing a batch dialog option struct BatchOption { //! Default constructor BatchOption( ) : label( wxT("\0") ), selection(false), index(-1) {} //! Constructor //! \param lab Checkbox label //! \param sel Checkbox status //! \param id Index in dialog BatchOption(const wxString& lab, bool sel, int id) : label(lab), selection(sel), index(id) {} wxString label; //! Checkbox label bool selection; //! Checkbox status int index; //! Index within dialog }; //! Dialog for batch analysis settings. class wxStfBatchDlg : public wxDialog { DECLARE_EVENT_TABLE() private: std::vector batchOptions; wxCheckListBox* m_checkList; wxStdDialogButtonSizer* m_sdbSizer; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); BatchOption LookUp( int index ) const; enum { id_base=0, id_basesd, id_threshold, id_slopethresholdtime, id_peakzero, id_peakbase, id_peakthreshold, id_peaktime, id_rtLoHi, id_innerLoHi, id_outerLoHi, id_t50, id_t50se, id_slopes, id_slopetimes, id_latencies, id_fit, #ifdef WITH_PSLOPE id_pslopes, #endif id_crossings }; public: //! Constructor /*! \param parent Pointer to parent window. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfBatchDlg( wxWindow* parent, int id = wxID_ANY, wxString title = wxT("Choose values"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Indicates whether the baseline should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintBase() const {return LookUp(id_base).selection;} //! Indicates whether the standard deviation of the baseline should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintBaseSD() const {return LookUp(id_basesd).selection;} //! Indicates whether the threshold should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintThreshold() const {return LookUp(id_threshold).selection;} //! Indicates whether the time of slope threshold crossing should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintSlopeThresholdTime() const {return LookUp(id_slopethresholdtime).selection;} //! Indicates whether the peak (from 0) value should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintPeakZero() const {return LookUp(id_peakzero).selection;} //! Indicates whether the peak (from baseline) value should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintPeakBase() const {return LookUp(id_peakbase).selection;} //! Indicates whether the peak value (from threshold) should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintPeakThreshold() const {return LookUp(id_peakthreshold).selection;} //! Indicates whether the peak value (from threshold) should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintPeakTime() const {return LookUp(id_peaktime).selection;} //! Indicates whether the Lo-Hi% rise time should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintRTLoHi() const {return LookUp(id_rtLoHi).selection;} //! Indicates whether the Lo-Hi% inner rise time should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintInnerRTLoHi() const {return LookUp(id_innerLoHi).selection;} //! Indicates whether the Lo-Hi% inner rise time should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintOuterRTLoHi() const {return LookUp(id_outerLoHi).selection;} //! Indicates whether the half amplitude duration should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintT50() const {return LookUp(id_t50).selection;} //! Indicates whether the start and end time for half amplitude should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintT50SE() const {return LookUp(id_t50se).selection;} //! Indicates whether the maximal slopes should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintSlopes() const {return LookUp(id_slopes).selection;} //! Indicates whether the peak value (from threshold) should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintSlopeTimes() const {return LookUp(id_slopetimes).selection;} #ifdef WITH_PSLOPE //! Indicates whether the slopes should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintPSlopes() const {return LookUp(id_pslopes).selection;} #endif //! Indicates whether a threshold crossing should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintThr() const {return LookUp(id_crossings).selection;} //! Indicates whether the latency should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintLatencies() const {return LookUp(id_latencies).selection;} //! Indicates whether the fit results should be printed in the batch analysis table. /*! \return true if it should be printed, false otherwise. */ bool PrintFitResults() const {return LookUp(id_fit).selection;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; //! Dialog for setting printout options. class wxStfPreprintDlg : public wxDialog { DECLARE_EVENT_TABLE() private: bool m_gimmicks,m_isFile; int m_downsampling; wxStdDialogButtonSizer* m_sdbSizer; wxCheckBox* m_checkBox; wxTextCtrl* m_textCtrl; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param isFile Set this to true if something should be printed to a file. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfPreprintDlg( wxWindow* parent, bool isFile=false, int id = wxID_ANY, wxString title = wxT("Settings"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Indicates whether gimmicks (cursors, results table etc.) sould be printed. /*! \return true if gimmicks should be printed. */ bool GetGimmicks() const {return m_gimmicks;} //! Prints every n-th point. /*! \return If the return value \e n > 1, every n-th point will be printed. */ int GetDownSampling() const {return m_downsampling;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; //! Dialog for setting the parameters of a Gaussian function. class wxStfGaussianDlg : public wxDialog { DECLARE_EVENT_TABLE() private: double m_width; double m_center; double m_amp; wxStdDialogButtonSizer* m_sdbSizer; wxSlider* m_slider; wxTextCtrl *m_textCtrlCenter, *m_textCtrlWidth; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfGaussianDlg( wxWindow* parent, int id = wxID_ANY, wxString title = wxT("Settings for Gaussian function"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the width of the Gaussian. /*! \return The width of the Gaussian. */ double Width() const {return m_width;} //! Get the center of the Gaussian. /*! \return The center of the Gaussian. */ double Center() const {return m_center;} //! Get the amplitude of the Gaussian. /*! \return The amplitude of the Gaussian. */ double Amp() const {return m_amp;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; //! Dialog for text import filter settings. class wxStfTextImportDlg : public wxDialog { DECLARE_EVENT_TABLE() private: int m_hLines; bool m_toSection; bool m_firstIsTime; bool m_isSeries; int m_ncolumns; double m_sr; wxString m_yUnits; wxString m_yUnitsCh2; wxString m_xUnits; bool m_applyToAll; void disableSenseless(); wxStdDialogButtonSizer* m_sdbSizer; wxTextCtrl *m_textCtrlHLines, *m_textCtrlYUnits, *m_textCtrlYUnitsCh2, *m_textCtrlXUnits, *m_textCtrlSR; wxComboBox *m_comboBoxNcolumns,*m_comboBoxFirsttime,*m_comboBoxSecorch; wxCheckBox *m_checkBoxApplyToAll; void OnComboNcolumns( wxCommandEvent& event ); void OnComboFirsttime( wxCommandEvent& event ); void OnComboSecorch( wxCommandEvent& event ); //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param textPreview The preview text to be shown. * \param hLines_ The number of header lines that are initially set. * \param isSeries Set this to true for file series so that they can * be batch-opened. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfTextImportDlg( wxWindow* parent, const wxString& textPreview=wxT("\0"), int hLines_=1, bool isSeries=false, int id = wxID_ANY, wxString title = wxT("Text file import settings"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the number of header lines. /*! \return The number of header lines. */ int GetHLines() const {return m_hLines;} //! Indicates whether columns should be put into section or into channels. /*! \return true if they should be put into sections. */ bool ToSection() const {return m_toSection;} //! Indicates whether the first column contains time values. /*! \return true is the first column contains time values. */ bool FirstIsTime() const {return m_firstIsTime;} //! Get the number of columns. /*! \return The number of columns. */ int GetNColumns() const {return m_ncolumns;} //! Get the sampling rate. /*! \return The sampling rate. */ double GetSR() const {return m_sr;} //! Get the y units of the first channel. /*! \return The y units of the first channel. */ const wxString& GetYUnits() const {return m_yUnits;} //! Get the y units of the second channel. /*! \return The y units of the second channel. */ const wxString& GetYUnitsCh2() const {return m_yUnitsCh2;} //! Get the x units. /*! \return The x units. */ const wxString& GetXUnits() const {return m_xUnits;} //! Indicates whether the settings apply to all files in a series. /*! \return true if the settings apply to all files. */ bool ApplyToAll() const {return m_applyToAll;} //! Get the text import filter settings struct. /*! \return The stf::txtImportSettings struct. */ stfio::txtImportSettings GetTxtImport() const; //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; class wxDirPickerCtrl; class wxListCtrl; //! Dialog for re-ordering channels before saving to file class wxStfOrderChannelsDlg : public wxDialog { DECLARE_EVENT_TABLE() private: wxListCtrl* m_List; std::vector channelOrder; void OnUparrow( wxCommandEvent& event ); void OnDownarrow( wxCommandEvent& event ); void SwapItems(long itemId1, long itemId2); //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param channelNames A vector containing channel names. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfOrderChannelsDlg( wxWindow* parent, const std::vector& channelNames= std::vector(0), int id = wxID_ANY, wxString title = wxT("Re-order channels"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the new channel order. /*! \return A vector of newly ordered channel indices. */ std::vector GetChannelOrder() const {return channelOrder;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; /* @} */ #endif stimfit-0.16.7/src/stimfit/gui/dlgs/smalldlgs.cpp0000775000175000017500000011514314750344764015446 #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include #include "./../../res/arrow_down.xpm" #include "./../../res/arrow_up.xpm" #include "./../app.h" #include "./smalldlgs.h" BEGIN_EVENT_TABLE( wxStfFileInfoDlg, wxDialog ) END_EVENT_TABLE() wxStfFileInfoDlg::wxStfFileInfoDlg( wxWindow* parent, const std::string& szGeneral, const std::string& szFile, const std::string& szSection, int id, wxString title, wxPoint pos, wxSize size, int style ) : wxDialog( parent, id, title, pos, size, style ) { // this->SetSize(464,464); wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); wxString wxs = stf::std2wx(szGeneral); wxTextCtrl* textCtrlGeneral = new wxTextCtrl( this, wxID_ANY, wxs, wxDefaultPosition, wxSize(640,100), wxTE_MULTILINE | wxTE_DONTWRAP | wxTE_READONLY ); topSizer->Add( textCtrlGeneral, 0, wxALL, 5 ); wxBoxSizer* subSizer; subSizer = new wxBoxSizer( wxHORIZONTAL ); wxTextCtrl* textCtrlFile = new wxTextCtrl( this, wxID_ANY, stf::std2wx(szFile), wxDefaultPosition, wxSize(416,400), wxTE_MULTILINE | wxTE_DONTWRAP | wxTE_READONLY ); subSizer->Add( textCtrlFile, 0, wxALL, 5 ); wxTextCtrl* textCtrlSection = new wxTextCtrl( this, wxID_ANY, stf::std2wx(szSection), wxDefaultPosition, wxSize(214,400), wxTE_MULTILINE | wxTE_DONTWRAP | wxTE_READONLY ); subSizer->Add( textCtrlSection, 0, wxALL, 5 ); topSizer->Add( subSizer, 0, wxALIGN_CENTER, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } #define wxCOMBOCH1 1000 #define wxCOMBOCH2 1001 BEGIN_EVENT_TABLE( wxStfChannelSelDlg, wxDialog ) EVT_COMBOBOX( wxCOMBOCH1, wxStfChannelSelDlg::OnComboCh1 ) EVT_COMBOBOX( wxCOMBOCH2, wxStfChannelSelDlg::OnComboCh2 ) END_EVENT_TABLE() wxStfChannelSelDlg::wxStfChannelSelDlg( wxWindow* parent, const std::vector& channelNames, int id, wxString title, wxPoint pos, wxSize size, int style ) : wxDialog( parent, id, title, pos, size, style ), m_selChannel1(0), m_selChannel2(1) { wxArrayString strArray; strArray.Alloc(channelNames.size()); for (c_wxs_it cit = channelNames.begin(); cit != channelNames.end(); cit++) { strArray.Add( *cit ); } wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); // Add static boxes and combo boxes: wxStaticBoxSizer* ch1Sizer; ch1Sizer = new wxStaticBoxSizer( new wxStaticBox( this, -1, wxT("Select active channel:") ), wxVERTICAL ); m_comboBoxCh1 = new wxComboBox( this, wxCOMBOCH1, channelNames[0], wxDefaultPosition, wxSize(128,20), strArray, wxCB_DROPDOWN | wxCB_READONLY ); ch1Sizer->Add( m_comboBoxCh1, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); topSizer->Add( ch1Sizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5); wxStaticBoxSizer* ch2Sizer; ch2Sizer = new wxStaticBoxSizer( new wxStaticBox( this, -1, wxT("Select second channel:") ), wxVERTICAL ); m_comboBoxCh2 = new wxComboBox( this, wxCOMBOCH2, channelNames[1], wxDefaultPosition, wxSize(128,20), strArray, wxCB_DROPDOWN | wxCB_READONLY ); ch2Sizer->Add( m_comboBoxCh2, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); topSizer->Add( ch2Sizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); m_comboBoxCh1->SetSelection(0); m_comboBoxCh2->SetSelection(1); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfChannelSelDlg::OnComboCh1( wxCommandEvent& event ) { event.Skip(); if (m_comboBoxCh1->GetCurrentSelection()==m_comboBoxCh2->GetCurrentSelection()) { // correct selection: for (int n_c=0;n_c<(int)m_comboBoxCh1->GetCount();++n_c) { if (n_c!=m_comboBoxCh1->GetCurrentSelection()) { m_comboBoxCh2->SetSelection(n_c); break; } } } } void wxStfChannelSelDlg::OnComboCh2( wxCommandEvent& event ) { event.Skip(); if (m_comboBoxCh2->GetCurrentSelection()==m_comboBoxCh1->GetCurrentSelection()) { // correct selection: for (int n_c=0;n_c<(int)m_comboBoxCh2->GetCount();++n_c) { if (n_c!=m_comboBoxCh2->GetCurrentSelection()) { m_comboBoxCh1->SetSelection(n_c); break; } } } } void wxStfChannelSelDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxGetApp().ErrorMsg(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfChannelSelDlg::OnOK() { m_selChannel1 = m_comboBoxCh1->GetCurrentSelection(); m_selChannel2 = m_comboBoxCh2->GetCurrentSelection(); return true; } BEGIN_EVENT_TABLE( wxStfAlignDlg, wxDialog ) END_EVENT_TABLE() wxStfAlignDlg::wxStfAlignDlg(wxWindow* parent, bool hasReference, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), m_alignRise(0), m_useReference(true), m_hasReference(hasReference) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); if (m_hasReference) { m_checkBox=new wxCheckBox( this, wxID_ANY, wxT("Use reference channel"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBox->SetValue(true); topSizer->Add( m_checkBox, 0, wxALIGN_LEFT | wxALL, 5 ); } wxString m_radioBoxChoices[] = { wxT("peak"), wxT("steepest slope during rise"), wxT("half amplitude"), wxT("onset") }; int m_radioBoxNChoices = sizeof( m_radioBoxChoices ) / sizeof( wxString ); m_radioBox = new wxRadioBox( this, wxID_ANY, wxT("Alignment point"), wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices, m_radioBoxChoices, m_radioBoxNChoices, wxRA_SPECIFY_ROWS); topSizer->Add( m_radioBox, 0, wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfAlignDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfAlignDlg::OnOK() { m_alignRise = m_radioBox->GetSelection(); if (m_hasReference) { m_useReference = m_checkBox->IsChecked(); } else { m_useReference = false; } return true; } BEGIN_EVENT_TABLE( wxStfFilterSelDlg, wxDialog ) END_EVENT_TABLE() wxStfFilterSelDlg::wxStfFilterSelDlg(wxWindow* parent, int id, wxString title, wxPoint pos, wxSize size,int style) : wxDialog( parent, id, title, pos, size, style ), m_filterSelect(0) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); wxString m_radioBoxChoices[] = { wxT("Notch (inverted Gaussian)"), wxT("Low pass (4th-order Bessel)"), wxT("Low pass (Gaussian)") }; int m_radioBoxNChoices = sizeof( m_radioBoxChoices ) / sizeof( wxString ); m_radioBox = new wxRadioBox( this, wxID_ANY, wxT("Select filter function"), wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices, m_radioBoxChoices, 3, wxRA_SPECIFY_ROWS ); topSizer->Add( m_radioBox, 0, wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfFilterSelDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfFilterSelDlg::OnOK() { m_filterSelect=m_radioBox->GetSelection()+1; return true; } BEGIN_EVENT_TABLE( wxStfTransformDlg, wxDialog ) END_EVENT_TABLE() wxStfTransformDlg::wxStfTransformDlg(wxWindow* parent, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), m_fSelect(0) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); wxString m_radioBoxChoices[] = { wxT(" ln(x) ") }; int m_radioBoxNChoices = sizeof( m_radioBoxChoices ) / sizeof( wxString ); m_radioBox = new wxRadioBox( this, wxID_ANY, wxT("Select function"), wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices, m_radioBoxChoices, 0, wxRA_SPECIFY_ROWS ); topSizer->Add( m_radioBox, 0, wxALIGN_CENTER | wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfTransformDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfTransformDlg::OnOK() { m_fSelect=m_radioBox->GetSelection()+1; return true; } BEGIN_EVENT_TABLE( wxStfFitInfoDlg, wxDialog ) END_EVENT_TABLE() wxStfFitInfoDlg::wxStfFitInfoDlg(wxWindow* parent, const wxString& info, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); wxTextCtrl* m_textCtrl; m_textCtrl=new wxTextCtrl( this, wxID_ANY, info, wxDefaultPosition, wxSize(320,120), wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP ); topSizer->Add( m_textCtrl, 0, wxALIGN_CENTER | wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } BEGIN_EVENT_TABLE( wxStfBatchDlg, wxDialog ) END_EVENT_TABLE() wxStfBatchDlg::wxStfBatchDlg(wxWindow* parent, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, wxT("Choose values"), pos, size, style ), batchOptions( 0 ) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); batchOptions.push_back( BatchOption( wxT("Base"), true, id_base ) ); batchOptions.push_back( BatchOption( wxT("Base SD"), false, id_basesd ) ); batchOptions.push_back( BatchOption( wxT("Threshold"), true, id_threshold ) ); batchOptions.push_back( BatchOption( wxT("time of slope threshold crossing"), false, id_slopethresholdtime ) ); batchOptions.push_back( BatchOption( wxT("Peak (from 0)"), true, id_peakzero ) ); batchOptions.push_back( BatchOption( wxT("Peak (from base)"), true, id_peakbase ) ); batchOptions.push_back( BatchOption( wxT("Peak (from threshold)"), true, id_peakthreshold ) ); batchOptions.push_back( BatchOption( wxT("Peak time"), true, id_peaktime ) ); batchOptions.push_back( BatchOption( wxT("Lo-Hi% risetime"), false, id_rtLoHi ) ); batchOptions.push_back( BatchOption( wxT("inner risetime"), false, id_innerLoHi ) ); batchOptions.push_back( BatchOption( wxT("outer risetime"), false, id_outerLoHi ) ); batchOptions.push_back( BatchOption( wxT("Half amplitude duration"), false, id_t50 ) ); batchOptions.push_back( BatchOption( wxT("start and end time of half amplitude"), false, id_t50se ) ); batchOptions.push_back( BatchOption( wxT("Max slopes"), false, id_slopes ) ); batchOptions.push_back( BatchOption( wxT("Max slope times"), false, id_slopetimes ) ); batchOptions.push_back( BatchOption( wxT("Latencies"), false, id_latencies ) ); batchOptions.push_back( BatchOption( wxT("Fit results"), false, id_fit ) ); #ifdef WITH_PSLOPE batchOptions.push_back( BatchOption( wxT("pSlope"), false, id_pslopes ) ); #endif batchOptions.push_back( BatchOption( wxT("Threshold crossings"), false, id_crossings ) ); std::vector::const_iterator bo_it; std::vector checkListChoices(batchOptions.size()); for (bo_it = batchOptions.begin(); bo_it != batchOptions.end(); ++bo_it) { try { checkListChoices.at(bo_it->index) = bo_it->label; } catch (const std::out_of_range& e) { wxString errorMsg( wxT("Error while populating checkbox list:\n") ); errorMsg += wxString(e.what(), wxConvLocal); wxGetApp().ExceptMsg( errorMsg ); } }; m_checkList = new wxCheckListBox( this, wxID_ANY, wxDefaultPosition, wxSize(280,350), checkListChoices.size(), &checkListChoices[0], 0 ); for (bo_it = batchOptions.begin(); bo_it != batchOptions.end(); ++bo_it) { m_checkList->Check(bo_it->index, wxGetApp().wxGetProfileInt( wxT("Batch Dialog"), bo_it->label, bo_it->selection) ); } topSizer->Add( m_checkList, 0, wxALIGN_CENTER | wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfBatchDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfBatchDlg::OnOK() { std::vector::iterator bo_it; for (bo_it = batchOptions.begin(); bo_it != batchOptions.end(); ++bo_it) { bo_it->selection = m_checkList->IsChecked( bo_it->index ); wxGetApp().wxWriteProfileInt( wxT("Batch Dialog"), bo_it->label, bo_it->selection ); } return true; } BatchOption wxStfBatchDlg::LookUp( int index ) const { std::vector::const_iterator bo_it; for (bo_it = batchOptions.begin(); bo_it != batchOptions.end(); ++bo_it) { if ( bo_it->index == index ) { return *bo_it; } } return BatchOption( wxT(""), false, -1 ); } BEGIN_EVENT_TABLE( wxStfPreprintDlg, wxDialog ) END_EVENT_TABLE() wxStfPreprintDlg::wxStfPreprintDlg(wxWindow* parent, bool isFile_, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), m_gimmicks(true), m_isFile(isFile_), m_downsampling(1) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); if (!m_isFile) { m_checkBox=new wxCheckBox( this, wxID_ANY, wxT("Print gimmicks (Cursors etc.)"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBox->SetValue(true); topSizer->Add( m_checkBox, 0, wxALIGN_LEFT | wxALL, 5 ); } wxFlexGridSizer* gridSizer; gridSizer=new wxFlexGridSizer(1,2,0,0); wxStaticText* staticText; staticText=new wxStaticText( this, wxID_ANY, wxT("Print every n-th point:"), wxDefaultPosition, wxSize(112,20), 0 ); gridSizer->Add( staticText, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString def; def << 1; m_textCtrl=new wxTextCtrl( this, wxID_ANY, def, wxDefaultPosition, wxSize(32,20), wxTE_RIGHT ); gridSizer->Add( m_textCtrl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); topSizer->Add( gridSizer, 0, wxALIGN_CENTER | wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfPreprintDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfPreprintDlg::OnOK() { if (!m_isFile) { m_gimmicks=m_checkBox->IsChecked(); } else { m_gimmicks=false; } // Read entry to string: wxString entry = m_textCtrl->GetValue(); long tempLong; entry.ToLong( &tempLong ); m_downsampling = (int) tempLong; return true; } BEGIN_EVENT_TABLE( wxStfGaussianDlg, wxDialog ) END_EVENT_TABLE() wxStfGaussianDlg::wxStfGaussianDlg(wxWindow* parent, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), m_width(0.001), m_center(0.05), m_amp(1.0) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); wxFlexGridSizer *gridSizer; gridSizer=new wxFlexGridSizer(3,2,0,0); wxStaticText* staticTextAmp; staticTextAmp=new wxStaticText( this, wxID_ANY, wxT("Amplitude:"), wxDefaultPosition, wxDefaultSize, 0); gridSizer->Add( staticTextAmp, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); m_slider = new wxSlider( this, wxID_ANY, 100, 0, 100, wxDefaultPosition, wxSize(128,-1), wxSL_HORIZONTAL ); gridSizer->Add( m_slider, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxStaticText* staticTextCenter; staticTextCenter=new wxStaticText( this, wxID_ANY, wxT("Center (kHz):"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextCenter, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString def; def << m_center; m_textCtrlCenter=new wxTextCtrl( this, wxID_ANY, def, wxDefaultPosition, wxSize(40,20), wxTE_RIGHT ); gridSizer->Add( m_textCtrlCenter, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxStaticText* staticTextWidth; staticTextWidth=new wxStaticText( this, wxID_ANY, wxT("Width (kHz):"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextWidth, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString def2; def2 << m_width; m_textCtrlWidth=new wxTextCtrl( this, wxID_ANY, def2, wxDefaultPosition, wxSize(40,20), wxTE_RIGHT ); gridSizer->Add( m_textCtrlWidth, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); topSizer->Add( gridSizer, 0, wxALIGN_CENTER | wxALL, 5 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfGaussianDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfGaussianDlg::OnOK() { m_amp=m_slider->GetValue() / 100.0; // Read entry to string: wxString entryCenter = m_textCtrlCenter->GetValue(); entryCenter.ToDouble( &m_center ); wxString entryWidth = m_textCtrlWidth->GetValue(); entryWidth.ToDouble( &m_width ); return true; } #define wxCOMBONCOLUMNS 1000 #define wxCOMBOFIRSTTIME 1001 #define wxCOMBOSECORCH 1002 BEGIN_EVENT_TABLE( wxStfTextImportDlg, wxDialog ) EVT_COMBOBOX( wxCOMBONCOLUMNS, wxStfTextImportDlg::OnComboNcolumns ) EVT_COMBOBOX( wxCOMBOFIRSTTIME, wxStfTextImportDlg::OnComboFirsttime ) EVT_COMBOBOX( wxCOMBOSECORCH, wxStfTextImportDlg::OnComboSecorch ) END_EVENT_TABLE() wxStfTextImportDlg::wxStfTextImportDlg(wxWindow* parent, const wxString& textPreview, int hLines_, bool isSeries, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), m_hLines(hLines_),m_toSection(true), m_firstIsTime(true),m_isSeries(isSeries),m_ncolumns(2), m_sr(20),m_yUnits(wxT("mV")),m_yUnitsCh2(wxT("pA")),m_xUnits(wxT("ms")) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); wxFlexGridSizer *gridSizer; gridSizer=new wxFlexGridSizer(4,4,0,10); // Header lines------------------------------------------------------ wxStaticText* staticTextHLines; staticTextHLines=new wxStaticText( this, wxID_ANY, wxT("Header lines to skip:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextHLines, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strHLines; strHLines << m_hLines; m_textCtrlHLines=new wxTextCtrl( this, wxID_ANY, strHLines, wxDefaultPosition, wxSize(64,20), wxTE_RIGHT ); gridSizer->Add( m_textCtrlHLines, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Number of columns------------------------------------------------- wxStaticText* staticTextNcolumns; staticTextNcolumns=new wxStaticText( this, wxID_ANY, wxT("Number of columns:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextNcolumns, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString szNcolumns[] = { wxT("1"), wxT("2"), wxT("3") }; int szNcolumnsSize = sizeof( szNcolumns ) / sizeof( wxString ); m_comboBoxNcolumns = new wxComboBox( this, wxCOMBONCOLUMNS, wxT("1"), wxDefaultPosition, wxSize(64,20), szNcolumnsSize, szNcolumns, wxCB_DROPDOWN | wxCB_READONLY ); gridSizer->Add( m_comboBoxNcolumns, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Type of first column--------------------------------------------- wxStaticText* staticTextFirsttime; staticTextFirsttime=new wxStaticText( this, wxID_ANY, wxT("First column is time:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextFirsttime, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString szFirsttime[] = { wxT("Yes"), wxT("No"), }; int szFirsttimeSize = sizeof( szFirsttime ) / sizeof( wxString ); m_comboBoxFirsttime = new wxComboBox( this, wxCOMBOFIRSTTIME, wxT("Yes"), wxDefaultPosition, wxSize(64,20), szFirsttimeSize, szFirsttime, wxCB_DROPDOWN | wxCB_READONLY ); gridSizer->Add( m_comboBoxFirsttime, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Read into sections or channels----------------------------------- wxStaticText* staticTextSecorch; staticTextSecorch=new wxStaticText( this, wxID_ANY, wxT("Read columns into:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextSecorch, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString szSecorch[] = { wxT("Sections"), wxT("Channels"), }; int szSecorchSize = sizeof( szSecorch ) / sizeof( wxString ); m_comboBoxSecorch = new wxComboBox( this, wxCOMBOSECORCH, wxT("Sections"), wxDefaultPosition, wxSize(64,20), szSecorchSize, szSecorch, wxCB_DROPDOWN | wxCB_READONLY ); gridSizer->Add( m_comboBoxSecorch, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Y units----------------------------------------------------------- wxStaticText* staticTextYUnits; staticTextYUnits=new wxStaticText( this, wxID_ANY, wxT("Y units:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextYUnits, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); m_textCtrlYUnits=new wxTextCtrl( this, wxID_ANY, m_yUnits, wxDefaultPosition, wxSize(64,20), wxTE_LEFT ); gridSizer->Add( m_textCtrlYUnits, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Y units of channel 2---------------------------------------------- wxStaticText* staticTextYUnitsCh2; staticTextYUnitsCh2=new wxStaticText( this, wxID_ANY, wxT("Y units, channel 2:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextYUnitsCh2, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); m_textCtrlYUnitsCh2=new wxTextCtrl( this, wxID_ANY, m_yUnitsCh2, wxDefaultPosition, wxSize(64,20), wxTE_LEFT ); gridSizer->Add( m_textCtrlYUnitsCh2, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // X units----------------------------------------------------------- wxStaticText* staticTextXUnits; staticTextXUnits=new wxStaticText( this, wxID_ANY, wxT("X units:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextXUnits, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); m_textCtrlXUnits=new wxTextCtrl( this, wxID_ANY, m_xUnits, wxDefaultPosition, wxSize(64,20), wxTE_LEFT ); gridSizer->Add( m_textCtrlXUnits, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Sampling rate----------------------------------------------------- wxStaticText* staticTextSR; staticTextSR=new wxStaticText( this, wxID_ANY, wxT("Sampling rate (kHz):"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextSR, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strSR; strSR << m_sr; m_textCtrlSR=new wxTextCtrl( this, wxID_ANY, strSR, wxDefaultPosition, wxSize(64,20), wxTE_RIGHT ); gridSizer->Add( m_textCtrlSR, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); topSizer->Add( gridSizer, 0, wxALIGN_CENTER, 5 ); // Check box for batch import---------------------------------------- if (m_isSeries) { m_checkBoxApplyToAll=new wxCheckBox( this, wxID_ANY, wxT("Apply settings to all files in series"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBoxApplyToAll->SetValue(false); topSizer->Add( m_checkBoxApplyToAll, 0, wxALIGN_CENTER | wxALL, 5 ); } // OK / Cancel buttons----------------------------------------------- m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); // Text preview------------------------------------------------------ wxTextCtrl* previewCtrl; previewCtrl=new wxTextCtrl( this, wxID_ANY, textPreview, wxDefaultPosition, wxSize(368,160), wxTE_MULTILINE | wxTE_DONTWRAP | wxTE_READONLY ); topSizer->Add( previewCtrl, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); disableSenseless(); this->Layout(); } void wxStfTextImportDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfTextImportDlg::OnOK() { long tempLong; m_textCtrlHLines->GetValue().ToLong( &tempLong ); m_hLines = tempLong; m_toSection=(m_comboBoxSecorch->GetCurrentSelection()==0); m_firstIsTime=(m_comboBoxFirsttime->GetCurrentSelection()==0); m_ncolumns=m_comboBoxNcolumns->GetCurrentSelection()+1; m_yUnits = m_textCtrlYUnits->GetValue(); m_yUnitsCh2 = m_textCtrlYUnitsCh2->GetValue(); m_xUnits = m_textCtrlXUnits->GetValue(); double tempDouble; m_textCtrlSR->GetValue().ToDouble ( &tempDouble ); m_sr = tempDouble; if (m_isSeries) { m_applyToAll=m_checkBoxApplyToAll->IsChecked(); } return true; } stfio::txtImportSettings wxStfTextImportDlg::GetTxtImport() const { stfio::txtImportSettings retTxtImport; retTxtImport.firstIsTime=m_firstIsTime; retTxtImport.hLines=m_hLines; retTxtImport.ncolumns=m_ncolumns; retTxtImport.sr=m_sr; retTxtImport.toSection=m_toSection; retTxtImport.xUnits = stf::wx2std(m_xUnits); retTxtImport.yUnits = stf::wx2std(m_yUnits); retTxtImport.yUnitsCh2 = stf::wx2std(m_yUnitsCh2); return retTxtImport; } void wxStfTextImportDlg::disableSenseless() { // if there is only one column, it can't be time: if (m_comboBoxNcolumns->GetCurrentSelection()==0) { m_firstIsTime=false; m_comboBoxFirsttime->SetSelection(1); m_comboBoxFirsttime->Enable(false); } else { m_comboBoxFirsttime->Enable(); } // if the first column is time, disable manual sampling rate settings: if (m_comboBoxFirsttime->GetCurrentSelection()==0) { m_textCtrlSR->Enable(false); } else { m_textCtrlSR->Enable(); } // if there is only one data column, // it doesn't make sense to choose between channels and sections int temp_nColumns=m_comboBoxNcolumns->GetCurrentSelection()+1; int temp_nTime=(m_comboBoxFirsttime->GetCurrentSelection()==0)? 1:0; int nData=temp_nColumns-temp_nTime; if (nData<2) { m_comboBoxSecorch->Enable(false); } else { m_comboBoxSecorch->Enable(); } // Enable units of second channel only if // there is a second channel at all: if (nData>1 && m_comboBoxSecorch->GetCurrentSelection()==1) { m_textCtrlYUnitsCh2->Enable(); } else { m_textCtrlYUnitsCh2->Enable(false); } } void wxStfTextImportDlg::OnComboNcolumns( wxCommandEvent& event ) { event.Skip(); m_ncolumns=m_comboBoxNcolumns->GetCurrentSelection()+1; disableSenseless(); } void wxStfTextImportDlg::OnComboFirsttime( wxCommandEvent& event ) { event.Skip(); m_firstIsTime=(m_comboBoxFirsttime->GetCurrentSelection()==0); disableSenseless(); } void wxStfTextImportDlg::OnComboSecorch( wxCommandEvent& event ) { event.Skip(); m_toSection=(m_comboBoxSecorch->GetCurrentSelection()==0); disableSenseless(); } enum { wxID_BUP, wxID_BDOWN, wxID_LISTCH }; BEGIN_EVENT_TABLE( wxStfOrderChannelsDlg, wxDialog ) EVT_BUTTON( wxID_BUP, wxStfOrderChannelsDlg::OnUparrow ) EVT_BUTTON( wxID_BDOWN, wxStfOrderChannelsDlg::OnDownarrow ) END_EVENT_TABLE() wxStfOrderChannelsDlg::wxStfOrderChannelsDlg(wxWindow* parent, const std::vector& channelNames, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), channelOrder(channelNames.size()) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); // 2-column sizer for funcs (left) and settings (right) wxFlexGridSizer* mainGrid; mainGrid=new wxFlexGridSizer(1,2,0,5); m_List = new wxListCtrl( this, wxID_LISTCH, wxDefaultPosition, wxSize(240,(int)channelNames.size()*24), wxLC_LIST | wxLC_SINGLE_SEL ); for (long n_c=0;n_c<(long)channelNames.size();++n_c) { m_List->InsertItem( n_c, channelNames[n_c] ); channelOrder[n_c]=n_c; } mainGrid->Add( m_List, 0, wxALIGN_CENTER_HORIZONTAL, 2 ); // Add up and down arrows: wxBoxSizer* arrowSizer; arrowSizer = new wxBoxSizer( wxVERTICAL ); wxBitmapButton *bUp, *bDown; bUp = new wxBitmapButton(this,wxID_BUP,arrow_up); bDown = new wxBitmapButton(this,wxID_BDOWN,arrow_down); arrowSizer->Add(bUp, 0, wxALIGN_CENTER | wxALL, 2 ); arrowSizer->Add(bDown, 0, wxALIGN_CENTER | wxALL, 2 ); mainGrid->Add( arrowSizer, 0, wxALIGN_CENTER_HORIZONTAL, 2 ); topSizer->Add( mainGrid, 0, wxALIGN_CENTER_HORIZONTAL| wxALL, 5 ); wxStdDialogButtonSizer* sdbSizer = new wxStdDialogButtonSizer(); sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); sdbSizer->Realize(); topSizer->Add( sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfOrderChannelsDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxGetApp().ErrorMsg(wxT("Please select a valid function")); return; } } wxDialog::EndModal(retCode); } bool wxStfOrderChannelsDlg::OnOK() { return true; } void wxStfOrderChannelsDlg::OnUparrow( wxCommandEvent& event ) { event.Skip(); // Get currently selected item in list: if (m_List->GetSelectedItemCount()>0) { // Get first selected item: long item = -1; item=m_List->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED); // Return if this is already the topmost item: if (item <= 0) return; // Otherwise, move this item up by swapping with the previous item: SwapItems(item-1,item); // Focus on list: m_List->SetFocus(); } } void wxStfOrderChannelsDlg::OnDownarrow( wxCommandEvent& event ) { event.Skip(); // Get currently selected item in list: if (m_List->GetSelectedItemCount()>0) { // Get first selected item: long item = -1; item=m_List->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED); // Return if this is the last item: if (item >= m_List->GetItemCount()-1) return; // Otherwise, move this item down by swapping with the next item: SwapItems(item,item+1); // Focus on list: m_List->SetFocus(); } } void wxStfOrderChannelsDlg::SwapItems(long itemId1, long itemId2) { // Store the first item: wxString labelFirst=m_List->GetItemText(itemId1); int orderFirst=channelOrder[itemId1]; // Change first item label: m_List->SetItemText(itemId1,m_List->GetItemText(itemId2)); // Change second item label: m_List->SetItemText(itemId2,labelFirst); // Update channel order: channelOrder[itemId1]=channelOrder[itemId2]; channelOrder[itemId2]=orderFirst; } stimfit-0.16.7/src/stimfit/gui/dlgs/convertdlg.h0000664000175000017500000000635614750344764015302 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file convertdlg.h * \author Christoph Schmidt-Hieber * \date 2015-05-04 * \brief Batch conversion of files */ #ifndef _CONVERTDLG_H #define _CONVERTDLG_H /*! \addtogroup wxstf * @{ */ #include #include #include #include "./../../stf.h" //! Dialog for batch conversion of files.from cfs to atf. class wxStfConvertDlg : public wxDialog { DECLARE_EVENT_TABLE() private: wxGenericDirCtrl *mySrcDirCtrl, *myDestDirCtrl; wxString srcDir,destDir; wxString srcFilter; wxCheckBox* myCheckBoxSubdirs; stfio::filetype srcFilterExt, destFilterExt; wxArrayString srcFileNames; bool ReadPath(const wxString& path); void OnComboBoxSrcExt(wxCommandEvent& event); void OnComboBoxDestExt(wxCommandEvent& event); //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfConvertDlg( wxWindow* parent, int id = wxID_ANY, wxString title = wxT("Convert file series"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the source directory. /*! \return The source directory. */ wxString GetSrcDir() const {return srcDir;} //! Get the destination directory. /*! \return The destination directory. */ wxString GetDestDir() const {return destDir;} //! Get the source extension filter. /*! \return The source extension filter. */ wxString GetSrcFilter() const {return srcFilter;} //! Get the source extension as stfio::filetype. /*! \return The source extension as stfio::filetype. */ stfio::filetype GetSrcFileExt() const {return srcFilterExt;} //! Get the destination extension as stfio::filetype. /*! \return The destination extension as stfio::filetype. */ stfio::filetype GetDestFileExt() const {return destFilterExt;} //! Get the list of file names. /*! \return A vector with source file names. */ wxArrayString GetSrcFileNames() const {return srcFileNames;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; /* @} */ #endif stimfit-0.16.7/src/stimfit/gui/dlgs/eventdlg.h0000775000175000017500000000676314752207205014736 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file eventdlg.h * \author Christoph Schmidt-Hieber * \date 2008-01-18 * \brief Declares wxStfEventDlg. */ #ifndef _EVENTDLG_H #define _EVENTDLG_H /*! \addtogroup wxstf * @{ */ #include class SectionPointer; //! Dialog for event-detection settings. class wxStfEventDlg : public wxDialog { DECLARE_EVENT_TABLE() private: double m_threshold; stf::extraction_mode m_mode; bool isExtract; int m_minDistance; int m_template; wxStdDialogButtonSizer* m_sdbSizer; wxTextCtrl *m_textCtrlThr, *m_textCtrlDist; wxStaticBoxSizer* m_radioBox; wxComboBox* m_comboBoxTemplates; void OnClements( wxCommandEvent & event ); void OnJonas( wxCommandEvent & event ); void OnPernia( wxCommandEvent & event ); //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param templateSections A vector of pointers to sections that contain fits * which might be used as a template. * \param isExtract true if events are to be detected for later extraction * (rather than just plotting the detection criterion or * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfEventDlg( wxWindow* parent, const std::vector& templateSections, bool isExtract, int id = wxID_ANY, wxString title = wxT("Event detection settings"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the event detection threshold. /*! \return The event detection threshold. */ double GetThreshold() const {return m_threshold;} //! Indicates the selected extraction algorithm /*! \return The extraction algorithm. */ stf::extraction_mode GetMode() const {return m_mode;} //! Get the minimal distance between events. /*! \return The minimal distance between events in units of sampling points. */ int GetMinDistance() const {return m_minDistance;} //! Get the selected template. /*! \return The index of the template fit to be used for event detection. */ int GetTemplate() const {return m_template;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; /* @} */ #endif stimfit-0.16.7/src/stimfit/gui/dlgs/cursorsdlg.cpp0000775000175000017500000024043714750344764015660 #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "./../app.h" #include "./cursorsdlg.h" #include "./../doc.h" enum { wxLOADCRS, wxSAVECRS, wxCOMBOUM, wxCOMBOU1P, wxCOMBOU2P, wxCOMBOU1B, wxCOMBOU2B, wxCOMBOU1D, wxCOMBOU2D, wxCOMBOU1L, wxCOMBOU2L, #ifdef WITH_PSLOPE wxCOMBOU1PS, wxCOMBOU2PS, #endif wxTEXTM, wxTEXT1P, wxTEXT2P, wxTEXT1B, wxTEXT2B, wxTEXT1D, wxTEXT2D, wxTEXT1L, wxTEXT2L, #ifdef WITH_PSLOPE wxTEXT1PS, wxTEXT2PS, wxTEXT_PSDELTAT, #endif wxTEXTPM, wxRADIOALL, wxRADIOMEAN, wxRADIO_BASELINE_METHOD, // 0: mean + s.d.; 1: median + iqr wxRADIO_LAT_MAXSLOPE1, wxRADIO_LAT_HALFWIDTH1, wxRADIO_LAT_PEAK1, wxRADIO_LAT_MANUAL1, wxRADIO_LAT_EVENT2, wxRADIO_LAT_MAXSLOPE2, wxRADIO_LAT_HALFWIDTH2, wxRADIO_LAT_PEAK2, wxRADIO_LAT_MANUAL2, #ifdef WITH_PSLOPE // Slope radio boxes wxRADIO_PSManBeg, wxRADIO_PSEventBeg, wxRADIO_PSThrBeg, wxRADIO_PSt50Beg, wxRADIO_PSManEnd, wxRADIO_PSt50End, wxRADIO_PSDeltaT, wxRADIO_PSPeakEnd, #endif //WITH_PSLOPE wxMEASCURSOR, wxPEAKATEND, wxPEAKMEAN, wxDIRECTION, wxSLOPE, wxSLOPEUNITS, wxREFERENCE, wxSTARTFITATPEAK, //wxID_STARTFITATPEAK, wxRT_LABEL, wxRT_SLIDER, wxIDNOTEBOOK }; BEGIN_EVENT_TABLE( wxStfCursorsDlg, wxDialog ) EVT_NOTEBOOK_PAGE_CHANGED(wxIDNOTEBOOK, wxStfCursorsDlg::OnPageChanged) EVT_COMBOBOX( wxCOMBOUM, wxStfCursorsDlg::OnComboBoxUM ) EVT_COMBOBOX( wxCOMBOU1P, wxStfCursorsDlg::OnComboBoxU1P ) EVT_COMBOBOX( wxCOMBOU2P, wxStfCursorsDlg::OnComboBoxU2P ) EVT_COMBOBOX( wxCOMBOU1B, wxStfCursorsDlg::OnComboBoxU1B ) EVT_COMBOBOX( wxCOMBOU2B, wxStfCursorsDlg::OnComboBoxU2B ) EVT_COMBOBOX( wxCOMBOU1D, wxStfCursorsDlg::OnComboBoxU1D ) EVT_COMBOBOX( wxCOMBOU2D, wxStfCursorsDlg::OnComboBoxU2D ) EVT_COMBOBOX( wxCOMBOU1L, wxStfCursorsDlg::OnComboBoxU1L ) EVT_COMBOBOX( wxCOMBOU2L, wxStfCursorsDlg::OnComboBoxU2L ) #ifdef WITH_PSLOPE EVT_COMBOBOX( wxCOMBOU1PS, wxStfCursorsDlg::OnComboBoxU1PS ) EVT_COMBOBOX( wxCOMBOU2PS, wxStfCursorsDlg::OnComboBoxU2PS ) #endif EVT_BUTTON( wxID_APPLY, wxStfCursorsDlg::OnPeakcalcexec ) EVT_BUTTON( wxID_OPEN, wxStfCursorsDlg::OnLoadCursorConf ) EVT_BUTTON( wxID_SAVE, wxStfCursorsDlg::OnSaveCursorConf ) // bindings radio buttons EVT_RADIOBUTTON( wxRADIOALL, wxStfCursorsDlg::OnRadioAll ) EVT_RADIOBUTTON( wxRADIOMEAN, wxStfCursorsDlg::OnRadioMean ) EVT_RADIOBUTTON( wxRADIO_LAT_MANUAL1, wxStfCursorsDlg::OnRadioLatManualBeg ) EVT_RADIOBUTTON( wxRADIO_LAT_MAXSLOPE1, wxStfCursorsDlg::OnRadioLatNonManualBeg ) EVT_RADIOBUTTON( wxRADIO_LAT_HALFWIDTH1, wxStfCursorsDlg::OnRadioLatNonManualBeg ) EVT_RADIOBUTTON( wxRADIO_LAT_PEAK1, wxStfCursorsDlg::OnRadioLatNonManualBeg ) EVT_RADIOBUTTON( wxRADIO_LAT_MANUAL2, wxStfCursorsDlg::OnRadioLatManualEnd ) EVT_RADIOBUTTON( wxRADIO_LAT_HALFWIDTH2, wxStfCursorsDlg::OnRadioLatNonManualEnd ) EVT_RADIOBUTTON( wxRADIO_LAT_PEAK2, wxStfCursorsDlg::OnRadioLatNonManualEnd ) EVT_RADIOBUTTON( wxRADIO_LAT_MAXSLOPE2, wxStfCursorsDlg::OnRadioLatNonManualEnd ) EVT_RADIOBUTTON( wxRADIO_LAT_EVENT2, wxStfCursorsDlg::OnRadioLatNonManualEnd ) EVT_COMMAND_SCROLL( wxRT_SLIDER, wxStfCursorsDlg::OnRTSlider ) EVT_CHECKBOX (wxPEAKATEND, wxStfCursorsDlg::OnPeakAtEnd ) EVT_CHECKBOX (wxSTARTFITATPEAK, wxStfCursorsDlg::OnStartFitAtPeak ) #ifdef WITH_PSLOPE EVT_RADIOBUTTON( wxRADIO_PSManBeg, wxStfCursorsDlg::OnRadioPSManBeg ) EVT_RADIOBUTTON( wxRADIO_PSEventBeg, wxStfCursorsDlg::OnRadioPSEventBeg ) EVT_RADIOBUTTON( wxRADIO_PSThrBeg, wxStfCursorsDlg::OnRadioPSThrBeg ) EVT_RADIOBUTTON( wxRADIO_PSt50Beg, wxStfCursorsDlg::OnRadioPSt50Beg ) EVT_RADIOBUTTON( wxRADIO_PSManEnd, wxStfCursorsDlg::OnRadioPSManEnd ) EVT_RADIOBUTTON( wxRADIO_PSt50End, wxStfCursorsDlg::OnRadioPSt50End ) EVT_RADIOBUTTON( wxRADIO_PSDeltaT, wxStfCursorsDlg::OnRadioPSDeltaT ) EVT_RADIOBUTTON( wxRADIO_PSPeakEnd, wxStfCursorsDlg::OnRadioPSPeakEnd ) #endif END_EVENT_TABLE() wxStfCursorsDlg::wxStfCursorsDlg(wxWindow* parent, wxStfDoc* initDoc, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), cursorMIsTime(true), cursor1PIsTime(true), cursor2PIsTime(true), cursor1BIsTime(true), cursor2BIsTime(true), cursor1DIsTime(true), cursor2DIsTime(true), #ifdef WITH_PSLOPE cursor1PSIsTime(true), cursor2PSIsTime(true), #endif cursor1LIsTime(true), cursor2LIsTime(true), actDoc(initDoc) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); m_notebook = new wxNotebook( this, wxIDNOTEBOOK, wxDefaultPosition, wxDefaultSize, 0 ); m_notebook->AddPage( CreateMeasurePage(), wxT("Measure")); m_notebook->AddPage( CreatePeakPage(), wxT("Peak")); m_notebook->AddPage( CreateBasePage(), wxT("Base")); m_notebook->AddPage( CreateDecayPage(), wxT("Decay")); m_notebook->AddPage( CreateLatencyPage(), wxT("Latency")); #ifdef WITH_PSLOPE m_notebook->AddPage( CreatePSlopePage(), wxT("PSlope")); #endif topSizer->Add( m_notebook, 1, wxEXPAND | wxALL, 5 ); wxButton* bClose = new wxButton( this, wxID_CANCEL, wxT("Close") ); wxButton* bApply = new wxButton( this, wxID_APPLY, wxT("Apply") ); wxButton* bLoad = new wxButton( this, wxID_OPEN, wxT("Load") ); wxButton* bSave = new wxButton( this, wxID_SAVE, wxT("Save") ); wxBoxSizer* pSdbSizer = new wxBoxSizer(wxHORIZONTAL); pSdbSizer->Add( bClose, 0, wxALL, 1); pSdbSizer->Add( bApply, 0, wxALL, 1); pSdbSizer->Add( bLoad, 0, wxALL, 1); pSdbSizer->Add( bSave, 0, wxALL, 1); //pSdbSizer->Realize(); topSizer->Add( pSdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); if (actDoc!=NULL) { try { UpdateCursors(); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal )); } } } bool wxStfCursorsDlg::TransferDataFromWindow() { // Apply settings before closing dialog: wxCommandEvent unusedEvent; return wxWindow::TransferDataFromWindow(); } void wxStfCursorsDlg::EndModal(int retCode) { wxCommandEvent unusedEvent; // similar to overriding OnOK in MFC (I hope...) switch (retCode) { case wxID_OK: if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } OnPeakcalcexec(unusedEvent); break; case wxID_CANCEL: break; default: ; } wxDialog::EndModal(retCode); } bool wxStfCursorsDlg::IsCSRSyntax( wxFileConfig* csr_file) { wxString msg = wxT("Syntax Error: "); // Check groups wxString CSR_Group[] = { wxT("__CSR_HEADER__"), wxT("__MEASURE__"), wxT("__PEAK__"), wxT("__BASE__"), wxT("__DECAY__"), wxT("__LATENCY__") }; unsigned int nGroups = sizeof(CSR_Group)/sizeof(wxString); for (std::vector::size_type i=0; iHasGroup(CSR_Group[i])) { wxGetApp().ErrorMsg( msg + CSR_Group[i] + wxT(" not found !") ); return false; } } // check entry in every group // Other checkings... number of Groups if (nGroups != csr_file->GetNumberOfGroups()) { wxGetApp().ErrorMsg( wxT("Unexpected number of groups") ); return false; } return true; } bool wxStfCursorsDlg::OnOK() { //wxCommandEvent unusedEvent; //OnPeakcalcexec(unusedEvent); return true; } wxNotebookPage* wxStfCursorsDlg::CreateMeasurePage() { wxPanel* nbPage; nbPage=new wxPanel(m_notebook); wxBoxSizer* pageSizer; pageSizer=new wxBoxSizer(wxVERTICAL); pageSizer->Add( CreateCursorInput( nbPage, wxTEXTM, -1, wxCOMBOUM, -1, 1, 10 ), 0, wxALIGN_CENTER | wxALL, 2 ); wxCheckBox* pMeasCursor=new wxCheckBox( nbPage, wxMEASCURSOR, wxT("Show vertical ruler through cursor"), wxDefaultPosition, wxDefaultSize, 0 ); pageSizer->Add( pMeasCursor, 0, wxALIGN_CENTER | wxALL, 2); pageSizer->SetSizeHints( nbPage ); nbPage->SetSizer( pageSizer ); nbPage->Layout(); return nbPage; } wxNotebookPage* wxStfCursorsDlg::CreatePeakPage() { wxPanel* nbPage; nbPage=new wxPanel(m_notebook); wxBoxSizer* pageSizer; pageSizer=new wxBoxSizer(wxVERTICAL); pageSizer->Add( CreateCursorInput( nbPage, wxTEXT1P, wxTEXT2P, wxCOMBOU1P, wxCOMBOU2P, 1, 10 ), 0, wxALIGN_CENTER | wxALL, 2 ); wxCheckBox* pPeakAtEnd=new wxCheckBox( nbPage, wxPEAKATEND, wxT("Peak window ends at end of trace"), wxDefaultPosition, wxDefaultSize, 0 ); pPeakAtEnd->SetValue(false); pageSizer->Add( pPeakAtEnd, 0, wxALIGN_CENTER | wxALL, 2); wxFlexGridSizer* peakSettingsGrid; peakSettingsGrid=new wxFlexGridSizer(1,2,0,0); // rows, cols // START: Number of points for peak calculation: wxFlexGridSizer* CommonGrid; CommonGrid = new wxFlexGridSizer(1,2,0,0); wxFlexGridSizer* LeftGrid; LeftGrid = new wxFlexGridSizer(1,0,0); wxStaticBoxSizer* peakPointsSizer = new wxStaticBoxSizer( wxVERTICAL, nbPage, wxT("Number of points for peak") ); wxRadioButton* pAllPoints = new wxRadioButton( nbPage, wxRADIOALL, wxT("All points within peak window"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); wxRadioButton* pMeanPoints = new wxRadioButton( nbPage, wxRADIOMEAN, wxT("User-defined:"), wxDefaultPosition, wxDefaultSize ); wxFlexGridSizer* usrdefGrid; usrdefGrid = new wxFlexGridSizer(1,2,0,0); usrdefGrid->Add(pMeanPoints, 0, wxALIGN_RIGHT |wxALIGN_CENTER_VERTICAL | wxALL, 2); wxTextCtrl* textMeanPoints=new wxTextCtrl( nbPage, wxTEXTPM, wxT("1"), wxDefaultPosition, wxSize(44,20), wxTE_RIGHT ); usrdefGrid->Add(textMeanPoints, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 2); peakPointsSizer->Add( pAllPoints, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2 ); peakPointsSizer->Add( usrdefGrid, 0, wxALIGN_LEFT | wxALL, 2 ); peakSettingsGrid->Add( peakPointsSizer, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2 ); LeftGrid->Add(peakSettingsGrid, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2); /** Rise time slider **/ wxFlexGridSizer* RTGrid; RTGrid = new wxFlexGridSizer(1,2,0,0); wxStaticText* pRTLabel = new wxStaticText( nbPage, wxRT_LABEL, wxT("Rise time 20-80%"), wxDefaultPosition, wxDefaultSize, wxTE_LEFT ); wxSlider *RTSlider = new wxSlider( nbPage, wxRT_SLIDER, 20, 5, 45, wxDefaultPosition, wxSize(100, wxDefaultCoord), wxSL_HORIZONTAL | wxSL_AUTOTICKS, wxDefaultValidator, wxT("")); #if (wxCHECK_VERSION(2, 9, 0)) RTSlider->SetTickFreq(5); #else RTSlider->SetTickFreq(5,1); #endif RTGrid->Add(pRTLabel, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); RTGrid->Add(RTSlider, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); LeftGrid->Add(RTGrid, 1, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL | wxALL, 2); CommonGrid->Add(LeftGrid, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2); // END: Number of points for peak calculation: // START: Peak direction wxFlexGridSizer* RigthGrid; RigthGrid = new wxFlexGridSizer(1,0,0); wxString directionChoices[] = { wxT("Up"), wxT("Down"), wxT("Both") }; int directionNChoices = sizeof( directionChoices ) / sizeof( wxString ); wxRadioBox* pDirection = new wxRadioBox( nbPage, wxDIRECTION, wxT("Peak direction"), wxDefaultPosition, wxDefaultSize, directionNChoices, directionChoices, 0, wxRA_SPECIFY_ROWS ); pDirection->SetSelection(1); //peakSettingsGrid->Add( pDirection, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2 ); RigthGrid->Add( pDirection, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2 ); CommonGrid->Add(RigthGrid, 0, wxALIGN_RIGHT | wxALIGN_TOP | wxALL, 2); pageSizer->Add(CommonGrid, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2); //pageSizer->Add(peakSettingsGrid, 0, wxALIGN_CENTER | wxALL, 2); // END: Peak direction wxFlexGridSizer* slopeSettingsGrid = new wxFlexGridSizer(1,2,0,0); // Threshold slope wxStaticBoxSizer* slopeSizer = new wxStaticBoxSizer( wxVERTICAL, nbPage, wxT("Threshold slope ") ); wxFlexGridSizer* slopeGrid = new wxFlexGridSizer(1,2,0,0); // user entry wxTextCtrl* pSlope=new wxTextCtrl( nbPage, wxSLOPE, wxT(""), wxDefaultPosition, wxSize(64,20), wxTE_RIGHT ); slopeGrid->Add( pSlope, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Units wxStaticText* pSlopeUnits=new wxStaticText( nbPage, wxSLOPEUNITS, wxT(" "), wxDefaultPosition, wxDefaultSize, wxTE_LEFT ); slopeGrid->Add( pSlopeUnits, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); slopeSizer->Add( slopeGrid, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); slopeSettingsGrid->Add( slopeSizer, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // START: Measure peak kinetics wxString referenceChoices[] = { wxT("From baseline"), wxT("From threshold") }; int referenceNChoices = sizeof( referenceChoices ) / sizeof( wxString ); wxRadioBox* pReference = new wxRadioBox( nbPage, wxREFERENCE, wxT("Measure peak kinetics "), wxDefaultPosition, wxDefaultSize, referenceNChoices, referenceChoices, 0, wxRA_SPECIFY_ROWS ); pReference->SetSelection(0); slopeSettingsGrid->Add( pReference, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); pageSizer->Add( slopeSettingsGrid, 0, wxALIGN_CENTER | wxALL, 2 ); // END: Measure peak kinetics pageSizer->SetSizeHints(nbPage); nbPage->SetSizer( pageSizer ); nbPage->Layout(); return nbPage; } wxNotebookPage* wxStfCursorsDlg::CreateBasePage() { wxPanel* nbPage; nbPage=new wxPanel(m_notebook); wxBoxSizer* pageSizer; pageSizer=new wxBoxSizer(wxVERTICAL); pageSizer->Add( CreateCursorInput( nbPage, wxTEXT1B, wxTEXT2B, wxCOMBOU1B, wxCOMBOU2B, 1, 10 ), 0, wxALIGN_CENTER | wxALL, 2 ); // Grid wxFlexGridSizer* BaseMethodSizer = new wxFlexGridSizer(1, 0, 0); wxString BaselineMethods[] = { wxT("Mean and Standard Deviation (SD)"), wxT("Median and InterQuartil Ratio (IQR)") }; int iBaselineMethods = sizeof(BaselineMethods) / sizeof(wxString); //**** Radio options for baseline methods "mean, or median " **** wxRadioBox* pBaselineMethod = new wxRadioBox( nbPage, wxRADIO_BASELINE_METHOD, wxT("Method to compute the baseline"), wxDefaultPosition, wxDefaultSize, iBaselineMethods, BaselineMethods, 0, wxRA_SPECIFY_ROWS ); pBaselineMethod->SetSelection(0); BaseMethodSizer->Add(pBaselineMethod, 0, wxALIGN_CENTER | wxALIGN_TOP | wxALL, 2); pageSizer->Add( BaseMethodSizer, 0, wxALIGN_CENTER | wxALL, 2 ); pageSizer->SetSizeHints(nbPage); nbPage->SetSizer( pageSizer ); nbPage->Layout(); return nbPage; } wxNotebookPage* wxStfCursorsDlg::CreateDecayPage() { wxPanel* nbPage; nbPage=new wxPanel(m_notebook); wxBoxSizer* pageSizer; pageSizer=new wxBoxSizer(wxVERTICAL); pageSizer->Add( CreateCursorInput( nbPage, wxTEXT1D, wxTEXT2D, wxCOMBOU1D, wxCOMBOU2D, 1, 10 ), 0, wxALIGN_CENTER | wxALL, 2 ); wxFlexGridSizer* decaySettingsGrid = new wxFlexGridSizer(1,3,0,0); wxCheckBox* pStartFitAtPeak = new wxCheckBox( nbPage, wxSTARTFITATPEAK, wxT("Start fit at peak"), wxDefaultPosition, wxDefaultSize, 0 ); decaySettingsGrid->Add( pStartFitAtPeak, 0, wxALIGN_CENTER | wxALL, 2); pageSizer->Add( decaySettingsGrid, 0, wxALIGN_CENTER | wxALL, 2 ); pageSizer->SetSizeHints(nbPage); nbPage->SetSizer( pageSizer ); nbPage->Layout(); return nbPage; } wxNotebookPage* wxStfCursorsDlg:: CreateLatencyPage(){ wxPanel* nbPage; nbPage = new wxPanel(m_notebook); wxBoxSizer* pageSizer; pageSizer = new wxBoxSizer(wxVERTICAL); pageSizer->Add(CreateCursorInput(nbPage, wxTEXT1L, wxTEXT2L, wxCOMBOU1L, wxCOMBOU2L, 1, 10), 0, wxALIGN_CENTER | wxALL, 2); // Checkbox for using peak window for latency cursors wxStaticText *pUsePeak = new wxStaticText(nbPage, wxID_ANY, wxT("If not manual, latencies are within peak cursors"), wxDefaultPosition, wxDefaultSize, 0); pageSizer->Add(pUsePeak, 0 , wxALIGN_CENTER | wxALL, 2); // Grid wxFlexGridSizer* LatBegEndGrid; LatBegEndGrid = new wxFlexGridSizer(1,2,0,0); // rows, cols //**** Radio options "Measure from" **** wxStaticBoxSizer* LeftBoxSizer = new wxStaticBoxSizer( wxVERTICAL, nbPage, wxT("Reference channel") ); LeftBoxSizer->GetStaticBox()->SetForegroundColour(*wxRED); // Latency from: Manual wxRadioButton* wxRadio_Lat_Manual1 = new wxRadioButton( nbPage, wxRADIO_LAT_MANUAL1, wxT("Manual"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); // Latency from: Peak wxRadioButton* wxRadio_Lat_Peak1 = new wxRadioButton( nbPage, wxRADIO_LAT_PEAK1, wxT("Peak"), wxDefaultPosition, wxDefaultSize); // Latency from: Maximal slope wxRadioButton* wxRadio_Lat_MaxSlope1 = new wxRadioButton( nbPage, wxRADIO_LAT_MAXSLOPE1, wxT("Maximal slope"), wxDefaultPosition, wxDefaultSize ); // Latency from: Half-maximal amplitude wxRadioButton* wxRadio_Lat_HalfWidth1 = new wxRadioButton( nbPage, wxRADIO_LAT_HALFWIDTH1, wxT("Half-width (t50)"), wxDefaultPosition, wxDefaultSize ); // Sizer to group the radio options LeftBoxSizer->Add( wxRadio_Lat_Manual1, 0, wxALIGN_LEFT | wxALL, 2); LeftBoxSizer->Add( wxRadio_Lat_Peak1, 0, wxALIGN_LEFT | wxALL, 2); LeftBoxSizer->Add( wxRadio_Lat_MaxSlope1, 0, wxALIGN_LEFT | wxALL, 2); LeftBoxSizer->Add( wxRadio_Lat_HalfWidth1, 0, wxALIGN_LEFT | wxALL, 2); // Add to LatBegEndGrid LatBegEndGrid->Add(LeftBoxSizer, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2); //**** Radio options "Latency to" **** wxStaticBoxSizer* RightBoxSizer = new wxStaticBoxSizer( wxVERTICAL, nbPage, wxT("To active channel") ); // Latency to: Manual wxRadioButton* wxRadio_Lat_Manual2 = new wxRadioButton( nbPage, wxRADIO_LAT_MANUAL2, wxT("Manual"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); //wxRadio_Lat_Manual2->SetValue(true); // Latency to: Peak wxRadioButton* wxRadio_Lat_Peak2 = new wxRadioButton( nbPage, wxRADIO_LAT_PEAK2, wxT("Peak"), wxDefaultPosition, wxDefaultSize); // Latency to: Half-maximal amplitude wxRadioButton* wxRadio_Lat_HalfWidth2 = new wxRadioButton( nbPage, wxRADIO_LAT_HALFWIDTH2, wxT("Half-width (t50)"), wxDefaultPosition, wxDefaultSize); // Latency to: Maximal slope wxRadioButton* wxRadio_Lat_MaxSlope2 = new wxRadioButton( nbPage, wxRADIO_LAT_MAXSLOPE2, wxT("Maximal slope"), wxDefaultPosition, wxDefaultSize); // Latency to: Beginning of event wxRadioButton* wxRadio_Lat_Event2 = new wxRadioButton( nbPage, wxRADIO_LAT_EVENT2, wxT("Beginning of event"), wxDefaultPosition, wxDefaultSize ); // Sizer to group the radio options RightBoxSizer->Add( wxRadio_Lat_Manual2, 0, wxALIGN_LEFT | wxALL, 2); RightBoxSizer->Add( wxRadio_Lat_Peak2, 0, wxALIGN_LEFT | wxALL, 2); RightBoxSizer->Add( wxRadio_Lat_MaxSlope2, 0, wxALIGN_LEFT | wxALL, 2); RightBoxSizer->Add( wxRadio_Lat_HalfWidth2, 0, wxALIGN_LEFT | wxALL, 2); RightBoxSizer->Add( wxRadio_Lat_Event2, 0, wxALIGN_LEFT | wxALL, 2); // Add to LatBegEndGrid LatBegEndGrid->Add(RightBoxSizer, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2); pageSizer->Add(LatBegEndGrid, 0, wxALIGN_CENTER | wxALL, 2); nbPage->SetSizer(pageSizer); nbPage->Layout(); return nbPage; } #ifdef WITH_PSLOPE wxNotebookPage* wxStfCursorsDlg::CreatePSlopePage() { wxPanel* nbPage; nbPage=new wxPanel(m_notebook); // Sizer wxBoxSizer* pageSizer; pageSizer=new wxBoxSizer(wxVERTICAL); pageSizer->Add( CreateCursorInput( nbPage, wxTEXT1PS, wxTEXT2PS, wxCOMBOU1PS, wxCOMBOU2PS, 1, 10 ), 0, wxALIGN_CENTER | wxALL, 2 ); // Grid wxFlexGridSizer* PSBegEndGrid; PSBegEndGrid = new wxFlexGridSizer(1,2,0,0); // rows, cols //**** Radio options "Slope from" **** wxStaticBoxSizer* LeftBoxSizer = new wxStaticBoxSizer( wxVERTICAL, nbPage, wxT("Slope from") ); // Slope from: Manual wxRadioButton* pPSManBeg = new wxRadioButton( nbPage, wxRADIO_PSManBeg, wxT("Manual"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); //pPSManBeg->SetValue(true); // Slope from: Beginning of event wxRadioButton* pPSEventBeg = new wxRadioButton( nbPage, wxRADIO_PSEventBeg, wxT("Beginning of event"), wxDefaultPosition, wxDefaultSize ); // Slope from: Threshold slope wxFlexGridSizer* thrGrid; thrGrid = new wxFlexGridSizer(1,2,0,0); wxRadioButton* pPSThrBeg = new wxRadioButton( nbPage, wxRADIO_PSThrBeg, wxT("Threshold"), wxDefaultPosition, wxDefaultSize); thrGrid->Add(pPSThrBeg, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 2); // Slope from: t50 wxRadioButton* pPSt50Beg = new wxRadioButton( nbPage, wxRADIO_PSt50Beg, wxT("Half-width (t50)"), wxDefaultPosition, wxDefaultSize); // activate radio buttons according to the PSlope mode of the active document wxTextCtrl* pCursor1PS = (wxTextCtrl*)FindWindow(wxTEXT1PS); if ( pCursor1PS == NULL ){ wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::CreatePSlopePage()")); } switch( actDoc->GetPSlopeBegMode()){ case 1: pPSEventBeg->SetValue(true); pCursor1PS->Enable(false); break; case 2: pPSThrBeg->SetValue(true); pCursor1PS->Enable(false); break; case 3: pPSt50Beg->SetValue(true); pCursor1PS->Enable(false); break; case 0: default: pPSManBeg->SetValue(true); pCursor1PS->Enable(true); } // Sizer to group the radio options LeftBoxSizer->Add( pPSManBeg, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); LeftBoxSizer->Add( pPSEventBeg, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); LeftBoxSizer->Add( thrGrid, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); LeftBoxSizer->Add( pPSt50Beg, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); // Add to PSBegEndGrid PSBegEndGrid->Add(LeftBoxSizer, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2); //**** Radio options "Slope to" **** wxStaticBoxSizer* RightBoxSizer = new wxStaticBoxSizer( wxVERTICAL, nbPage, wxT("Slope to") ); // Slope to: Manual wxRadioButton* pPSManEnd = new wxRadioButton( nbPage, wxRADIO_PSManEnd, wxT("Manual"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); // Slope to: Half-width wxRadioButton* pPSt50End = new wxRadioButton( nbPage, wxRADIO_PSt50End, wxT("Half-width (t50)"), wxDefaultPosition, wxDefaultSize); // Slope to: DeltaT wxFlexGridSizer* DeltaTGrid; DeltaTGrid = new wxFlexGridSizer(1,2,0,0); wxRadioButton* pPSDeltaT = new wxRadioButton( nbPage, wxRADIO_PSDeltaT, wxT("Delta t"), wxDefaultPosition, wxDefaultSize); DeltaTGrid->Add(pPSDeltaT, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 2); wxTextCtrl* pTextPSDeltaT = new wxTextCtrl(nbPage, wxTEXT_PSDELTAT, wxT(""), wxDefaultPosition, wxSize(44,20), wxTE_RIGHT); pTextPSDeltaT->Enable(false); DeltaTGrid->Add(pTextPSDeltaT, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 2); // Slope to: Peak wxRadioButton* pPSPeakEnd = new wxRadioButton( nbPage, wxRADIO_PSPeakEnd, wxT("Peak"), wxDefaultPosition, wxDefaultSize); // activate radio buttons according to the PSlope mode of the active document wxTextCtrl* pCursor2PS = (wxTextCtrl*)FindWindow(wxTEXT2PS); if (pCursor2PS == NULL){ wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::CreatePSlopePage()")); } switch( actDoc->GetPSlopeEndMode()){ case 1: pPSt50End->SetValue(true); pCursor2PS->Enable(false); break; case 2: pPSDeltaT->SetValue(true); pTextPSDeltaT->Enable(true); pCursor2PS->Enable(false); break; case 3: pPSPeakEnd->SetValue(true); pCursor2PS->Enable(false); break; case 0: default: pPSManEnd->SetValue(true); pCursor2PS->Enable(true); } // Sizer to group the radio options RightBoxSizer->Add( pPSManEnd, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); RightBoxSizer->Add( pPSt50End, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); RightBoxSizer->Add( DeltaTGrid, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); RightBoxSizer->Add( pPSPeakEnd, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2); // Add to PSBegEndGrid PSBegEndGrid->Add(RightBoxSizer, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2); pageSizer->Add(PSBegEndGrid, 0, wxALIGN_CENTER | wxALL, 2); nbPage->SetSizer(pageSizer); nbPage->Layout(); return nbPage; } #endif // WITH_PSLOPE wxFlexGridSizer* wxStfCursorsDlg::CreateCursorInput( wxPanel* nbPage, wxWindowID textC1id, wxWindowID textC2id, wxWindowID comboU1id, wxWindowID comboU2id, std::size_t c1, std::size_t c2 ) { wxFlexGridSizer* cursorGrid=new wxFlexGridSizer(2,3,0,0); // Cursor 1: // Description wxStaticText *Cursor1; Cursor1 = new wxStaticText( nbPage, wxID_ANY, wxT("First cursor:"), wxDefaultPosition, wxDefaultSize, wxTE_LEFT ); cursorGrid->Add( Cursor1, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // user entry wxString strc1,strc2; strc1 << (int)c1; wxTextCtrl* textC1 = new wxTextCtrl( nbPage, textC1id, strc1, wxDefaultPosition, wxSize(64,20), wxTE_RIGHT ); cursorGrid->Add( textC1, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // units #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) wxString szUnits[] = { actDoc->GetXUnits(), wxT("pts") }; int szUnitsSize = sizeof( szUnits ) / sizeof( wxString ); wxComboBox* comboU1 = new wxComboBox( nbPage, comboU1id, actDoc->GetXUnits(), wxDefaultPosition, #else wxString szUnits[] = { wxString(actDoc->GetXUnits().c_str(), wxConvUTF8), wxT("pts") }; int szUnitsSize = sizeof( szUnits ) / sizeof( wxString ); wxComboBox* comboU1 = new wxComboBox( nbPage, comboU1id, wxString(actDoc->GetXUnits().c_str(), wxConvUTF8), wxDefaultPosition, #endif wxSize(64,20), szUnitsSize, szUnits, wxCB_DROPDOWN | wxCB_READONLY ); cursorGrid->Add( comboU1, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Cursor 2: if (textC2id >= 0) { wxStaticText *Cursor2; // Description Cursor2 = new wxStaticText( nbPage, wxID_ANY, wxT("Second cursor:"), wxDefaultPosition, wxDefaultSize, wxTE_LEFT ); cursorGrid->Add( Cursor2, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // user entry strc2 << (int)c2; wxTextCtrl* textC2 = new wxTextCtrl( nbPage, textC2id, strc2, wxDefaultPosition, wxSize(64,20), wxTE_RIGHT ); cursorGrid->Add( textC2, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // units #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) wxComboBox* comboU2 = new wxComboBox( nbPage, comboU2id, actDoc->GetXUnits(), wxDefaultPosition, #else wxComboBox* comboU2 = new wxComboBox( nbPage, comboU2id, wxString(actDoc->GetXUnits().c_str(), wxConvUTF8), wxDefaultPosition, #endif wxSize(64,20), szUnitsSize, szUnits, wxCB_DROPDOWN | wxCB_READONLY ); cursorGrid->Add( comboU2, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); } return cursorGrid; } void wxStfCursorsDlg::OnPeakcalcexec( wxCommandEvent& event ) { event.Skip(); // Update the results table (see wxStfApp in app.cpp) wxGetApp().OnPeakcalcexecMsg(actDoc); } bool wxStfCursorsDlg::LoadCursorConf(const wxString& filepath ){ // When loading the configuration we'll write directly in the active document // loading a cursor file will also update measurements, cursors, the graph and result table. // It will write the registry as well, since it is similar to pressing "Apply". // see wxStfApp::OnPeakcalcexeMsg() for details. if (actDoc == NULL) { wxGetApp().ErrorMsg(wxT("No active document found")); return false; } wxFileConfig* csr_config = new wxFileConfig(wxT(""), wxT(""), filepath ); // minimal syntax check if ( !IsCSRSyntax( csr_config ) ) { return false; } wxString CursorValue; long start_csr, end_csr; // *** update controls in __MEASURE__ tab **** csr_config->Read( wxT("__MEASURE__/Cursor"), &start_csr ); // read from file wxTextCtrl *pMeasureCursor = (wxTextCtrl*)FindWindow(wxTEXTM); if (pMeasureCursor == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::LoadCursorConf()")); return false; } if (cursorMIsTime) { float fvalue = start_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), start_csr ); pMeasureCursor->SetValue( CursorValue ); actDoc->SetMeasCursor( GetCursorM() ); int show_ruler; csr_config->Read( wxT("__MEASURE__/ShowRuler"), &show_ruler ); // read from file SetRuler( show_ruler ); actDoc->SetMeasRuler( show_ruler ); // **** update controls in __PEAK__ tab **** csr_config->Read( wxT("__PEAK__/LeftCursor"), &start_csr ); // read from file csr_config->Read( wxT("__PEAK__/RightCursor"), &end_csr ); // read from file wxTextCtrl *pPeak1Cursor = (wxTextCtrl*)FindWindow(wxTEXT1P); wxTextCtrl *pPeak2Cursor = (wxTextCtrl*)FindWindow(wxTEXT2P); if (pPeak1Cursor == NULL || pPeak2Cursor == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::LoadCursorConf()")); return false; } if (cursor1PIsTime) { float fvalue = start_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), start_csr ); pPeak1Cursor->SetValue( CursorValue ); actDoc->SetPeakBeg( GetCursor1P() ); if (cursor2PIsTime) { float fvalue = end_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), end_csr ); pPeak2Cursor->SetValue( CursorValue ); actDoc->SetPeakEnd( GetCursor2P() ); bool is_end; csr_config->Read( wxT("__PEAK__/PeakAtEnd"), &is_end ); // read from file SetPeakAtEnd( is_end ); actDoc->SetPeakAtEnd( is_end ); int npoints; csr_config->Read( wxT("__PEAK__/NumberOfPoints"), &npoints ); // read from file SetPeakPoints( npoints); actDoc->SetPM( npoints ); int direction; csr_config->Read( wxT("__PEAK__/Direction"), &direction ); // read from file stfnum::direction mydirection; switch (direction) { case 0: mydirection = stfnum::up; break; case 1: mydirection = stfnum::down; break; case 2: mydirection = stfnum::both; break; default: mydirection = stfnum::undefined_direction; } SetDirection( mydirection ); actDoc->SetDirection ( mydirection ); bool confbase; csr_config->Read( wxT("__PEAK__/FromBase"), &confbase ); // read from file SetFromBase( confbase ); actDoc->SetFromBase( confbase ); int rt_factor; csr_config->Read( wxT("__PEAK__/RTFactor"), &rt_factor ); // read from file SetRTFactor( rt_factor ); actDoc->SetRTFactor( rt_factor ); double slope; wxString wxSlope; csr_config->Read( wxT("__PEAK__/Slope"), &wxSlope); // read from file wxSlope.ToDouble(&slope); SetSlope( slope ); actDoc->SetSlopeForThreshold( slope ); // **** update controls in __BASE__ tab **** csr_config->Read( wxT("__BASE__/LeftCursor"), &start_csr ); // read from file csr_config->Read( wxT("__BASE__/RightCursor"), &end_csr ); // read from file wxTextCtrl *pBase1Cursor = (wxTextCtrl*)FindWindow(wxTEXT1B); wxTextCtrl *pBase2Cursor = (wxTextCtrl*)FindWindow(wxTEXT2B); if (pBase1Cursor == NULL || pBase2Cursor == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::LoadCursorConf()")); return false; } if (cursor1BIsTime) { float fvalue = start_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), start_csr ); pBase1Cursor->SetValue( CursorValue ); actDoc->SetBaseBeg( GetCursor1B() ); if (cursor2BIsTime) { float fvalue = end_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), end_csr ); pBase2Cursor->SetValue( CursorValue ); actDoc->SetBaseEnd( GetCursor2B() ); int base_method; csr_config->Read( wxT("__BASE__/BaselineMethod"), &base_method ); // read from file stfnum::baseline_method mybase_method; switch( base_method ) { case 0: mybase_method = stfnum::mean_sd; break; case 1: mybase_method = stfnum::median_iqr; break; default: mybase_method = stfnum::mean_sd; } SetBaselineMethod ( mybase_method ); actDoc->SetBaselineMethod( mybase_method ); // **** update controls in __DECAY__ tab **** csr_config->Read( wxT("__DECAY__/LeftCursor"), &start_csr ); // read from file csr_config->Read( wxT("__DECAY__/RightCursor"), &end_csr ); // read from file wxTextCtrl *pFit1Cursor = (wxTextCtrl*)FindWindow(wxTEXT1D); wxTextCtrl *pFit2Cursor = (wxTextCtrl*)FindWindow(wxTEXT2D); if (pBase1Cursor == NULL || pBase2Cursor == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::LoadCursorConf()")); return false; } if (cursor1DIsTime) { float fvalue = start_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), start_csr ); pFit1Cursor->SetValue( CursorValue ); actDoc->SetFitBeg( GetCursor1D() ); if (cursor2DIsTime) { float fvalue = end_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), end_csr ); pFit2Cursor->SetValue( CursorValue ); actDoc->SetFitEnd( GetCursor2D() ); bool is_peak; csr_config->Read(wxT("__DECAY__/StartFitAtPeak"), &is_peak); SetStartFitAtPeak( is_peak); actDoc->SetStartFitAtPeak( is_peak ); // **** update controls in LATENCY tab **** csr_config->Read( wxT("__LATENCY__/LeftCursor"), &start_csr ); // read from file csr_config->Read( wxT("__LATENCY__/RightCursor"), &end_csr ); // read from file wxTextCtrl *pLatency1Cursor = (wxTextCtrl*)FindWindow(wxTEXT1L); wxTextCtrl *pLatency2Cursor = (wxTextCtrl*)FindWindow(wxTEXT2L); if (pLatency1Cursor == NULL || pLatency2Cursor == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::LoadCursorConf()")); return false; } if (cursor1LIsTime) { float fvalue = start_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), start_csr ); pLatency1Cursor->SetValue( CursorValue ); actDoc->SetLatencyBeg( GetCursor1L() ); if (cursor2LIsTime) { float fvalue = end_csr*actDoc->GetXScale() ; CursorValue = wxString::Format( wxT("%f"), fvalue ); } else CursorValue = wxString::Format( wxT("%i"), end_csr ); pLatency2Cursor->SetValue( CursorValue ); actDoc->SetLatencyEnd( GetCursor2L() ); int mode; csr_config->Read( wxT("__LATENCY__/LeftMode"), &mode ); // read from file stf::latency_mode latency_mode; switch( mode ) { case 0: latency_mode =stf::manualMode; break; case 1: latency_mode = stf::peakMode; break; case 2: latency_mode = stf::riseMode; break; case 3: latency_mode = stf::halfMode; break; case 4: latency_mode = stf::footMode; break; default: latency_mode = stf::undefinedMode; } SetLatencyStartMode( latency_mode ); actDoc->SetLatencyStartMode( latency_mode ); csr_config->Read( wxT("__LATENCY__/RightMode"), &mode ); // read from file switch( mode ) { case 0: latency_mode =stf::manualMode; break; case 1: latency_mode = stf::peakMode; break; case 2: latency_mode = stf::riseMode; break; case 3: latency_mode = stf::halfMode; break; case 4: latency_mode = stf::footMode; break; default: latency_mode = stf::undefinedMode; } SetLatencyEndMode( latency_mode ); actDoc->SetLatencyEndMode( latency_mode ); delete csr_config; // we use wxStfApp::OnPeakcalcexec() here basically to update the results table. // Because wxStfApp::OnPeakcalcexec() only updates the properties of wxStfDoc in the current tab // of the cursor dialog, we need to call the methods from actDoc() to update the cursors which // are not currently visible, but stored in the csr file. wxGetApp().OnPeakcalcexecMsg(actDoc); return true; } void wxStfCursorsDlg::OnLoadCursorConf( wxCommandEvent& event ) { event.Skip(); wxString csrFilter = wxT("Cursor conf (*.csr)|*csr"); wxFileDialog* LoadCursorDialog = new wxFileDialog(this, wxT("Load Cursor configuration"), wxT(""), wxT(""), csrFilter, wxFD_OPEN | wxFD_PREVIEW); if (LoadCursorDialog->ShowModal() == wxID_OK ){ wxString mypath = LoadCursorDialog->GetPath(); LoadCursorConf( mypath ); } } bool wxStfCursorsDlg::SaveCursorConf(const wxString& mypath ){ // Read cursor configuration from active document! if (actDoc == NULL){ throw std::runtime_error("No active document found"); return false; } wxDateTime now = wxDateTime::Now(); wxFileConfig* csr_config = new wxFileConfig(wxT(""), wxT(""), mypath ); csr_config->SetPath( wxT("__CSR_HEADER__") ); //csr_config->Write( wxT("Date"), now.Format( wxT("%Y/%M/%d"), wxDateTime::CET) ); csr_config->Write( wxT("Date"), now.Format( wxT("%A, %d %B, %Y"), wxDateTime::CET) ); csr_config->Write( wxT("Time"), now.Format( wxT("%H:%M:%S %p"), wxDateTime::CET) ); csr_config->SetPath( wxT("../__MEASURE__") ); csr_config->Write( wxT("Cursor"), (int)actDoc->GetMeasCursor() ); csr_config->Write( wxT("ShowRuler"), (int)actDoc->GetMeasRuler() ); csr_config->SetPath( wxT("../__PEAK__") ); csr_config->Write( wxT("LeftCursor"), (int)actDoc->GetPeakBeg() ); csr_config->Write( wxT("Rightcursor"), (int)actDoc->GetPeakEnd() ); csr_config->Write( wxT("PeakAtEnd"), (int)actDoc->GetPeakAtEnd() ); csr_config->Write( wxT("NumberOfPoints"), (int)actDoc->GetPM() ); csr_config->Write( wxT("Direction"), (int)actDoc->GetDirection() ); csr_config->Write( wxT("FromBase"), (int)actDoc->GetFromBase() ); csr_config->Write( wxT("RTFactor"), (int)actDoc->GetRTFactor() ); wxString mySlope; mySlope << actDoc->GetSlopeForThreshold(); csr_config->Write( wxT("Slope"), mySlope ); csr_config->SetPath( wxT("../__BASE__") ); csr_config->Write( wxT("LeftCursor"), (int)actDoc->GetBaseBeg() ); csr_config->Write( wxT("RightCursor"),(int)actDoc->GetBaseEnd() ); csr_config->Write( wxT("BaselineMethod"), (int)actDoc->GetBaselineMethod() ); csr_config->SetPath( wxT("../__DECAY__") ); csr_config->Write( wxT("LeftCursor"), (int)actDoc->GetFitBeg() ); csr_config->Write( wxT("RightCursor"),(int)actDoc->GetFitEnd() ); csr_config->Write( wxT("StartFitAtPeak"),(int)actDoc->GetStartFitAtPeak() ); csr_config->SetPath( wxT("../__LATENCY__") ); csr_config->Write( wxT("LeftCursor"), (int)actDoc->GetLatencyBeg() ); csr_config->Write( wxT("RightCursor"),(int)actDoc->GetLatencyEnd() ); csr_config->Write( wxT("LeftMode"),(int)actDoc->GetLatencyStartMode() ); csr_config->Write( wxT("RightMode"),(int)actDoc->GetLatencyEndMode() ); csr_config->Flush(); // write all changes return true; } void wxStfCursorsDlg::OnSaveCursorConf( wxCommandEvent& event ) { event.Skip(); wxString crsFilter = wxT("Cursor conf (*.csr)|*csr"); wxFileDialog* SaveCursorDialog = new wxFileDialog(this, wxT("Save Cursor configuration"), wxT(""), wxT(""), crsFilter, wxFD_SAVE | wxFD_PREVIEW); if (SaveCursorDialog->ShowModal() == wxID_OK ){ wxString mypath = SaveCursorDialog->GetPath(); SaveCursorConf( mypath ); } } int wxStfCursorsDlg::ReadCursor(wxWindowID textId, bool isTime) const { // always returns in units of sampling points, // conversion is necessary if it's in units of time: long cursor; wxString strEdit; wxTextCtrl *pText = (wxTextCtrl*)FindWindow(textId); if (pText == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::ReadCursor()")); return 0; } strEdit << pText->GetValue(); if (isTime) { double fEdit; strEdit.ToDouble( &fEdit ); cursor=stf::round(fEdit/actDoc->GetXScale()); } else { strEdit.ToLong ( &cursor ); } return (int)cursor; } void wxStfCursorsDlg::WriteCursor(wxWindowID textId, bool isTime, long value) const { wxString myvalue; wxTextCtrl *pText = (wxTextCtrl*)FindWindow(textId); if (pText == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::SetCursor()")); return; } if (isTime){ float fvalue = stf::round( value/actDoc->GetXScale() ); myvalue = wxString::Format(wxT("%f"), fvalue); } else { myvalue = wxString::Format(wxT("%i"), value); } pText->SetValue(myvalue); } #ifdef WITH_PSLOPE int wxStfCursorsDlg::ReadDeltaT(wxWindowID textID) const { // returns DeltaT entered in the textBox in units of sampling points long cursorpos=0; wxString strDeltaT; wxTextCtrl *pText = (wxTextCtrl*)FindWindow(textID); if (pText == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::ReadDeltaT()")); return 0; } strDeltaT << pText->GetValue(); double DeltaTval; strDeltaT.ToDouble(&DeltaTval); cursorpos = stf::round(DeltaTval/actDoc->GetXScale()); return (int)cursorpos; } #endif // WITH_PSLOPE int wxStfCursorsDlg::GetCursorM() const { return ReadCursor(wxTEXTM,cursorMIsTime); } int wxStfCursorsDlg::GetCursor1P() const { return ReadCursor(wxTEXT1P,cursor1PIsTime); } int wxStfCursorsDlg::GetCursor2P() const { return ReadCursor(wxTEXT2P,cursor2PIsTime); } int wxStfCursorsDlg::GetCursor1B() const { return ReadCursor(wxTEXT1B,cursor1BIsTime); } int wxStfCursorsDlg::GetCursor2B() const { return ReadCursor(wxTEXT2B,cursor2BIsTime); } int wxStfCursorsDlg::GetCursor1D() const { return ReadCursor(wxTEXT1D,cursor1DIsTime); } int wxStfCursorsDlg::GetCursor2D() const { return ReadCursor(wxTEXT2D,cursor2DIsTime); } int wxStfCursorsDlg::GetCursor1L() const { return ReadCursor(wxTEXT1L, cursor1LIsTime); } int wxStfCursorsDlg::GetCursor2L() const { return ReadCursor(wxTEXT2L, cursor2LIsTime); } #ifdef WITH_PSLOPE int wxStfCursorsDlg::GetCursor1PS() const { return ReadCursor(wxTEXT1PS, cursor1PSIsTime); } int wxStfCursorsDlg::GetCursor2PS() const { return ReadCursor(wxTEXT2PS, cursor2PSIsTime); } #endif int wxStfCursorsDlg::GetPeakPoints() const { wxRadioButton* pRadioButtonAll = (wxRadioButton*)FindWindow(wxRADIOALL); wxRadioButton* pRadioButtonMean = (wxRadioButton*)FindWindow(wxRADIOMEAN); if (pRadioButtonAll==NULL || pRadioButtonMean==NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetPeakPoints()")); return 0; } if (pRadioButtonAll->GetValue()) { return -1; } else { if (pRadioButtonMean->GetValue()) { return ReadCursor(wxTEXTPM,false); } else { wxGetApp().ErrorMsg(wxT("nothing selected in wxStfCursorsDlg::GetPeakPoints()")); return 0; } } } int wxStfCursorsDlg::GetRTFactor() const { wxSlider *pRTSlider = (wxSlider*)FindWindow(wxRT_SLIDER); if (pRTSlider == NULL ) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg:GetRTFactor()")); return -1; } return pRTSlider->GetValue(); } #ifdef WITH_PSLOPE int wxStfCursorsDlg::GetDeltaT() const { return ReadDeltaT(wxTEXT_PSDELTAT); } #endif #ifdef WITH_PSLOPE void wxStfCursorsDlg::SetDeltaT (int DeltaT) { wxRadioButton* pRadPSDeltaT = (wxRadioButton*)FindWindow(wxRADIO_PSDeltaT); wxTextCtrl* pTextPSDeltaT = (wxTextCtrl*)FindWindow(wxTEXT_PSDELTAT); if (pRadPSDeltaT == NULL || pTextPSDeltaT == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::wxSetDeltaT()")); return; } // transform sampling points into x-units double fDeltaT; fDeltaT =DeltaT*actDoc->GetXScale(); wxString strDeltaTval; strDeltaTval << fDeltaT; pTextPSDeltaT->SetValue(strDeltaTval); } #endif // WITH_PSLOPE void wxStfCursorsDlg::SetPeakPoints(int peakPoints) { wxRadioButton* pRadioButtonAll = (wxRadioButton*)FindWindow(wxRADIOALL); wxRadioButton* pRadioButtonMean = (wxRadioButton*)FindWindow(wxRADIOMEAN); wxTextCtrl* pTextPM = (wxTextCtrl*)FindWindow(wxTEXTPM); if (pRadioButtonAll==NULL || pRadioButtonMean==NULL || pTextPM==NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::SetPeakPoints()")); return; } if (peakPoints==0 || peakPoints<-1) { throw std::runtime_error("peak points out of range in wxStfCursorsDlg::SetPeakPoints()"); } else if (peakPoints == -1) { pRadioButtonAll->SetValue(true); pRadioButtonMean->SetValue(false); pTextPM->Enable(false); } else { wxString entry; entry << peakPoints; pRadioButtonAll->SetValue(false); pRadioButtonMean->SetValue(true); pTextPM->Enable(true); pTextPM->SetValue( entry ); } } stfnum::direction wxStfCursorsDlg::GetDirection() const { wxRadioBox* pDirection = (wxRadioBox*)FindWindow(wxDIRECTION); if (pDirection == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetDirection()")); return stfnum::undefined_direction; } switch (pDirection->GetSelection()) { case 0: return stfnum::up; case 1: return stfnum::down; case 2: return stfnum::both; default: return stfnum::undefined_direction; } } void wxStfCursorsDlg::SetDirection(stfnum::direction direction) { wxRadioBox* pDirection = (wxRadioBox*)FindWindow(wxDIRECTION); if (pDirection == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetDirection()")); return; } switch (direction) { case stfnum::up: pDirection->SetSelection(0); break; case stfnum::down: pDirection->SetSelection(1); break; case stfnum::both: case stfnum::undefined_direction: pDirection->SetSelection(2); break; } } bool wxStfCursorsDlg::GetFromBase() const { wxRadioBox* pReference = (wxRadioBox*)FindWindow(wxREFERENCE); if (pReference == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetFromBase()")); return true; } switch (pReference->GetSelection()) { case 0: return true; case 1: return false; default: return true; } } void wxStfCursorsDlg::SetRTFactor(int RTFactor) { wxSlider *pRTSlider = (wxSlider*)FindWindow(wxRT_SLIDER); wxStaticText *pRTLabel = (wxStaticText*)FindWindow(wxRT_LABEL); if (pRTSlider == NULL || pRTLabel == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg:SetRTFactor()")); return; } pRTSlider->SetValue(RTFactor); wxString label(wxT("Rise time ")); label << pRTSlider->GetValue() << wxT("-"); label << 100-pRTSlider->GetValue() << wxT("\%"); pRTLabel->SetLabel(label); } void wxStfCursorsDlg::SetFromBase(bool fromBase) { wxRadioBox* pReference = (wxRadioBox*)FindWindow(wxREFERENCE); if (pReference == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::SetFromBase()")); return; } if (fromBase) { pReference->SetSelection(0); } else { pReference->SetSelection(1); } } enum stfnum::baseline_method wxStfCursorsDlg::GetBaselineMethod() const { wxRadioBox* pBaselineMethod = (wxRadioBox*)FindWindow(wxRADIO_BASELINE_METHOD); if (pBaselineMethod == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetBaseSelection()")); return stfnum::mean_sd; //default value mean and standard deviation } switch( pBaselineMethod->GetSelection() ) { case 0: return stfnum::mean_sd; case 1: return stfnum::median_iqr; default: return stfnum::mean_sd; } } void wxStfCursorsDlg::SetBaselineMethod(stfnum::baseline_method base_method) { wxRadioBox* pBaselineMethod = (wxRadioBox*)FindWindow(wxRADIO_BASELINE_METHOD); if (pBaselineMethod == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::SetBaselineMethod()")); return; } switch(base_method) { case stfnum::median_iqr: pBaselineMethod->SetSelection(1); break; case stfnum::mean_sd: pBaselineMethod->SetSelection(0); break; } } bool wxStfCursorsDlg::GetPeakAtEnd() const { //Check if 'Upper limit at end of trace' is selected wxCheckBox* pPeakAtEnd = (wxCheckBox*)FindWindow(wxPEAKATEND); if (pPeakAtEnd == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetPeakAtEnd()")); return false; } return pPeakAtEnd->IsChecked(); } void wxStfCursorsDlg::OnPeakAtEnd( wxCommandEvent& event) { event.Skip(); wxCheckBox* pPeakAtEnd = (wxCheckBox*)FindWindow(wxPEAKATEND); wxTextCtrl* pCursor2P = (wxTextCtrl*)FindWindow(wxTEXT2P); if (pPeakAtEnd == NULL || pCursor2P == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnPeakAtEnd()")); return; } // second peak cursor is inactive if the peak at the end checkbox is checked pCursor2P->Enable(! pPeakAtEnd->IsChecked() ); } void wxStfCursorsDlg::SetPeakAtEnd( bool is_end ) { wxCheckBox* pPeakAtEnd = (wxCheckBox*)FindWindow(wxPEAKATEND); wxTextCtrl* pCursor2P = (wxTextCtrl*)FindWindow(wxTEXT2P); if (pPeakAtEnd == NULL || pCursor2P == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::SetPeakAtEnd()")); return; } pCursor2P->Enable( ! is_end ); pPeakAtEnd->SetValue( is_end ); } bool wxStfCursorsDlg::GetStartFitAtPeak() const { //Check if 'Start fit at peak' is selected wxCheckBox* pStartFitAtPeak = (wxCheckBox*)FindWindow(wxSTARTFITATPEAK); if (pStartFitAtPeak == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetStartFitAtPeak()")); return false; } return pStartFitAtPeak->IsChecked(); } void wxStfCursorsDlg::SetStartFitAtPeak(bool is_peak){ wxCheckBox* pStartFitAtPeak = (wxCheckBox*)FindWindow(wxSTARTFITATPEAK); wxTextCtrl* pCursor1D = (wxTextCtrl*)FindWindow(wxTEXT1D); if (pStartFitAtPeak == NULL || pCursor1D == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetStartFitAtPeak()")); return; } pCursor1D->Enable( ! is_peak ); pStartFitAtPeak->SetValue( is_peak); } void wxStfCursorsDlg::OnStartFitAtPeak( wxCommandEvent& event) { event.Skip(); wxCheckBox* pStartFitAtPeak = (wxCheckBox*)FindWindow(wxSTARTFITATPEAK); wxTextCtrl* pCursor1D = (wxTextCtrl*)FindWindow(wxTEXT1D); if (pStartFitAtPeak == NULL || pCursor1D == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnStartFitAtEnd()")); return; } // left decay cursor is inactive if the start fit at peak is checked pCursor1D->Enable(! pStartFitAtPeak->IsChecked() ); } void wxStfCursorsDlg::OnPageChanged(wxNotebookEvent& event) { event.Skip(); if (actDoc!=NULL) { try { UpdateCursors(); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal )); } } } void wxStfCursorsDlg::OnComboBoxUM( wxCommandEvent& event ) { event.Skip(); UpdateUnits(wxCOMBOUM,cursorMIsTime,wxTEXTM); } void wxStfCursorsDlg::OnComboBoxU1P( wxCommandEvent& event ) { event.Skip(); UpdateUnits(wxCOMBOU1P,cursor1PIsTime,wxTEXT1P); } void wxStfCursorsDlg::OnComboBoxU2P( wxCommandEvent& event ) { event.Skip(); UpdateUnits(wxCOMBOU2P,cursor2PIsTime,wxTEXT2P); } void wxStfCursorsDlg::OnComboBoxU1B( wxCommandEvent& event ) { event.Skip(); UpdateUnits(wxCOMBOU1B,cursor1BIsTime,wxTEXT1B); } void wxStfCursorsDlg::OnComboBoxU2B( wxCommandEvent& event ) { event.Skip(); UpdateUnits(wxCOMBOU2B,cursor2BIsTime,wxTEXT2B); } void wxStfCursorsDlg::OnComboBoxU1D( wxCommandEvent& event ) { event.Skip(); UpdateUnits(wxCOMBOU1D,cursor1DIsTime,wxTEXT1D); } void wxStfCursorsDlg::OnComboBoxU2D( wxCommandEvent& event ) { event.Skip(); UpdateUnits(wxCOMBOU2D,cursor2DIsTime,wxTEXT2D); } void wxStfCursorsDlg::OnComboBoxU1L( wxCommandEvent& event ) { event.Skip(); wxRadioButton* wxRadio_Lat_Manual1 = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL1); if (wxRadio_Lat_Manual1 == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::OnComboBoxU1LS()")); return; } else wxRadio_Lat_Manual1->SetValue(true); UpdateUnits(wxCOMBOU1L,cursor1LIsTime,wxTEXT1L); } void wxStfCursorsDlg::OnComboBoxU2L( wxCommandEvent& event ) { event.Skip(); wxRadioButton* wxRadio_Lat_Manual2 = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL2); if (wxRadio_Lat_Manual2 == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::OnComboBoxU2LS()")); return; } else wxRadio_Lat_Manual2->SetValue(true); UpdateUnits(wxCOMBOU2L,cursor2LIsTime,wxTEXT2L); } void wxStfCursorsDlg::OnRadioLatManualBeg( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor1L = (wxTextCtrl*)FindWindow(wxTEXT1L); if (pCursor1L == NULL ) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioLatManBeg()")); return; } // if cursor wxTextCtrl is NOT enable2 if (!pCursor1L->IsEnabled()) pCursor1L->Enable(true); } void wxStfCursorsDlg::OnRadioLatManualEnd( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor2L = (wxTextCtrl*)FindWindow(wxTEXT2L); if (pCursor2L == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioLatManEnd()")); return; } // if cursor wxTextCtrl is NOT enabled if (!pCursor2L->IsEnabled()) pCursor2L->Enable(true); } void wxStfCursorsDlg::OnRadioLatNonManualBeg( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor1L = (wxTextCtrl*)FindWindow(wxTEXT1L); wxRadioButton* pLatencyManualEnd = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL2); if (pCursor1L == NULL || pLatencyManualEnd == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioLatt50Beg()")); return; } // disable cursor wxTextCtrl if it is enabled if (pCursor1L->IsEnabled()) pCursor1L->Enable(false); } void wxStfCursorsDlg::OnRadioLatNonManualEnd( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor2L = (wxTextCtrl*)FindWindow(wxTEXT2L); wxRadioButton* pLatencyManualBeg = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL1); if (pCursor2L == NULL || pLatencyManualBeg == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioNonManualEnd()")); return; } // disable cursor wxTextCtrl if it is enabled if (pCursor2L->IsEnabled()) pCursor2L->Enable(false); } #ifdef WITH_PSLOPE void wxStfCursorsDlg::OnComboBoxU1PS( wxCommandEvent& event ) { event.Skip(); // select manual option in "measurement from" box wxRadioButton* pPSManBeg = (wxRadioButton*)FindWindow(wxRADIO_PSManBeg); if (pPSManBeg == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::OnComboBoxU1PS()")); return; } else pPSManBeg->SetValue(true); UpdateUnits(wxCOMBOU1PS,cursor1PSIsTime,wxTEXT1PS); } void wxStfCursorsDlg::OnComboBoxU2PS( wxCommandEvent& event ) { event.Skip(); // select manual option in "measurement to" box wxRadioButton* pPSManEnd = (wxRadioButton*)FindWindow(wxRADIO_PSManEnd); if (pPSManEnd == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::OnComboBoxU2PS()")); return; } else pPSManEnd->SetValue(true); UpdateUnits(wxCOMBOU2PS,cursor2PSIsTime,wxTEXT2PS); } void wxStfCursorsDlg::OnRadioPSManBeg( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor1PS = (wxTextCtrl*)FindWindow(wxTEXT1PS); if (pCursor1PS == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioManBeg()")); return; } // if cursor wxTextCtrl is NOT enabled if (!pCursor1PS->IsEnabled()) pCursor1PS->Enable(true); } void wxStfCursorsDlg::OnRadioPSEventBeg( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor1PS = (wxTextCtrl*)FindWindow(wxTEXT1PS); if ( pCursor1PS == NULL ) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioPSEventBeg()")); return; } // disable cursor wxTextCtrl if it is enabled if (pCursor1PS->IsEnabled()) pCursor1PS->Enable(false); } void wxStfCursorsDlg::OnRadioPSThrBeg( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor1PS = (wxTextCtrl*)FindWindow(wxTEXT1PS); if (pCursor1PS == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioThrBeg()")); return; } // disable cursor wxTextCtrl if it is enabled if (pCursor1PS->IsEnabled()) pCursor1PS->Enable(false); } void wxStfCursorsDlg::OnRadioPSt50Beg( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor1PS = (wxTextCtrl*)FindWindow(wxTEXT1PS); if ( pCursor1PS == NULL ) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioPSt50Beg()")); return; } // disable cursor wxTextCtrl if it is enabled if (pCursor1PS->IsEnabled()) pCursor1PS->Enable(false); } void wxStfCursorsDlg::OnRadioPSManEnd( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor2PS = (wxTextCtrl*)FindWindow(wxTEXT2PS); wxTextCtrl* pTextPSDeltaT = (wxTextCtrl*)FindWindow(wxTEXT_PSDELTAT); if (pCursor2PS == NULL || pTextPSDeltaT == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioManEnd()")); return; } // if cursor wxTextCtrl is NOT enabled if (!pCursor2PS->IsEnabled()) pCursor2PS->Enable(true); if (pTextPSDeltaT->IsEnabled()) pTextPSDeltaT->Enable(false); } void wxStfCursorsDlg::OnRadioPSt50End( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor2PS = (wxTextCtrl*)FindWindow(wxTEXT2PS); wxTextCtrl* pTextPSDeltaT = (wxTextCtrl*)FindWindow(wxTEXT_PSDELTAT); if (pCursor2PS == NULL || pTextPSDeltaT == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioPSt50End()")); return; } // disable cursor wxTextCtrl if it is enabled if (pCursor2PS->IsEnabled()) pCursor2PS->Enable(false); if (pTextPSDeltaT->IsEnabled()) pTextPSDeltaT->Enable(false); SetPSlopeEndMode(stf::psEnd_t50Mode); } void wxStfCursorsDlg::OnRadioPSDeltaT( wxCommandEvent& event) { event.Skip(); wxTextCtrl* pCursor2PS = (wxTextCtrl*)FindWindow(wxTEXT2PS); wxTextCtrl* pTextPSDeltaT = (wxTextCtrl*)FindWindow(wxTEXT_PSDELTAT); if (pCursor2PS == NULL || pTextPSDeltaT == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioPSDeltaT")); return; } // disable cursor wxTextCtrl if it is enabled if (pCursor2PS->IsEnabled()) pCursor2PS->Enable(false); // enable text control if (!pTextPSDeltaT->IsEnabled()) pTextPSDeltaT->Enable(true); SetPSlopeEndMode(stf::psEnd_DeltaTMode); } void wxStfCursorsDlg::OnRadioPSPeakEnd( wxCommandEvent& event ) { event.Skip(); wxTextCtrl* pCursor2PS = (wxTextCtrl*)FindWindow(wxTEXT2PS); wxTextCtrl* pTextPSDeltaT = (wxTextCtrl*)FindWindow(wxTEXT_PSDELTAT); if (pCursor2PS == NULL || pTextPSDeltaT == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioPeakEnd()")); return; } // disable cursor wxTextCtrl if is enabled if (pCursor2PS->IsEnabled()) pCursor2PS->Enable(false); if (pTextPSDeltaT->IsEnabled()) pTextPSDeltaT->Enable(false); SetPSlopeEndMode(stf::psEnd_peakMode); } #endif // WITH_PSLOPE void wxStfCursorsDlg::OnRadioAll( wxCommandEvent& event ) { event.Skip(); wxRadioButton* pRadioAll = (wxRadioButton*)FindWindow(wxRADIOALL); wxRadioButton* pRadioMean = (wxRadioButton*)FindWindow(wxRADIOMEAN); wxTextCtrl* pTextPM = (wxTextCtrl*)FindWindow(wxTEXTPM); if (pTextPM==NULL || pRadioMean==NULL || pRadioAll==NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioAll()")); return; } pTextPM->Enable(false); pRadioMean->SetValue(false); } void wxStfCursorsDlg::OnRadioMean( wxCommandEvent& event ) { event.Skip(); wxRadioButton* pRadioAll = (wxRadioButton*)FindWindow(wxRADIOALL); wxRadioButton* pRadioMean = (wxRadioButton*)FindWindow(wxRADIOMEAN); wxTextCtrl* pTextPM = (wxTextCtrl*)FindWindow(wxTEXTPM); if (pTextPM==NULL || pRadioMean==NULL || pRadioAll==NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::OnRadioMean()")); return; } pTextPM->Enable(true); pRadioAll->SetValue(false); } void wxStfCursorsDlg::OnRTSlider( wxScrollEvent& event ) { event.Skip(); wxSlider *pRTSlider = (wxSlider*)FindWindow(wxRT_SLIDER); wxStaticText *pRTLabel = (wxStaticText*)FindWindow(wxRT_LABEL); if (pRTSlider==NULL || pRTLabel == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg:OnRTSlider()")); return; } wxString label(wxT("Rise time ")); label << pRTSlider->GetValue() << wxT("-"); label << 100-pRTSlider->GetValue() << wxT("\%"); pRTLabel->SetLabel(label); } stf::latency_mode wxStfCursorsDlg::GetLatencyStartMode() const { wxRadioButton* pManual = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL1); wxRadioButton* pPeak = (wxRadioButton*)FindWindow(wxRADIO_LAT_PEAK1); wxRadioButton* pMaxSlope = (wxRadioButton*)FindWindow(wxRADIO_LAT_MAXSLOPE1); wxRadioButton* pt50 = (wxRadioButton*)FindWindow(wxRADIO_LAT_HALFWIDTH1); if (pManual == NULL || pPeak == NULL || pMaxSlope == NULL || pt50 == NULL ) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::GetLatencyStartMode()")); return stf::undefinedMode; } if (pManual->GetValue() ) return stf::manualMode; else if (pPeak->GetValue()) return stf::peakMode; else if (pMaxSlope->GetValue()) return stf::riseMode; else if (pt50->GetValue()) return stf::halfMode; else return stf::undefinedMode; } stf::latency_mode wxStfCursorsDlg::GetLatencyEndMode() const { wxRadioButton* pEvent = (wxRadioButton*)FindWindow(wxRADIO_LAT_EVENT2); wxRadioButton* pManual = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL2); wxRadioButton* pPeak = (wxRadioButton*)FindWindow(wxRADIO_LAT_PEAK2); wxRadioButton* pMaxSlope = (wxRadioButton*)FindWindow(wxRADIO_LAT_MAXSLOPE2); wxRadioButton* pt50 = (wxRadioButton*)FindWindow(wxRADIO_LAT_HALFWIDTH2); if (pEvent == NULL || pManual == NULL || pPeak == NULL || pMaxSlope == NULL || pt50 == NULL ) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::GetLatencyEndMode()")); return stf::undefinedMode; } if (pManual->GetValue() ) { return stf::manualMode; } else { if (pEvent->GetValue()) { return stf::footMode; } else { if (pPeak->GetValue()) { return stf::peakMode; } else { if (pMaxSlope->GetValue()) { return stf::riseMode; } else { if (pt50->GetValue()) { return stf::halfMode; } else { return stf::undefinedMode; } } } } } } void wxStfCursorsDlg::SetLatencyStartMode(stf::latency_mode latencyBegMode){ wxRadioButton* pManual = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL1); wxRadioButton* pPeak = (wxRadioButton*)FindWindow(wxRADIO_LAT_PEAK1); wxRadioButton* pMaxSlope = (wxRadioButton*)FindWindow(wxRADIO_LAT_MAXSLOPE1); wxRadioButton* pt50 = (wxRadioButton*)FindWindow(wxRADIO_LAT_HALFWIDTH1); if (pManual == NULL || pPeak == NULL || pMaxSlope == NULL || pt50 == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::SetLatencyStartMode()")); } switch (latencyBegMode) { case stf::manualMode: pManual->SetValue(true); break; case stf::peakMode: pPeak->SetValue(true); break; case stf::riseMode: pMaxSlope->SetValue(true); break; case stf::halfMode: pt50->SetValue(true); break; default: break; } } void wxStfCursorsDlg::SetLatencyEndMode(stf::latency_mode latencyEndMode){ wxRadioButton* pManual = (wxRadioButton*)FindWindow(wxRADIO_LAT_MANUAL2); wxRadioButton* pPeak = (wxRadioButton*)FindWindow(wxRADIO_LAT_PEAK2); wxRadioButton* pMaxSlope = (wxRadioButton*)FindWindow(wxRADIO_LAT_MAXSLOPE2); wxRadioButton* pt50 = (wxRadioButton*)FindWindow(wxRADIO_LAT_HALFWIDTH2); wxRadioButton* pEvent = (wxRadioButton*)FindWindow(wxRADIO_LAT_EVENT2); if (pManual == NULL || pPeak == NULL || pMaxSlope == NULL || pt50 == NULL || pEvent == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::SetLatencyEndtMode()")); } switch (latencyEndMode) { case stf::manualMode: pManual->SetValue(true); break; case stf::peakMode: pPeak->SetValue(true); break; case stf::riseMode: pMaxSlope->SetValue(true); break; case stf::halfMode: pt50->SetValue(true); break; case stf::footMode: pEvent->SetValue(true); break; default: break; } } #ifdef WITH_PSLOPE stf::pslope_mode_beg wxStfCursorsDlg::GetPSlopeBegMode() const { wxRadioButton* pPSManBeg = (wxRadioButton*)FindWindow(wxRADIO_PSManBeg); wxRadioButton* pPSEventBeg = (wxRadioButton*)FindWindow(wxRADIO_PSEventBeg); wxRadioButton* pPSThrBeg = (wxRadioButton*)FindWindow(wxRADIO_PSThrBeg); wxRadioButton* pPSt50Beg = (wxRadioButton*)FindWindow(wxRADIO_PSt50Beg); if (pPSManBeg == NULL || pPSEventBeg == NULL || pPSThrBeg == NULL || pPSt50Beg == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::OnRadioPSBeg()")); return stf::psBeg_undefined; } if ( pPSManBeg->GetValue() ) return stf::psBeg_manualMode; else if ( pPSEventBeg->GetValue() ) return stf::psBeg_footMode; else if( pPSThrBeg->GetValue() ) return stf::psBeg_thrMode; else if ( pPSt50Beg->GetValue() ) return stf::psBeg_t50Mode; else return stf::psBeg_undefined; } stf::pslope_mode_end wxStfCursorsDlg::GetPSlopeEndMode() const { wxRadioButton* pPSManEnd = (wxRadioButton*)FindWindow(wxRADIO_PSManEnd); wxRadioButton* pPSt50End = (wxRadioButton*)FindWindow(wxRADIO_PSt50End); wxRadioButton* pPSDeltaT = (wxRadioButton*)FindWindow(wxRADIO_PSDeltaT); wxRadioButton* pPSPeakEnd = (wxRadioButton*)FindWindow(wxRADIO_PSPeakEnd); if (pPSManEnd == NULL || pPSt50End == NULL || pPSDeltaT == NULL || pPSPeakEnd == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::GetPSlopeEndMode()")); } if ( pPSManEnd->GetValue() ) return stf::psEnd_manualMode; else if ( pPSt50End->GetValue() ) return stf::psEnd_t50Mode; else if( pPSDeltaT->GetValue() ) return stf::psEnd_DeltaTMode; else if ( pPSPeakEnd->GetValue() ) return stf::psEnd_peakMode; else return stf::psEnd_undefined; // return dlgPSlopeModeEnd; } void wxStfCursorsDlg::SetPSlopeEndMode(stf::pslope_mode_end pslopeEndMode) { wxRadioButton* pPSManBeg = (wxRadioButton*)FindWindow(wxRADIO_PSManBeg); wxRadioButton* pPSEventBeg = (wxRadioButton*)FindWindow(wxRADIO_PSEventBeg); wxRadioButton* pPSThrBeg = (wxRadioButton*)FindWindow(wxRADIO_PSThrBeg); wxRadioButton* pPSt50Beg = (wxRadioButton*)FindWindow(wxRADIO_PSThrBeg); if (pPSManBeg == NULL || pPSEventBeg == NULL || pPSThrBeg == NULL || pPSt50Beg == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::SetPSlopeEndMode()")); return; } switch (pslopeEndMode) { case stf::psBeg_manualMode: pPSManBeg->Enable(true); break; case stf::psBeg_footMode: pPSEventBeg->Enable(true); break; case stf::psBeg_thrMode: pPSThrBeg->Enable(true); break; case stf::psBeg_t50Mode: pPSt50Beg->Enable(true); default: break; } } void wxStfCursorsDlg::SetPSlopeBegMode(stf::pslope_mode_beg pslopeBegMode) { wxRadioButton* pPSManBeg = (wxRadioButton*)FindWindow(wxRADIO_PSManBeg); wxRadioButton* pPSEventBeg = (wxRadioButton*)FindWindow(wxRADIO_PSEventBeg); wxRadioButton* pPSThrBeg = (wxRadioButton*)FindWindow(wxRADIO_PSThrBeg); wxRadioButton* pPSt50Beg = (wxRadioButton*)FindWindow(wxRADIO_PSThrBeg); if (pPSManBeg == NULL || pPSEventBeg == NULL || pPSThrBeg == NULL || pPSt50Beg == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfCursorsDlg::SetPSlopeBegMode()")); return; } switch (pslopeBegMode) { case stf::psBeg_manualMode: pPSManBeg->Enable(true); break; case stf::psBeg_footMode: pPSEventBeg->Enable(true); break; case stf::psBeg_thrMode: pPSThrBeg->Enable(true); break; case stf::psBeg_t50Mode: pPSt50Beg->Enable(true); default: break; } } #endif // WITH_PSLOPE void wxStfCursorsDlg::UpdateUnits(wxWindowID comboId, bool& setTime, wxWindowID textId) { // Read current entry: wxString strRead; wxTextCtrl* pText = (wxTextCtrl*)FindWindow(textId); if (pText == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::UpdateUnits()")); return; } strRead << pText->GetValue(); double fEntry=0.0; strRead.ToDouble( &fEntry ); wxComboBox* pCombo = (wxComboBox*)FindWindow(comboId); if (pCombo == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::UpdateUnits()")); return; } bool isTimeNow=(pCombo->GetCurrentSelection()==0); // switched from pts to time: if (!setTime&&isTimeNow) { // switched from pts to time: double fNewValue=fEntry*actDoc->GetXScale(); wxString strNewValue;strNewValue << fNewValue; pText->SetValue( strNewValue ); setTime=true; } if (setTime&&!isTimeNow) { // switched from time to pts: int iNewValue = stf::round(fEntry/actDoc->GetXScale()); wxString strNewValue; strNewValue << iNewValue; pText->SetValue( strNewValue ); setTime=false; } } void wxStfCursorsDlg::UpdateCursors() { stf::cursor_type select = CurrentCursor(); int iNewValue1=0, iNewValue2=0; bool cursor2isTime=true, cursor1isTime=true; wxTextCtrl* pText1=NULL, *pText2=NULL; if (actDoc == NULL) { throw std::runtime_error("No active document found"); } switch (select) { case stf::measure_cursor: // Measure iNewValue1=(int)actDoc->GetMeasCursor(); cursor1isTime=cursorMIsTime; pText1=(wxTextCtrl*)FindWindow(wxTEXTM); // update Show ruler SetRuler( actDoc->GetMeasRuler() ); break; case stf::peak_cursor: // Peak iNewValue1=(int)actDoc->GetPeakBeg(); iNewValue2=(int)actDoc->GetPeakEnd(); cursor1isTime=cursor1PIsTime; cursor2isTime=cursor2PIsTime; pText1=(wxTextCtrl*)FindWindow(wxTEXT1P); pText2=(wxTextCtrl*)FindWindow(wxTEXT2P); // Update peak at the end SetPeakAtEnd( actDoc->GetPeakAtEnd() ); // Update the mean peak points and direction: SetPeakPoints( actDoc->GetPM() ); SetDirection( actDoc->GetDirection() ); SetFromBase( actDoc->GetFromBase() ); // Update rise time factor SetRTFactor( actDoc->GetRTFactor() ); // Update threshold slope SetSlope( actDoc->GetSlopeForThreshold() ); break; case stf::base_cursor: // Base iNewValue1=(int)actDoc->GetBaseBeg(); iNewValue2=(int)actDoc->GetBaseEnd(); cursor1isTime=cursor1BIsTime; cursor2isTime=cursor2BIsTime; pText1=(wxTextCtrl*)FindWindow(wxTEXT1B); pText2=(wxTextCtrl*)FindWindow(wxTEXT2B); SetBaselineMethod( actDoc->GetBaselineMethod() ); break; case stf::decay_cursor: // Decay iNewValue1=(int)actDoc->GetFitBeg(); iNewValue2=(int)actDoc->GetFitEnd(); cursor1isTime=cursor1DIsTime; cursor2isTime=cursor2DIsTime; pText1=(wxTextCtrl*)FindWindow(wxTEXT1D); pText2=(wxTextCtrl*)FindWindow(wxTEXT2D); // Update left decay cursor to peak SetStartFitAtPeak( actDoc->GetStartFitAtPeak() ); break; case stf::latency_cursor: // Latency iNewValue1= (int)actDoc->GetLatencyBeg(); iNewValue2= (int)actDoc->GetLatencyEnd(); cursor1isTime=cursor1LIsTime; cursor2isTime=cursor2LIsTime; // if GetLatencyStartmode() is zero, textbox is enabled pText1=(wxTextCtrl*)FindWindow(wxTEXT1L); pText1->Enable(!actDoc->GetLatencyStartMode()); // if GetLatencyEndmode() is zero, textbox is enabled pText2=(wxTextCtrl*)FindWindow(wxTEXT2L); pText2->Enable(!actDoc->GetLatencyEndMode()); // use peak for latency measurements? //SetPeak4Latency ( actDoc->GetLatencyWindowMode() ); // Update RadioButton options SetLatencyStartMode( actDoc->GetLatencyStartMode() ); SetLatencyEndMode( actDoc->GetLatencyEndMode() ); break; #ifdef WITH_PSLOPE case stf::pslope_cursor: iNewValue1=(int)actDoc->GetPSlopeBeg(); iNewValue2=(int)actDoc->GetPSlopeEnd(); cursor1isTime = cursor1PSIsTime; cursor2isTime = cursor2PSIsTime; pText1=(wxTextCtrl*)FindWindow(wxTEXT1PS); pText2=(wxTextCtrl*)FindWindow(wxTEXT2PS); // Update PSlope Beg and End radio options SetPSlopeBegMode( actDoc->GetPSlopeBegMode() ); SetPSlopeEndMode( actDoc->GetPSlopeEndMode() ); SetDeltaT( actDoc->GetDeltaT() ); break; #endif default: break; } double fNewValue1=iNewValue1*actDoc->GetXScale(); double fNewValue2=iNewValue2*actDoc->GetXScale(); wxString strNewValue; if (cursor1isTime) { strNewValue << fNewValue1; } else { strNewValue << iNewValue1; } if (pText1 != NULL) { pText1->SetValue( strNewValue ); } if (select!=stf::measure_cursor && pText2 != NULL) { wxString strNewValue2; if (cursor2isTime) { strNewValue2 << fNewValue2; } else { strNewValue2 << iNewValue2; } pText2->SetValue( strNewValue2 ); } //SetSlope( actDoc->GetSlopeForThreshold() ); wxString slopeUnits; slopeUnits += stf::std2wx( actDoc->at(actDoc->GetCurChIndex()).GetYUnits() ); slopeUnits += wxT("/"); slopeUnits += stf::std2wx( actDoc->GetXUnits() ); SetSlopeUnits(slopeUnits); } stf::cursor_type wxStfCursorsDlg::CurrentCursor() const { if (m_notebook == NULL) return stf::undefined_cursor; switch (m_notebook->GetSelection()) { case 0: return stf::measure_cursor; case 1: return stf::peak_cursor; case 2: return stf::base_cursor; case 3: return stf::decay_cursor; case 4: return stf::latency_cursor; #ifdef WITH_PSLOPE case 5: return stf::pslope_cursor; #endif default: return stf::undefined_cursor; } } double wxStfCursorsDlg::GetSlope() const { double f=0.0; wxTextCtrl* pSlope =(wxTextCtrl*) FindWindow(wxSLOPE); if (pSlope == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetSlope()")); return 0; } wxString entry; entry << pSlope->GetValue(); entry.ToDouble( &f ); return f; } void wxStfCursorsDlg::SetSlope( double fSlope ) { wxTextCtrl* pSlope = (wxTextCtrl*)FindWindow(wxSLOPE); wxString wxsSlope; wxsSlope << fSlope; if ( pSlope != NULL ) pSlope->SetValue( wxsSlope ); } void wxStfCursorsDlg::SetSlopeUnits(const wxString& units) { wxStaticText* pSlopeUnits = (wxStaticText*)FindWindow(wxSLOPEUNITS); if (pSlopeUnits != NULL) { pSlopeUnits->SetLabel(units); } } bool wxStfCursorsDlg::GetRuler() const { wxCheckBox* pMeasCursor = (wxCheckBox*)FindWindow(wxMEASCURSOR); if (pMeasCursor == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::GetRuler()")); return false; } return pMeasCursor->IsChecked(); } void wxStfCursorsDlg::SetRuler(bool value) { wxCheckBox* pMeasCursor = (wxCheckBox*)FindWindow( wxMEASCURSOR ); if (pMeasCursor == NULL) { wxGetApp().ErrorMsg(wxT("null pointer in wxStfCursorsDlg::SetRuler()")); return; } pMeasCursor->SetValue(value); } stimfit-0.16.7/src/stimfit/gui/dlgs/convertdlg.cpp0000664000175000017500000002424114750344764015626 #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include #include #include #include "convertdlg.h" #include "./../app.h" enum { wxCOMBOBOX_SRC, wxCOMBOBOX_DEST, wxGENERICDIRCTRL_SRC, wxGENERICDIRCTRL_DEST }; BEGIN_EVENT_TABLE( wxStfConvertDlg, wxDialog ) EVT_COMBOBOX( wxCOMBOBOX_SRC, wxStfConvertDlg::OnComboBoxSrcExt) EVT_COMBOBOX( wxCOMBOBOX_DEST, wxStfConvertDlg::OnComboBoxDestExt) END_EVENT_TABLE() // wxStfConvertDlg constructor wxStfConvertDlg::wxStfConvertDlg(wxWindow* parent, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), srcDir(wxT("")), destDir(wxT("")), srcFilter(wxT("")), myCheckBoxSubdirs(NULL), srcFilterExt(stfio::cfs), destFilterExt(stfio::igor), srcFileNames(0) { if (srcDir == wxT("")) { srcDir = wxGetApp().wxGetProfileString( wxT("Settings"), wxT("Most recent batch source directory"), wxT("")); if (srcDir == wxT("") || !wxFileName::DirExists(srcDir)) { srcDir = wxStandardPaths::Get().GetDocumentsDir(); } } if (destDir == wxT("")) { destDir = wxGetApp().wxGetProfileString( wxT("Settings"), wxT("Most recent batch target directory"), wxT("")); if (destDir == wxT("") || !wxFileName::DirExists(destDir)) { destDir = wxStandardPaths::Get().GetDocumentsDir(); } } wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); //wxFlexGridSizer *gridSizer; //gridSizer = new wxFlexGridSizer(2,2,0,10); wxFlexGridSizer *gridSizer; gridSizer = new wxFlexGridSizer(1,2,0,0); // SOURCE dir ------------------------------------------------------ // wxFlexGridSizer to place a 1) combo + 2) directory listing wxFlexGridSizer *myLeftSizer; // this is a sizer for the left side myLeftSizer = new wxFlexGridSizer(3, 1, 0, 0); // SOURCE 1.- wxComboBox to select the source file extension wxFlexGridSizer *mySrcComboSizer; // a sizer for my Combo mySrcComboSizer = new wxFlexGridSizer(1, 2, 0, 0); wxStaticText* staticTextExt; staticTextExt = new wxStaticText( this, wxID_ANY, wxT("Origin filetype:"), wxDefaultPosition, wxDefaultSize, 0 ); wxArrayString myextensions; myextensions.Add(wxT("CFS binary [*.dat ]")); myextensions.Add(wxT("Axon binary [*.abf ]")); myextensions.Add(wxT("Axograph [*.axgd]")); myextensions.Add(wxT("Axon textfile [*.atf ]")); myextensions.Add(wxT("ASCII [*.* ]")); myextensions.Add(wxT("HDF5 [*.h5 ]")); myextensions.Add(wxT("HEKA files [*.dat ]")); myextensions.Add(wxT("Igor files [*.ibw ]")); wxComboBox* myComboBoxExt; myComboBoxExt = new wxComboBox(this, wxCOMBOBOX_SRC, myextensions[0], wxDefaultPosition, wxDefaultSize, myextensions, wxCB_READONLY); // add to mySrcComboSizer mySrcComboSizer->Add( staticTextExt, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); mySrcComboSizer->Add( myComboBoxExt, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // add to myLeftSizer myLeftSizer->Add( mySrcComboSizer, 0, wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // ---- wxComboBox to select the source file extension // SOURCE 2.- A wxGenericDirCtrl to select the source directory: //wxGenericDirCtrl *mySrcDirCtrl; mySrcDirCtrl = new wxGenericDirCtrl(this, wxGENERICDIRCTRL_SRC, srcDir, wxDefaultPosition, wxSize(300,300), wxDIRCTRL_DIR_ONLY); // add to myLeftSizer myLeftSizer->Add( mySrcDirCtrl, 0, wxEXPAND | wxALL , 2 ); // ---- A wxGenericDirCtrl to select the source directory: myCheckBoxSubdirs = new wxCheckBox( this, wxID_ANY, wxT("Include subdirectories"), wxDefaultPosition, wxDefaultSize, 0 ); myCheckBoxSubdirs->SetValue(false); myLeftSizer->Add( myCheckBoxSubdirs, 0, wxALIGN_LEFT | wxALL, 2 ); // Finally add myLeftSizer to the gridSizer gridSizer->Add( myLeftSizer, 0, wxALIGN_LEFT, 5 ); //topSizer->Add( gridSizer, 0, wxALIGN_CENTER, 5 ); // DESTINATION dir ---------------------------------------------------------- // wxFlexGridSizer to place a 1) combo + 2) directory listing wxFlexGridSizer *myRightSizer; // this is a sizer for the right side myRightSizer = new wxFlexGridSizer(2, 1, 0, 0); // DESTINATION 1.- wxComboBox to select the destiny file extension wxFlexGridSizer *myDestComboSizer; // a sizer for my Combo myDestComboSizer = new wxFlexGridSizer(1, 2, 0, 0); wxStaticText* staticTextDestExt; staticTextDestExt = new wxStaticText( this, wxID_ANY, wxT("Destination filetype:"), wxDefaultPosition, wxDefaultSize, 0 ); wxArrayString mydestextensions; //ordered by importance mydestextensions.Add(wxT("Igor binary [*.ibw ]")); mydestextensions.Add(wxT("Axon textfile [*.atf ]")); #if defined(WITH_BIOSIG) mydestextensions.Add(wxT("GDF (Biosig) [*.gdf ]")); #endif wxComboBox* myComboBoxDestExt; myComboBoxDestExt = new wxComboBox(this, wxCOMBOBOX_DEST, mydestextensions[0], wxDefaultPosition, wxDefaultSize, mydestextensions, wxCB_READONLY); // add to mySrcComboSizer myDestComboSizer->Add( staticTextDestExt, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); myDestComboSizer->Add( myComboBoxDestExt, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // add to myRightSizer myRightSizer->Add( myDestComboSizer, 0, wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // ---- wxComboBox to select the source file extension // DESTINATION 2.- A wxGenericDirCtrl to select the destiny directory: myDestDirCtrl = new wxGenericDirCtrl(this, wxGENERICDIRCTRL_DEST, destDir, wxDefaultPosition, wxSize(300,300), wxDIRCTRL_DIR_ONLY); // add to myLeftSizer myRightSizer->Add( myDestDirCtrl, 0, wxEXPAND | wxALL, 2 ); // ---- A wxGenericDirCtrl to select the source directory: // Finally add myRightSizer to gridSizer and this to topSizer gridSizer->Add( myRightSizer, 0, wxALIGN_RIGHT, 5); topSizer->Add( gridSizer, 0, wxALIGN_CENTER, 5 ); // OK / Cancel buttons----------------------------------------------- wxStdDialogButtonSizer* sdbSizer = new wxStdDialogButtonSizer(); wxButton *myConvertButton; myConvertButton = new wxButton( this, wxID_OK, wxT("C&onvert")); // this for wxWidgets 2.9.1 //myConvertButton->SetBitmap(wxBitmap(wxT("icon_cross.png"), wxBITMAP_TYPE_PNG)); sdbSizer->AddButton(myConvertButton); sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); sdbSizer->Realize(); topSizer->Add( sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfConvertDlg::OnComboBoxDestExt(wxCommandEvent& event){ event.Skip(); wxComboBox* pComboBox = (wxComboBox*)FindWindow(wxCOMBOBOX_DEST); if (pComboBox == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfConvertDlg::OnComboBoxDestExt()")); return; } // update destFilterExt switch(pComboBox->GetSelection()){ case 0: destFilterExt = stfio::igor; break; case 1: destFilterExt = stfio::atf; break; #if defined(WITH_BIOSIG) case 2: destFilterExt = stfio::biosig; break; #endif default: destFilterExt = stfio::igor; } } void wxStfConvertDlg::OnComboBoxSrcExt(wxCommandEvent& event){ event.Skip(); wxComboBox* pComboBox = (wxComboBox*)FindWindow(wxCOMBOBOX_SRC); if (pComboBox == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfConvertDlg::OnComboBoxSrcExt()")); return; } // update srcFilterExt and srcFilter // see index of wxArrayString myextensions to evaluate case switch(pComboBox->GetSelection()){ case 0: srcFilterExt = stfio::cfs; break; case 1: srcFilterExt = stfio::abf; break; case 2: srcFilterExt = stfio::axg; break; case 3: srcFilterExt = stfio::atf; break; case 4: break; case 5: srcFilterExt = stfio::hdf5; break; case 6: srcFilterExt = stfio::heka; break; case 7: srcFilterExt = stfio::igor; break; default: srcFilterExt = stfio::none; } srcFilter = wxT("*") + stf::std2wx(stfio::findExtension(srcFilterExt)); } void wxStfConvertDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { return; } } wxDialog::EndModal(retCode); } bool wxStfConvertDlg::OnOK() { srcDir = mySrcDirCtrl->GetPath(); destDir = myDestDirCtrl->GetPath(); if (!wxDir::Exists(srcDir)) { wxString msg; msg << srcDir << wxT(" doesn't exist"); wxLogMessage(msg); return false; } if (!wxDir::Exists(destDir)) { wxString msg; msg << destDir << wxT(" doesn't exist"); wxLogMessage(msg); return false; } if (!ReadPath(srcDir)) { wxString msg; msg << srcFilter << wxT(" not found in ") << srcDir; wxLogMessage(msg); return false; } wxGetApp().wxWriteProfileString( wxT("Settings"), wxT("Most recent batch source directory"), srcDir); wxGetApp().wxWriteProfileString( wxT("Settings"), wxT("Most recent batch target directory"), destDir); return true; } bool wxStfConvertDlg::ReadPath(const wxString& path) { // Walk through path: wxDir dir(path); if ( !dir.IsOpened() ) { return false; } if (!dir.HasFiles(srcFilter)) { return false; } int dir_flags = myCheckBoxSubdirs->IsChecked() ? wxDIR_FILES | wxDIR_DIRS | wxDIR_HIDDEN : wxDIR_FILES | wxDIR_HIDDEN; wxDir::GetAllFiles(path, &srcFileNames, srcFilter, dir_flags); return true; } stimfit-0.16.7/src/stimfit/gui/dlgs/fitseldlg.cpp0000775000175000017500000003476714750344764015455 #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "./../app.h" #include "./../doc.h" #include "./../view.h" #include "./../graph.h" #include "./fitseldlg.h" #define wxID_LIST 1001 #define wxID_PREVIEW 1002 BEGIN_EVENT_TABLE( wxStfFitSelDlg, wxDialog ) EVT_LIST_ITEM_SELECTED( wxID_LIST, wxStfFitSelDlg::OnListItemSelected ) EVT_BUTTON( wxID_PREVIEW, wxStfFitSelDlg::OnButtonClick ) END_EVENT_TABLE() wxStfFitSelDlg::wxStfFitSelDlg(wxWindow* parent, wxStfDoc* doc, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), m_fselect(18), init_p(0), opts(6), noInput(false), use_scaling(false), paramDescArray(MAXPAR), paramEntryArray(MAXPAR), pDoc(doc) { // Check www.ics.forth.gr/~lourakis/levmar/levmar.pdf for details // if you change values here, please change src/stimfit/py/pystf.cxx accordingly //opts[0]=5*1E-3; //default: 1E-03; opts[0] = 1E-05; //scale for initial damping term, default: 1E-03; opts[1] = 1E-17; //stopping thr. for ||J^T e||, default: 1E-17; opts[2] = 1E-17; //stopping thr. for ||Dp||_2, default: 1E-17; opts[3] = 1E-32; //stopping thr. for squared diff ||e||_2, default: 1E-17; opts[4] = 64; //max number of iterations (Kmax), default: 64; opts[5] = 16; //max number of pass per iteration; wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); // 2-column sizer for funcs (left) and settings (right) wxFlexGridSizer* mainGrid = new wxFlexGridSizer(1,2,0,5); wxStaticBoxSizer* m_listSizer = new wxStaticBoxSizer( wxVERTICAL, this, wxT("Available functions") ); m_listCtrl = new wxListCtrl( this, wxID_LIST, wxDefaultPosition, wxSize(550,400), wxLC_LIST ); int n_f = 0; for (c_stfunc_it cit = wxGetApp().GetFuncLib().begin(); cit != wxGetApp().GetFuncLib().end(); cit++) { wxString funcName; funcName << wxString::Format(wxT("%2d: "), n_f) << stf::std2wx(cit->name); m_listCtrl->InsertItem( n_f++, funcName ); } m_listSizer->Add( m_listCtrl, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2 ); mainGrid->Add( m_listSizer, 0, wxALIGN_CENTER_HORIZONTAL, 2 ); // vertical sizer for initial parameters (top) and options (bottom) wxBoxSizer* settingsSizer; settingsSizer=new wxBoxSizer(wxVERTICAL); wxStaticBoxSizer* paramSizer = new wxStaticBoxSizer( wxVERTICAL, this, wxT("Initial parameters") ); // grid for parameters: wxFlexGridSizer* paramGrid; paramGrid=new wxFlexGridSizer(0,4,0,4); // add parameter boxes: std::vector< wxStaticText* >::iterator it1; std::vector< wxTextCtrl* >::iterator it2 = paramEntryArray.begin(); for (it1 = paramDescArray.begin(); it1 != paramDescArray.end() && it2 != paramEntryArray.end(); it1++) { *it1 = new wxStaticText( this, wxID_ANY, wxT(" "), wxDefaultPosition, wxSize(74,20), wxTE_LEFT ); paramGrid->Add( *it1, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2 ); *it2 = new wxTextCtrl( this, wxID_ANY, wxT(" "), wxDefaultPosition, wxSize(74,20), wxTE_RIGHT ); paramGrid->SetFlexibleDirection(wxHORIZONTAL); paramGrid->Add( *it2, 0, wxALIGN_CENTER_VERTICAL | wxALL, 2 ); it2++; } //settingsSizer->Add( paramGrid, 0, wxALIGN_CENTER_HORIZONTAL, 2 ); paramSizer->Add( paramGrid, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 2 ); settingsSizer->Add( paramSizer, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 2 ); // Fit options: // grid for parameters: wxFlexGridSizer* optionsGrid; optionsGrid=new wxFlexGridSizer(opts.size()+1, 2, 0, 0); wxStaticBoxSizer* fitoptSizer = new wxStaticBoxSizer( wxVERTICAL, this, wxT("Fitting options") ); InitOptions(optionsGrid); // add the options grid to the settings sizer: fitoptSizer->Add( optionsGrid, 0, wxEXPAND | wxALL, 2 ); settingsSizer->Add( fitoptSizer, 0, wxALIGN_CENTER_HORIZONTAL, 2 ); //settingsSizer->Add( optionsGrid, 0, wxALIGN_CENTER_HORIZONTAL | wxALIGN_BOTTOM, 2 ); // add the settings sizer to the main grid: mainGrid->Add( settingsSizer, 0, wxALIGN_CENTER_HORIZONTAL, 2 ); // add the main grid to the dialog: topSizer->Add( mainGrid, 0, wxALIGN_CENTER_HORIZONTAL| wxALL, 5 ); // Ok / Cancel / Preview: wxButton* previewButton; previewButton = new wxButton( this, wxID_PREVIEW, wxT("Preview"), wxDefaultPosition, wxDefaultSize, 0 ); topSizer->Add( previewButton, 0, wxALIGN_CENTER | wxALL, 2 ); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER| wxALL, 2 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); // select first function: if (m_listCtrl->GetItemCount()>0) { m_listCtrl->SetItemState(0,wxLIST_STATE_SELECTED,wxLIST_STATE_SELECTED); } } void wxStfFitSelDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) switch (retCode) { case wxID_OK: if (!OnOK()) { wxLogMessage(wxT("Please select a valid function")); return; } break; case wxID_CANCEL: try { pDoc->DeleteFit(pDoc->GetCurChIndex(), pDoc->GetCurSecIndex()); } catch (const std::out_of_range& e) { } break; default: ; } wxDialog::EndModal(retCode); } bool wxStfFitSelDlg::OnOK() { Update_fselect(); read_init_p(); read_opts(); // wxStfDoc* pDoc=pDoc; // pDoc->cur().SetIsFitted(false); // pDoc->cur().SetFit(Vector_double(0)); return true; } void wxStfFitSelDlg::InitOptions(wxFlexGridSizer* optionsGrid) { // Number of passes-------------------------------------------------- wxStaticText* staticTextNPasses; staticTextNPasses=new wxStaticText( this, wxID_ANY, wxT("Max. number of passes:"), wxDefaultPosition, wxDefaultSize, 0 ); optionsGrid->Add( staticTextNPasses, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strNPasses; strNPasses << opts[5]; m_textCtrlMaxpasses = new wxTextCtrl( this, wxID_ANY, strNPasses, wxDefaultPosition, wxSize(74,20), wxTE_RIGHT ); optionsGrid->Add( m_textCtrlMaxpasses, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Number of iterations---------------------------------------------- wxStaticText* staticTextNIter; staticTextNIter=new wxStaticText( this, wxID_ANY, wxT("Max. number of iterations per pass:"), wxDefaultPosition, wxDefaultSize, 0 ); optionsGrid->Add( staticTextNIter, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strNIter; strNIter << opts[4]; m_textCtrlMaxiter=new wxTextCtrl( this, wxID_ANY, strNIter, wxDefaultPosition, wxSize(74,20), wxTE_RIGHT ); optionsGrid->Add( m_textCtrlMaxiter, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Initial scaling factor-------------------------------------------- wxStaticText* staticTextMu; staticTextMu=new wxStaticText( this, wxID_ANY, wxT("Initial scaling factor:"), wxDefaultPosition, wxDefaultSize, 0 ); optionsGrid->Add( staticTextMu, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strMu; strMu << opts[0]; m_textCtrlMu=new wxTextCtrl( this, wxID_ANY, strMu, wxDefaultPosition, wxSize(74,20), wxTE_RIGHT ); optionsGrid->Add( m_textCtrlMu, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Gradient of squared error----------------------------------- wxStaticText* staticTextJTE; staticTextJTE=new wxStaticText( this, wxID_ANY, wxT("Stop. thresh. for gradient of squared error:"), wxDefaultPosition, wxDefaultSize, 0 ); optionsGrid->Add( staticTextJTE, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strJTE; strJTE << opts[1]; m_textCtrlJTE=new wxTextCtrl( this, wxID_ANY, strJTE, wxDefaultPosition, wxSize(74,20), wxTE_RIGHT ); optionsGrid->Add( m_textCtrlJTE, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Parameter gradient------------------------------------------------ wxStaticText* staticTextDP; staticTextDP=new wxStaticText( this, wxID_ANY, wxT("Stop. thresh. for rel. parameter change:"), wxDefaultPosition, wxDefaultSize, 0 ); optionsGrid->Add( staticTextDP, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strDP; strDP << opts[2]; m_textCtrlDP=new wxTextCtrl( this, wxID_ANY, strDP, wxDefaultPosition, wxSize(74,20), wxTE_RIGHT ); optionsGrid->Add( m_textCtrlDP, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Squared error----------------------------------------------------- wxStaticText* staticTextE2; staticTextE2=new wxStaticText( this, wxID_ANY, wxT("Stop. thresh. for squared error:"), wxDefaultPosition, wxDefaultSize, 0 ); optionsGrid->Add( staticTextE2, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString strE2; strE2 << opts[3]; m_textCtrlE2=new wxTextCtrl( this, wxID_ANY, strE2, wxDefaultPosition, wxSize(74,20), wxTE_RIGHT ); optionsGrid->Add( m_textCtrlE2, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); // Use scaling------------------------------------------------------- m_checkBox = new wxCheckBox(this, wxID_ANY, wxT("Scale data amplitude to 1.0"), wxDefaultPosition, wxDefaultSize, 0); m_checkBox->SetValue(false); optionsGrid->Add( m_checkBox, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); } void wxStfFitSelDlg::OnButtonClick( wxCommandEvent& event ) { event.Skip(); // Make sure we are up-to-date: Update_fselect(); // read in parameters: read_init_p(); // tell the document that a fit has been performed: if (pDoc==0) { wxGetApp().ErrorMsg(wxT("Couldn't connect to document")); return; } // calculate a graph from the current parameters: std::size_t fitSize= pDoc->GetFitEnd()-pDoc->GetFitBeg(); Vector_double fit(fitSize); for (std::size_t n_f=0;n_fGetXScale()*n_f,init_p ); } catch (const std::out_of_range& e) { wxString msg(wxT("Could not retrieve selected function from library:\n")); msg += wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(msg); m_fselect=-1; return; } } try { pDoc->SetIsFitted(pDoc->GetCurChIndex(), pDoc->GetCurSecIndex(), init_p, wxGetApp().GetFuncLibPtr(m_fselect), 0, pDoc->GetFitBeg(), pDoc->GetFitEnd() ); } catch (const std::out_of_range& e) { } // tell the view to draw the fit: wxStfView* pView = (wxStfView*)pDoc->GetFirstView(); if (pView != NULL) if (pView->GetGraph() != NULL) pView->GetGraph()->Refresh(); } void wxStfFitSelDlg::SetPars() { Update_fselect(); // get parameter names from selected function: try { // fill a temporary array: if (pDoc==NULL) return; std::size_t fitSize= pDoc->GetFitEnd()-pDoc->GetFitBeg(); if (fitSize<=0) { wxGetApp().ErrorMsg(wxT("Check fit cursor settings")); return; } Vector_double x(fitSize); //fill array: std::copy(&pDoc->cursec()[pDoc->GetFitBeg()], &pDoc->cursec()[pDoc->GetFitBeg()+fitSize], &x[0]); Vector_double initPars(wxGetApp().GetFuncLib().at(m_fselect).pInfo.size()); wxGetApp().GetFuncLib().at(m_fselect).init( x, pDoc->GetBase(), pDoc->GetPeak(), pDoc->GetRTLoHi(), pDoc->GetHalfDuration(), pDoc->GetXScale(), initPars); std::vector< wxStaticText* >::iterator it1; std::vector< wxTextCtrl* >::iterator it2 = paramEntryArray.begin(); std::size_t n_p = 0; for (it1 = paramDescArray.begin(); it1 != paramDescArray.end() && it2 != paramEntryArray.end(); it1++) { if (n_p < wxGetApp().GetFuncLib().at(m_fselect).pInfo.size()) { (*it1)->Show(); (*it2)->Show(); // Parameter label: (*it1)->SetLabel(stf::std2wx(wxGetApp().GetFuncLib().at(m_fselect).pInfo[n_p].desc)); // Initial parameter values: wxString strInit; strInit << initPars[n_p]; (*it2)->SetValue(strInit); (*it2)->Enable(!noInput); } else { (*it1)->Show(false); (*it2)->Show(false); } it2++; n_p++; } } catch (const std::out_of_range& e) { wxString msg(wxT("Could not retrieve selected function from library:\n")); msg += wxString( e.what(), wxConvLocal ); wxLogMessage(msg); m_fselect = -1; return; } this->Layout(); } void wxStfFitSelDlg::Update_fselect() { // Update currently selected function: if (m_listCtrl->GetSelectedItemCount()>0) { // Get first selected item: long item = -1; item=m_listCtrl->GetNextItem(item,wxLIST_NEXT_ALL,wxLIST_STATE_SELECTED); if (item==-1) return; m_fselect = item; } } void wxStfFitSelDlg::OnListItemSelected( wxListEvent& event ) { event.Skip(); SetPars(); } void wxStfFitSelDlg::read_init_p() { init_p.resize(wxGetApp().GetFuncLib().at(m_fselect).pInfo.size()); for (std::size_t n_p=0;n_pGetValue(); entryInit.ToDouble( &init_p[n_p] ); } } void wxStfFitSelDlg::read_opts() { // Read entry to string: wxString entryMu = m_textCtrlMu->GetValue(); entryMu.ToDouble( &opts[0] ); wxString entryJTE = m_textCtrlJTE->GetValue(); entryJTE.ToDouble( &opts[1] ); wxString entryDP = m_textCtrlDP->GetValue(); entryDP.ToDouble( &opts[2] ); wxString entryE2 = m_textCtrlE2->GetValue(); entryE2.ToDouble( &opts[3] ); wxString entryMaxiter = m_textCtrlMaxiter->GetValue(); entryMaxiter.ToDouble( &opts[4] ); wxString entryMaxpasses = m_textCtrlMaxpasses->GetValue(); entryMaxpasses.ToDouble( &opts[5] ); use_scaling = m_checkBox->GetValue(); } stimfit-0.16.7/src/stimfit/gui/dlgs/eventdlg.cpp0000775000175000017500000002114414750344764015271 #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "./../../stf.h" #include "./eventdlg.h" #include "./../app.h" enum { wxID_COMBOTEMPLATES, wxID_CRITERIA, wxDETECTIONCLEMENTS, wxDETECTIONJONAS, wxDETECTIONPERNIA }; BEGIN_EVENT_TABLE( wxStfEventDlg, wxDialog ) EVT_RADIOBUTTON( wxDETECTIONCLEMENTS, wxStfEventDlg::OnClements ) EVT_RADIOBUTTON( wxDETECTIONJONAS, wxStfEventDlg::OnJonas ) EVT_RADIOBUTTON( wxDETECTIONPERNIA, wxStfEventDlg::OnPernia ) END_EVENT_TABLE() wxStfEventDlg::wxStfEventDlg(wxWindow* parent, const std::vector& templateSections, bool isExtract_, int id, wxString title, wxPoint pos, wxSize size, int style) : wxDialog( parent, id, title, pos, size, style ), m_threshold(4.0), m_mode(stf::criterion), isExtract(isExtract_), m_minDistance(150), m_template(-1) { wxBoxSizer* topSizer; topSizer = new wxBoxSizer( wxVERTICAL ); wxFlexGridSizer* templateSizer = new wxFlexGridSizer(2,1,0,0); wxStaticText* staticTextTempl = new wxStaticText( this, wxID_ANY, wxT("Select template fit from section:"), wxDefaultPosition, wxDefaultSize, 0 ); templateSizer->Add( staticTextTempl, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxArrayString templateNames; templateNames.Alloc(templateSections.size()); int max_w = 0; for (std::size_t n_templ=0;n_templGetSectionDescription()); if (sec_desc.empty()) { sec_desc = wxT("Section "); sec_desc << n_templ; } int w, h; GetTextExtent( sec_desc, &w, &h ); if ( w > max_w ) max_w = w; templateNames.Add( sec_desc ); } } m_comboBoxTemplates = new wxComboBox( this, wxID_COMBOTEMPLATES, wxT("1"), wxDefaultPosition, wxSize( max_w + 36, 24 ), templateNames, wxCB_DROPDOWN | wxCB_READONLY ); if (templateSections.size()>0) { m_comboBoxTemplates->SetSelection(0); } templateSizer->Add( m_comboBoxTemplates, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); topSizer->Add( templateSizer, 0, wxALIGN_CENTER | wxALL, 5 ); if (isExtract) { wxFlexGridSizer* gridSizer; gridSizer=new wxFlexGridSizer(2,2,0,0); wxStaticText* staticTextThr; staticTextThr = new wxStaticText( this, wxID_CRITERIA, wxT("Threshold:"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextThr, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString def; def << m_threshold; m_textCtrlThr = new wxTextCtrl( this, wxID_ANY, def, wxDefaultPosition, wxSize(40,20), wxTE_RIGHT ); gridSizer->Add( m_textCtrlThr, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxStaticText* staticTextDist; staticTextDist = new wxStaticText( this, wxID_ANY, wxT("Min. distance between events (# points):"), wxDefaultPosition, wxDefaultSize, 0 ); gridSizer->Add( staticTextDist, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString def2; def2 << m_minDistance; m_textCtrlDist = new wxTextCtrl( this, wxID_ANY, def2, wxDefaultPosition, wxSize(40,20), wxTE_RIGHT ); gridSizer->Add( m_textCtrlDist, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 2 ); topSizer->Add( gridSizer, 0, wxALIGN_CENTER | wxALL, 5 ); //*** Radio options for event detection methods ***// m_radioBox = new wxStaticBoxSizer( wxVERTICAL, this, wxT("Detection method")); wxString m_radioBoxChoices[] = { wxT("Template scaling (Clements && Bekkers)"), wxT("Correlation coefficient (Jonas et al.)"), wxT("Deconvolution (Pernia-Andrade et al.)") }; wxRadioButton* wxRadioClements = new wxRadioButton(this, wxDETECTIONCLEMENTS, m_radioBoxChoices[0], wxDefaultPosition, wxDefaultSize, wxRB_GROUP); wxRadioButton* wxRadioJonas = new wxRadioButton(this, wxDETECTIONJONAS, m_radioBoxChoices[1], wxDefaultPosition, wxDefaultSize); wxRadioButton* wxRadioPernia = new wxRadioButton(this, wxDETECTIONPERNIA, m_radioBoxChoices[2], wxDefaultPosition, wxDefaultSize); m_radioBox->Add(wxRadioClements, 0, wxALIGN_LEFT | wxALL, 2); m_radioBox->Add(wxRadioJonas, 0, wxALIGN_LEFT | wxALL, 2); m_radioBox->Add(wxRadioPernia, 0, wxALIGN_LEFT | wxALL, 2); //m_radioBox->SetSelection(0); topSizer->Add( m_radioBox, 0, wxALIGN_CENTER | wxALL, 5 ); } m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER | wxALL, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfEventDlg::EndModal(int retCode) { wxCommandEvent unusedEvent; // similar to overriding OnOK in MFC (I hope...) switch( retCode) { case wxID_OK: if (!OnOK()) { wxLogMessage(wxT("Select a detection method")); return; } break; case wxID_CANCEL: break; default: return; } wxDialog::EndModal(retCode); } bool wxStfEventDlg::OnOK() { // Read template: m_template = m_comboBoxTemplates->GetCurrentSelection(); if (m_template<0) { wxLogMessage(wxT("Please select a valid template")); return false; } if (isExtract) { // Read entry to string: m_textCtrlThr->GetValue().ToDouble( &m_threshold ); long tempLong; m_textCtrlDist->GetValue().ToLong( &tempLong ); m_minDistance = (int)tempLong; wxRadioButton* wxRadioClements = (wxRadioButton*)FindWindow(wxDETECTIONCLEMENTS); wxRadioButton* wxRadioJonas = (wxRadioButton*)FindWindow(wxDETECTIONJONAS); wxRadioButton* wxRadioPernia = (wxRadioButton*)FindWindow(wxDETECTIONPERNIA); if ( wxRadioClements->GetValue() ) m_mode = stf::criterion; else if ( wxRadioJonas->GetValue() ) m_mode = stf::correlation; else if ( wxRadioPernia->GetValue() ) m_mode = stf::deconvolution; else return false; /*switch (m_radioBox->GetSelection()) { case 0: m_mode = stf::criterion; break; case 1: m_mode = stf::correlation; break; case 2: m_mode = stf::deconvolution; break; }*/ if (m_mode==stf::correlation && (m_threshold<0 || m_threshold>1)) { wxLogMessage(wxT("Please select a value between 0 and 1 for the correlation coefficient")); return false; } } return true; } void wxStfEventDlg::OnClements( wxCommandEvent& event) { event.Skip(); wxRadioButton* wxRadioClements = (wxRadioButton*)FindWindow(wxDETECTIONCLEMENTS); wxStaticText* staticTextThr = (wxStaticText*)FindWindow(wxID_CRITERIA); if (wxRadioClements == NULL || staticTextThr == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfEvenDlg::OnClements()")); return; } staticTextThr->SetLabel(wxT("Threshold:")); } void wxStfEventDlg::OnJonas( wxCommandEvent& event) { event.Skip(); wxRadioButton* wxRadioJonas = (wxRadioButton*)FindWindow(wxDETECTIONJONAS); wxStaticText* staticTextThr = (wxStaticText*)FindWindow(wxID_CRITERIA); if (wxRadioJonas == NULL || staticTextThr == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfEvenDlg::OnJonas()")); return; } staticTextThr->SetLabel(wxT("Correlation:")); } void wxStfEventDlg::OnPernia( wxCommandEvent& event) { event.Skip(); wxRadioButton* wxRadioPernia = (wxRadioButton*)FindWindow(wxDETECTIONPERNIA); wxStaticText* staticTextThr = (wxStaticText*)FindWindow(wxID_CRITERIA); if (wxRadioPernia == NULL || staticTextThr == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfEvenDlg::OnPernia()")); return; } staticTextThr->SetLabel( wxT("Standard deviation:") ); } stimfit-0.16.7/src/stimfit/gui/dlgs/cursorsdlg.h0000775000175000017500000003353014750344764015317 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file cursorsdlg.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfCursorsDlg. */ #ifndef _CURSORSDLG_H #define _CURSORSDLG_H /*! \addtogroup wxstf * @{ */ #include "./../../stf.h" #include #include #include #include #include class wxStfDoc; //! Cursor settings non-modal dialog class StfDll wxStfCursorsDlg : public wxDialog { DECLARE_EVENT_TABLE() private: wxNotebookPage* CreateMeasurePage(); wxNotebookPage* CreatePeakPage(); wxNotebookPage* CreateBasePage(); wxNotebookPage* CreateDecayPage(); wxNotebookPage* CreateLatencyPage(); #ifdef WITH_PSLOPE wxNotebookPage* CreatePSlopePage(); #endif wxFlexGridSizer* CreateCursorInput( wxPanel* nbPage, wxWindowID textC1, wxWindowID textC2, wxWindowID comboU1, wxWindowID comboU2, std::size_t c1, std::size_t c2 ); int ReadCursor(wxWindowID textId, bool isTime) const; void WriteCursor(wxWindowID textID, bool isTime, long cursor) const; int ReadDeltaT(wxWindowID textId) const; void UpdateUnits(wxWindowID comboId, bool& setTime, wxWindowID textID); bool cursorMIsTime, cursor1PIsTime,cursor2PIsTime, cursor1BIsTime,cursor2BIsTime, cursor1DIsTime,cursor2DIsTime, #ifdef WITH_PSLOPE cursor1PSIsTime,cursor2PSIsTime, #endif cursor1LIsTime,cursor2LIsTime; wxStfDoc* actDoc; wxNotebook* m_notebook; void OnPageChanged( wxNotebookEvent& event ); void OnComboBoxUM( wxCommandEvent& event ); void OnComboBoxU1P( wxCommandEvent& event ); void OnComboBoxU2P( wxCommandEvent& event ); void OnComboBoxU1B( wxCommandEvent& event ); void OnComboBoxU2B( wxCommandEvent& event ); void OnComboBoxU1D( wxCommandEvent& event ); void OnComboBoxU2D( wxCommandEvent& event ); void OnComboBoxU1L( wxCommandEvent& event ); void OnComboBoxU2L( wxCommandEvent& event ); #ifdef WITH_PSLOPE void OnComboBoxU1PS( wxCommandEvent& event ); void OnComboBoxU2PS( wxCommandEvent& event ); #endif void OnRadioLatManualBeg( wxCommandEvent& event ); void OnRadioLatManualEnd( wxCommandEvent& event ); void OnRadioLatNonManualBeg( wxCommandEvent& event ); void OnRadioLatNonManualEnd( wxCommandEvent& event ); #ifdef WITH_PSLOPE void OnRadioPSManBeg( wxCommandEvent& event ); void OnRadioPSEventBeg( wxCommandEvent& event ); void OnRadioPSThrBeg( wxCommandEvent& event ); void OnRadioPSt50Beg( wxCommandEvent& event ); void OnRadioPSManEnd( wxCommandEvent& event ); void OnRadioPSt50End( wxCommandEvent& event ); void OnRadioPSDeltaT( wxCommandEvent& event ); void OnRadioPSPeakEnd( wxCommandEvent& event ); #endif void OnRadioAll( wxCommandEvent& event ); void OnRadioMean( wxCommandEvent& event ); void OnPeakcalcexec( wxCommandEvent& event ); void OnLoadCursorConf( wxCommandEvent& event ); void OnSaveCursorConf( wxCommandEvent& event ); void OnBasetoslope( wxCommandEvent& event ); void OnRTSlider( wxScrollEvent& event ); void OnPeakAtEnd( wxCommandEvent& event ); void OnStartFitAtPeak( wxCommandEvent& event ); //! check the syntax of csr config files and return true if the syntax is correct. /*! \param crs_file, a crs config file */ bool IsCSRSyntax( wxFileConfig* crs_file ); //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param initDoc Pointer to the document the call originated from. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfCursorsDlg( wxWindow* parent, wxStfDoc* initDoc, int id = wxID_ANY, wxString title = wxT("Cursor settings"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); //! Called when data should be transferred from the non-modal dialog (e.g. when OK is pressed) /*! Note that a non-modal dialog won't be destroyed when OK is clicked, * it will only disappear from sight. This function will then apply the current * cursor settings and update the results table. * \return The return value of the base class version wxWindow::TransferDataFromWindow() */ virtual bool TransferDataFromWindow(); //! Get the measurement cursor x-position /*! \return The measurement cursor x-position in units of sampling points. */ int GetCursorM() const; //! Get the left peak cursor x-position /*! \return The left peak cursor x-position in units of sampling points. */ int GetCursor1P() const; //! Get the right peak cursor x-position /*! \return The right peak cursor x-position in units of sampling points. */ int GetCursor2P() const; //! Get the left base cursor x-position /*! \return The left base cursor x-position in units of sampling points. */ int GetCursor1B() const; //! Get the right base cursor x-position /*! \return The right base cursor x-position in units of sampling points. */ int GetCursor2B() const; //! Get the left fit cursor x-position /*! \return The left fit cursor x-position in units of sampling points. */ int GetCursor1D() const; //! Get the right fit cursor x-position /*! \return The right fit cursor x-position in units of sampling points. */ int GetCursor2D() const; //! Get the left latency cursor x-position /*! \return The left fit cursor x-position in units of sampling points. */ int GetCursor1L() const; //! Get the right latency cursor x-position /*! \return The right fit cursor x-position in units of sampling points. */ int GetCursor2L() const; #ifdef WITH_PSLOPE //! Get the left PSlope cursor x-position /*! \return The left fit cursor x-position in units of sampling points. */ int GetCursor1PS() const; //! Get the right PSlope cursor x-position /*! \return The right fit cursor x-position in units of sampling points. */ int GetCursor2PS() const; #endif //! Gets the number of points used for the binned average during peak detection. /*! \return The number of points used for the binned average during peak detection. */ int GetPeakPoints() const; //! Gets the lower factor (e.g 20) used to calculate the rise time. /*! \return The lower value of the percentage (e.g 20) to calculate the rise time. */ int GetRTFactor() const; //! Sets whether the right peak cursor should be at the end of the trace. /*! \param is_end true if the peak cursor is at the end of the trace, false otherwise. */ void SetPeakAtEnd( bool is_end); //! Sets the number of points used for the binned average during peak detection. /*! \param peakPoints The number of points used for the binned average during peak detection. */ void SetPeakPoints(int peakPoints); //! Set the lower value (e.g 20) to compute the rise-time. The high value is simply 100-lower value. /*! \param RTFactor is the lower value (e.g 20) . */ void SetRTFactor(int RTFactor); //! Gets the distance to the first PSlope cursor in number of points. /*! \return The distance to the first PSlope cursor in number of points. */ int GetDeltaT() const; //! Sets the number of points used for the distance from the first PSlope cursor. /*! \param peakPoints The number of points used for the distance from the first PSlope cursor. */ void SetDeltaT(int DeltaT); //! Sets whether the left decay cursor should be at the peak of the trace. /*! \param is_peak true if the decay cursor is at the peak of the trace, false otherwise. */ void SetStartFitAtPeak( bool is_peak); //! Gets the direction of peak calculations. /*! \return The current direction of peak calculations. */ stfnum::direction GetDirection() const; //! Gets the mode of Latency for the beginning of the latency cursor. /*! \return The current mode for the beginning latency cursor. */ stf::latency_mode GetLatencyStartMode() const; //! Gets the mode of Latency of the last latency cursor. /*! \return The current mode of the last latency cursor. */ stf::latency_mode GetLatencyEndMode() const; //! Sets the latency mode of the left latency cursor. /*! \param latencyBegMode: the new mode for the left latency cursor. */ void SetLatencyStartMode(stf::latency_mode latencyBegMode); //! Sets the latency mode of the right latency cursor. /*! \param latencyEndMode: the new mode for the right latency cursor. */ void SetLatencyEndMode(stf::latency_mode latencyEndMode); #ifdef WITH_PSLOPE //! Gets the mode of measure for the beginning of the slope cursor. /*! \return The current mode for the beginning slope cursor. */ stf::pslope_mode_beg GetPSlopeBegMode() const; //! Gets the mode of measure for the end of the slope cursor. /*! \return The current mode for the end slope cursor. */ stf::pslope_mode_end GetPSlopeEndMode() const; #endif // WITH_PSLOPE //! Indicates whether to use the baseline as a reference for AP kinetics. /*! \return true if the baseline should be used, false if the threshold should be used. */ bool GetFromBase() const; //! Sets the direction of peak calculations. /*! \param direction The new direction of peak calculations. */ void SetDirection(stfnum::direction direction); #ifdef WITH_PSLOPE //! Sets the mode of the right slope cursor. /*! \param pslopeEndMode The new mode for the slope cursor. */ void SetPSlopeEndMode(stf::pslope_mode_end pslopeEndMode); //! Sets the mode of the left slope cursor. /*! \param pslopeBegMode The new mode for the slope cursor. */ void SetPSlopeBegMode(stf::pslope_mode_beg pslopeBegMode); #endif // WITH_PSLOPE //! Sets the reference for AP kinetics measurements. /*! \param frombase true if the baseline should be used, false if the threshold should be used. */ void SetFromBase(bool frombase); //! Sets the reference for baseline measurement. /*! \param median true if the median should be used, false if the average is used. */ void SetBaselineMethod(enum stfnum::baseline_method); //! Indiates whether baseline is computed as mean or as median. /*! \param false indicates computing average (mean & s.d.), 1 indicates median & iqr. */ enum stfnum::baseline_method GetBaselineMethod() const; //! Indicates whether the right peak cursor should always be at the end of the trace. /*! \return true if the peak cursor should always be at the end of the trace. */ bool GetPeakAtEnd() const; //! Indicates whether to always start a fit at the current peak position. /*! \return true if the fit should always be started at the current peak position. */ bool GetStartFitAtPeak() const; //! Updates the cursor entries in the Cursors Settings menu. void UpdateCursors(); //! Retrieve the current cursor notebook page. /*! \return The cursor corresponding to the currently selected notebook page. */ stf::cursor_type CurrentCursor() const; //! Get the slope at which the baseline should be fixed. /*! \return The slope at which the baseline should be fixed. */ double GetSlope() const; //! Set the threshold slope. /*! \param slope The new threshold slope. */ void SetSlope( double slope ); //! Set the units of the slope. /*! \param units The units of the slope. */ void SetSlopeUnits(const wxString& units); //! Indicates whether the baseline should be fixed to a certain slope. /*! \return true if the baseline should be fixed, false otherwise. */ bool GetBaseToSlope() const; //! Indicates whether an additional vertical ruler is drawn through the measurement cursor. /*! \return true if an additional ruler should be drawn. */ bool GetRuler() const; //! Sets whether an additional vertical ruler should be drawn through the measurement cursor. /*! \param value true if an additional ruler should be drawn, false otherwise. */ void SetRuler(bool value); //! Load a cursor configuration file (*csr) in the Cursor Settings menu. /*! \param filepath The path where the csr file is located. */ bool LoadCursorConf( const wxString& filepath ); //! Save a cursor configuration file (*csr) from the Cursor Settings menu. /*! \param filepath The path where the csr file will be saved */ bool SaveCursorConf( const wxString& filepath ); //! Sets the currently active document. /*! \param actDoc_ A pointer to the currently active document. */ void SetActiveDoc(wxStfDoc* actDoc_) { actDoc = actDoc_; } }; /* @} */ #endif stimfit-0.16.7/src/stimfit/gui/dlgs/fitseldlg.h0000775000175000017500000000747414750344764015115 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file fitseldlg.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfFitSelDlg. */ #ifndef _FITSELDLG_H #define _FITSELDLG_H /*! \addtogroup wxstf * @{ */ #include #include #include "./../../stf.h" //! Non-linear regression settings dialog class wxStfFitSelDlg : public wxDialog { DECLARE_EVENT_TABLE() private: int m_fselect; Vector_double init_p; Vector_double opts; bool noInput, use_scaling; void SetPars(); void SetOpts(); void InitOptions(wxFlexGridSizer* optionsGrid); void Update_fselect(); void read_init_p(); void read_opts(); static const int MAXPAR=20; void OnListItemSelected( wxListEvent& event ); void OnButtonClick( wxCommandEvent& event ); wxStdDialogButtonSizer* m_sdbSizer; wxListCtrl* m_listCtrl; wxTextCtrl *m_textCtrlMu,*m_textCtrlJTE,*m_textCtrlDP,*m_textCtrlE2, *m_textCtrlMaxiter, *m_textCtrlMaxpasses; wxCheckBox *m_checkBox; std::vector< wxStaticText* > paramDescArray; std::vector< wxTextCtrl* > paramEntryArray; wxStfDoc* pDoc; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param doc Pointer to the document the call originated from. * \param id Window id. * \param title Dialog title. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfFitSelDlg( wxWindow* parent, wxStfDoc* doc, int id = wxID_ANY, wxString title = wxT("Non-linear regression"), wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); //! Get the selected fit function. /*! \return The index of the selected fit function. */ int GetFSelect() const {return m_fselect;} //! Get the initial parameters. /*! \return A valarray containing the initial parameter set to start the fit. */ Vector_double GetInitP() const {return init_p;} //! Get options for the algorithm. /*! \return A valarray containing the initial parameters for the algorithm. */ Vector_double GetOpts() const {return opts;} //! Scale x- and y-amplitudes to 1.0 before fit /*! \return True if scaling should be used */ bool UseScaling() const {return use_scaling;} //! Determines whether user-defined initial parameters are allowed. /*! \param noInput_ Set to true if the user may set the initial parameters, false otherwise. * Needed for batch analysis. */ void SetNoInput(bool noInput_) {noInput=noInput_;} }; /* @} */ #endif stimfit-0.16.7/src/stimfit/gui/table.cpp0000775000175000017500000000560714750344764013625 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // table.cpp // Table entries for spreadsheets in wxStfGrid. // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/grid.h" #include "./table.h" bool wxStfTable::IsEmptyCell( int row, int col ) { try { if (row==0 && col>=1) { return table.GetColLabel(col-1) == "\0"; } else if (col==0 && row>=1) { return table.GetRowLabel(row-1) == "\0"; } else if (col!=0 && row!=0) { return table.IsEmpty(row-1,col-1); } else { return true; } } catch (const std::out_of_range&) { return true; } } wxString wxStfTable::GetValue( int row, int col ) { try { if (row==0 && col>=1) { return stf::std2wx(table.GetColLabel(col-1)); } else if (col==0 && row>=1) { return stf::std2wx(table.GetRowLabel(row-1)); } else if (col!=0 && row!=0) { if (table.IsEmpty(row-1,col-1)) return wxT("\0"); wxString strVal; strVal << table.at(row-1,col-1); return strVal; } else { return wxT("\0"); } } catch (const std::out_of_range&) { return wxT("\0"); } } void wxStfTable::SetValue( int row, int col, const wxString& value ) { try { if (row==0 && col>=1) { return table.SetColLabel(col-1, stf::wx2std(value)); } else if (col==0 && row>=1) { return table.SetRowLabel(row-1, stf::wx2std(value)); } else if (col!=0 && row!=0) { wxString strVal; strVal << value; double in=0.0; strVal.ToDouble(&in); table.at(row-1,col-1)=in; } else { return; } } catch (const std::out_of_range&) { return; } } wxString wxStfTable::GetSelection(const wxGridCellCoordsArray& selection) { wxString ret(wxT("\0")); for (std::size_t n_sel=0;n_sel #ifndef WX_PRECOMP #include #endif #include "./usrdlg.h" BEGIN_EVENT_TABLE( wxStfUsrDlg, wxDialog ) END_EVENT_TABLE() wxStfUsrDlg::wxStfUsrDlg( wxWindow* parent, const stf::UserInput& input_, int id, wxPoint pos, wxSize size, int style #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) ) : wxDialog( parent, id, input_.title, pos, size, style ), #else ) : wxDialog( parent, id, wxString(input_.title.c_str(), wxConvUTF8), pos, size, style ), #endif input(input_), retVec(input_.labels.size()), m_textCtrlArray(input_.labels.size()), m_staticTextArray(input_.labels.size()) { wxFlexGridSizer* gSizer; gSizer = new wxFlexGridSizer( (int)input.labels.size(), 2, 0, 0 ); for (std::size_t nRow=0;nRowAdd( m_staticTextArray[nRow], 0, wxALIGN_CENTER_VERTICAL | wxALL, 2 ); wxString defLabel; defLabel << input.defaults[nRow]; m_textCtrlArray[nRow]= new wxTextCtrl( this, wxID_ANY, defLabel, wxDefaultPosition, wxSize(64,20), wxTE_RIGHT ); gSizer->Add( m_textCtrlArray[nRow], 0, wxALIGN_CENTER_VERTICAL | wxALL, 2 ); } wxSizer* topSizer; topSizer=new wxBoxSizer(wxVERTICAL); topSizer->Add(gSizer,0,wxALIGN_CENTER,5); m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizer->AddButton( new wxButton( this, wxID_OK ) ); m_sdbSizer->AddButton( new wxButton( this, wxID_CANCEL ) ); m_sdbSizer->Realize(); topSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER, 5 ); topSizer->SetSizeHints(this); this->SetSizer( topSizer ); this->Layout(); } void wxStfUsrDlg::EndModal(int retCode) { // similar to overriding OnOK in MFC (I hope...) if (retCode==wxID_OK) { if (!OnOK()) { wxLogMessage(wxT("Check your entries")); return; } } wxDialog::EndModal(retCode); } bool wxStfUsrDlg::OnOK() { try { for (std::size_t n=0;nGetValue(); entry.ToDouble( &retVec[n] ); } } catch (const std::out_of_range&) { return false; } return true; } stimfit-0.16.7/src/stimfit/gui/usrdlg/usrdlg.h0000775000175000017500000000474314750344764015003 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file usrdlg.h * \author Christoph Schmidt-Hieber * \date 2008-01-20 * \brief Declares wxStfUsrDlg. */ #ifndef _USRDLG_H #define _USRDLG_H /*! \addtogroup wxstf * @{ */ #ifdef _MSC_VER #pragma warning( disable : 4251 ) // Disable warning messages #endif #include #include #include #include "./../../stf.h" //! A user-defined dialog for entering floating-point numbers. class wxStfUsrDlg : public wxDialog { DECLARE_EVENT_TABLE() private: stf::UserInput input; Vector_double retVec; wxStdDialogButtonSizer* m_sdbSizer; std::vector m_textCtrlArray; std::vector m_staticTextArray; //! Only called when a modal dialog is closed with the OK button. /*! \return true if all dialog entries could be read successfully */ bool OnOK(); public: //! Constructor /*! \param parent Pointer to parent window. * \param input_ A stf::UserInput struct. * \param id Window id. * \param pos Initial position. * \param size Initial size. * \param style Dialog style. */ wxStfUsrDlg( wxWindow* parent, const stf::UserInput& input_, int id = wxID_ANY, wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize, int style = wxCAPTION ); //! Get the user entries. /*! \return The user entries as a vector of doubles. */ Vector_double readInput() const {return retVec;} //! Called upon ending a modal dialog. /*! \param retCode The dialog button id that ended the dialog * (e.g. wxID_OK) */ virtual void EndModal(int retCode); }; /*! @} */ #endif stimfit-0.16.7/src/stimfit/gui/unopt.cpp0000664000175000017500000006467714752207205013702 #ifdef WITH_PYTHON // For compilers that support precompilation, includes "wx/wx.h". #include #ifndef WX_PRECOMP #include "wx/wx.h" #endif // WX_PRECOMP #ifdef _POSIX_C_SOURCE #define _POSIX_C_SOURCE_WAS_DEF #undef _POSIX_C_SOURCE #endif #ifdef _XOPEN_SOURCE #define _XOPEN_SOURCE_WAS_DEF #undef _XOPEN_SOURCE #endif #include #ifdef _POSIX_C_SOURCE_WAS_DEF #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE #endif #endif #ifdef _XOPEN_SOURCE_WAS_DEF #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #endif #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic ignored "-Wwrite-strings" #endif #if PY_MAJOR_VERSION >= 3 #include #include #define PyString_Check PyUnicode_Check #define PyString_AsString PyBytes_AsString #define PyString_FromString PyUnicode_FromString #else #include #endif // revert to previous behaviour #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic warning "-Wwrite-strings" #endif #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #endif #include #ifdef __GNUC__ #pragma GCC diagnostic pop #endif #include "./app.h" #include "./doc.h" #include "./parentframe.h" int stf::Extension::n_extensions = 0; #if defined(__WXMAC__) || defined (__WXGTK__) #include wxString GetExecutablePath() { return wxStandardPaths::Get( ).GetExecutablePath(); } #endif // __WXMAC__ || __WXGTK__ #ifdef _WINDOWS #include #include wxString GetExecutablePath() { HKEY keyHandle; if( RegOpenKeyEx( HKEY_CURRENT_USER, wxT("Software\\Stimfit 0.14"), 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) { DWORD BufferSize = 8192; DWORD cbData = BufferSize; wxCharTypeBuffer data( BufferSize ); DWORD dwRet = RegQueryValueEx( keyHandle, TEXT("InstallLocation"), NULL, NULL, (LPBYTE) data.data(), &cbData ); while( dwRet == ERROR_MORE_DATA ) { // Get a buffer that is big enough. BufferSize += 4096; data.extend( BufferSize ); cbData = BufferSize; dwRet = RegQueryValueEx( keyHandle, TEXT("InstallLocation"), NULL, NULL, (LPBYTE) data.data(), &cbData ); } if( dwRet == ERROR_SUCCESS ) { RegCloseKey(keyHandle); return wxString( data ); } else { // wxGetApp().ErrorMsg( wxT("Couldn't read registry key for Stimfit") ); return wxT(""); } } else { // wxGetApp().ErrorMsg( wxT("Couldn't open registry key for Stimfit") ); return wxT(""); } } #endif // _WINDOWS #if PY_MAJOR_VERSION >= 3 PyObject* wxPyMake_wxObject(wxObject* source, bool setThisOwn) { bool checkEvtHandler = true; PyObject* target = NULL; bool isEvtHandler = false; bool isSizer = false; if (source) { // If it's derived from wxEvtHandler then there may // already be a pointer to a Python object that we can use // in the OOR data. if (checkEvtHandler && wxIsKindOf(source, wxEvtHandler)) { isEvtHandler = true; wxEvtHandler* eh = (wxEvtHandler*)source; wxPyClientData* data = (wxPyClientData*)eh->GetClientObject(); if (data) { target = data->GetData(); } } // Also check for wxSizer if (!target && wxIsKindOf(source, wxSizer)) { isSizer = true; wxSizer* sz = (wxSizer*)source; wxPyClientData* data = (wxPyClientData*)sz->GetClientObject(); if (data) { target = data->GetData(); } } if (! target) { // Otherwise make it the old fashioned way by making a new shadow // object and putting this pointer in it. Look up the class // heirarchy until we find a class name that is located in the // python module. const wxClassInfo* info = source->GetClassInfo(); wxString name = info->GetClassName(); wxString childname = name.Clone(); if (info) { target = wxPyConstructObject((void*)source, name.c_str(), setThisOwn); while (target == NULL) { info = info->GetBaseClass1(); name = info->GetClassName(); if (name == childname) break; childname = name.Clone(); target = wxPyConstructObject((void*)source, name.c_str(), setThisOwn); } if (target && isEvtHandler) ((wxEvtHandler*)source)->SetClientObject(new wxPyClientData(target)); if (target && isSizer) ((wxSizer*)source)->SetClientObject(new wxPyClientData(target)); } else { wxString msg(wxT("wxPython class not found for ")); msg += source->GetClassInfo()->GetClassName(); PyErr_SetString(PyExc_NameError, msg.mbc_str()); target = NULL; } } } else { // source was NULL so return None. Py_INCREF(Py_None); target = Py_None; } return target; } #endif bool wxStfApp::Init_wxPython() { // Initialize the Python interpreter if (!Py_IsInitialized()) { Py_Initialize(); } #if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7) PyEval_InitThreads(); #endif wxString cwd; #ifdef __WXMAC__ // Add the cwd to the present path: wxString app_path = wxFileName( GetExecutablePath() ).GetPath(); cwd << wxT("import os\n"); cwd << wxT("cwd=\"") << app_path << wxT("/../Frameworks\"\n"); cwd << wxT("import sys\n"); cwd << wxT("sys.path.append(cwd)\n"); cwd << wxT("cwd=\"") << app_path << wxT("/../Frameworks/stimfit\"\n"); cwd << wxT("sys.path.append(cwd)\n"); // cwd << wxT("cwd=\"") << app_path << wxT("/../Frameworks/numpy\"\n"); // cwd << wxT("sys.path.insert(0,cwd)\n"); #ifdef _STFDEBUG cwd << wxT("print(sys.path)\n"); cwd << wxT("import numpy\n"); cwd << wxT("print(numpy.version.version)\n"); #endif // _STFDEBUG #endif // __WXMAC__ #ifdef __WXGTK__ // Add the cwd to the present path: wxString app_path = wxFileName( GetExecutablePath() ).GetPath(); cwd << wxT("import os\n"); cwd << wxT("cwd=\"") << app_path << wxT("/../lib/stimfit\"\n"); cwd << wxT("import sys\n"); cwd << wxT("sys.path.append(cwd)\n"); #ifdef _STFDEBUG cwd << wxT("print(sys.path)\n"); cwd << wxT("import numpy\n"); cwd << wxT("print(numpy.version.version)\n"); #endif // _STFDEBUG #endif // __WXGTK__ #ifdef _WINDOWS // Add the cwd to the present path: wxString app_path = GetExecutablePath().BeforeFirst( wxUniChar('\0') ); cwd << wxT("cwd = \"") << app_path << wxT("\\wx-3.0-msw\"\nimport sys\nsys.path.insert(0,cwd)\n"); cwd << wxT("cwd = \"") << app_path << wxT("\\stf-site-packages\"\nsys.path.insert(0,cwd)\n"); cwd << wxT("cwd = \"") << app_path << wxT("\"\nsys.path.insert(0,cwd)\n"); #endif int cwd_result = PyRun_SimpleString(cwd.utf8_str()); if (cwd_result!=0) { PyErr_Print(); ErrorMsg( wxT("Couldn't modify Python path") ); Py_Finalize(); return false; } // Load the wxPython core API. Imports the wx._core_ module and sets a // local pointer to a function table located there. The pointer is used // internally by the rest of the API functions. #if PY_MAJOR_VERSION < 3 // Specify version of the wx module to be imported PyObject* wxversion = PyImport_ImportModule("wxversion"); if (wxversion==NULL) { PyErr_Print(); ErrorMsg( wxT("Couldn't import wxversion") ); Py_Finalize(); return false; } PyObject* wxselect = PyObject_GetAttrString(wxversion, "select"); Py_DECREF(wxversion); if (!PyCallable_Check(wxselect)) { PyErr_Print(); ErrorMsg( wxT("Couldn't select correct version of wx") ); Py_Finalize(); return false; } #if wxCHECK_VERSION(3, 1, 0) PyObject* ver_string = Py_BuildValue("ss","3.1",""); #elif wxCHECK_VERSION(3, 0, 0) PyObject* ver_string = Py_BuildValue("ss","3.0",""); #elif wxCHECK_VERSION(2, 9, 0) PyObject* ver_string = Py_BuildValue("ss","2.9",""); #else PyObject* ver_string = Py_BuildValue("ss","2.8",""); #endif PyObject* result = PyEval_CallObject(wxselect, ver_string); Py_DECREF(ver_string); if (result == NULL) { PyErr_Print(); ErrorMsg( wxT("Couldn't call wxversion.select") ); Py_Finalize(); return false; } #endif // < python 3 #if 0 // wxversion.select doesn't return an error code, but raises an exception long iresult = PyInt_AsLong(result); Py_DECREF(result); if (iresult == 0) { PyErr_Print(); ErrorMsg( wxT("Couldn't select correct version of wx") ); Py_Finalize(); return false; } #endif #if PY_MAJOR_VERSION >= 3 if (wxPyGetAPIPtr()==NULL) { #else if ( ! wxPyCoreAPI_IMPORT() ) { #endif PyErr_Print(); wxString errormsg; errormsg << wxT("Couldn't load wxPython core API.\n"); #ifdef _WINDOWS errormsg << wxT("Try the following steps:\n"); errormsg << wxT("1.\tUninstall a previous Stimfit installation\n"); errormsg << wxT("\t(Control Panel->Software)\n"); errormsg << wxT("2.\tUninstall a previous wxPython installation\n"); errormsg << wxT("\t(Control Panel->Software)\n"); errormsg << wxT("3.\tUninstall a previous Python 2.5 installation\n"); errormsg << wxT("\t(Control Panel->Software)\n"); errormsg << wxT("4.\tSet the current working directory\n"); errormsg << wxT("\tto the program directory so that all shared\n"); errormsg << wxT("\tlibraries can be found.\n"); errormsg << wxT("\tIf you used a shortcut, right-click on it,\n"); errormsg << wxT("\tchoose \"Properties\", select the \"Shortcut\"\n"); errormsg << wxT("\ttab, then set \"Run in...\" to the stimfit program\n"); errormsg << wxT("\tdirectory (typically C:\\Program Files\\Stimfit).\n"); errormsg << wxT("\tIf you started stimfit from the command line, you\n"); errormsg << wxT("\thave to set the current working directory using the\n"); errormsg << wxT("\t\"/d\" option (e.g. /d=C:\\Program Files\\Stimfit)\n"); #endif // _WINDOWS ErrorMsg( errormsg ); Py_Finalize(); #if PY_MAJOR_VERSION < 3 Py_DECREF(result); #endif return false; } // Save the current Python thread state and release the // Global Interpreter Lock. m_mainTState = wxPyBeginAllowThreads(); #ifdef IPYTHON // Set a dummy sys.argv for IPython wxPyBlock_t blocked = wxPyBeginBlockThreads(); char* argv = (char *)"\0"; PySys_SetArgv(1, &argv); wxPyEndBlockThreads(blocked); #endif return true; } void wxStfApp::ImportPython(const wxString &modulelocation) { // Get path and filename from modulelocation wxString python_path = wxFileName(modulelocation).GetPath(); wxString python_file = wxFileName(modulelocation).GetName(); // Grab the Global Interpreter Lock. wxPyBlock_t blocked = wxPyBeginBlockThreads(); wxString python_import; #ifdef IPYTHON // the ip object is created to access the interactive IPython session python_import << wxT("import IPython.ipapi\n"); python_import << wxT("ip = IPython.ipapi.get()\n"); python_import << wxT("import sys\n"); python_import << wxT("sys.path.append(\"") << python_path << wxT("\")\n"); #if (PY_VERSION_HEX < 0x03000000) python_import << wxT("if not sys.modules.has_key(\"") << python_file << wxT("\"):"); #else python_import << wxT("if '") << python_file << wxT("' not in sys.modules:"); #endif python_import << wxT("ip.ex(\"import ") << python_file << wxT("\")\n"); python_import << wxT("else:") << wxT("ip.ex(\"reload(") << python_file << wxT(")") << wxT("\")\n"); python_import << wxT("sys.path.remove(\"") << python_path << wxT("\")\n"); #else // Python code to import a module with PyCrust python_import << wxT("import sys\n"); python_import << wxT("sys.path.append(\"") << python_path << wxT("\")\n"); #if (PY_VERSION_HEX < 0x03000000) python_import << wxT("if not sys.modules.has_key(\"") << python_file << wxT("\"):"); #else python_import << wxT("if '") << python_file << wxT("' not in sys.modules:"); #endif python_import << wxT("import ") << python_file << wxT("\n"); python_import << wxT("else:") << wxT("reload(") << python_file << wxT(")") << wxT("\n"); python_import << wxT("sys.path.remove(\"") << python_path << wxT("\")\n"); python_import << wxT("del sys\n"); #endif #if ((wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) && !defined(__WXMAC__)) PyRun_SimpleString(python_import); #else PyRun_SimpleString(python_import.char_str()); #endif // Release the Global Interpreter Lock wxPyEndBlockThreads(blocked); } bool wxStfApp::Exit_wxPython() { wxPyEndAllowThreads(m_mainTState); Py_Finalize(); return true; } void wxStfParentFrame::RedirectStdio() { // This is a helpful little tidbit to help debugging and such. It // redirects Python's stdout and stderr to a window that will popup // only on demand when something is printed, like a traceback. wxString python_redirect; python_redirect = wxT("import sys, wx\n"); python_redirect << wxT("output = wx.PyOnDemandOutputWindow()\n"); python_redirect << wxT("sys.stdin = sys.stderr = output\n"); python_redirect << wxT("del sys, wx\n"); wxPyBlock_t blocked = wxPyBeginBlockThreads(); #if ((wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) && !defined(__WXMAC__)) PyRun_SimpleString(python_redirect); #else PyRun_SimpleString(python_redirect.char_str()); #endif wxPyEndBlockThreads(blocked); } new_wxwindow wxStfParentFrame::MakePythonWindow(const std::string& windowFunc, const std::string& mgr_name, const std::string& caption, bool show, bool full, bool isfloat, int width, int height, double mpl_width, double mpl_height) { // More complex embedded situations will require passing C++ objects to // Python and/or returning objects from Python to be used in C++. This // sample shows one way to do it. NOTE: The above code could just have // easily come from a file, or the whole thing could be in the Python // module that is imported and manipulated directly in this C++ code. See // the Python API for more details. wxWindow *window = NULL; PyObject *result; // As always, first grab the GIL wxPyBlock_t blocked = wxPyBeginBlockThreads(); RedirectStdio(); // Now make a dictionary to serve as the global namespace when the code is // executed. Put a reference to the builtins module in it. (Yes, the // names are supposed to be different, I don't know why...) PyObject* globals = PyDict_New(); #if PY_MAJOR_VERSION >= 3 PyObject* builtins = PyImport_ImportModule("builtins"); #else PyObject* builtins = PyImport_ImportModule("__builtin__"); #endif PyDict_SetItemString(globals, "__builtins__", builtins); Py_DECREF(builtins); // Execute the code to make the makeWindow function result = PyRun_String(python_code2.c_str(), Py_file_input, globals, globals); // Was there an exception? if (! result) { PyErr_Print(); wxGetApp().ErrorMsg(wxT("Couldn't initialize python shell")); wxPyEndBlockThreads(blocked); return NULL; } Py_DECREF(result); // Now there should be an object named 'makeWindow' in the dictionary that // we can grab a pointer to: PyObject* func = NULL; func = PyDict_GetItemString(globals, windowFunc.c_str()); if (!PyCallable_Check(func)) { PyErr_Print(); wxGetApp().ErrorMsg(wxT("Couldn't initialize window for the python shell")); wxPyEndBlockThreads(blocked); return NULL; } // Now build an argument tuple and call the Python function. Notice the // use of another wxPython API to take a wxWindows object and build a // wxPython object that wraps it. PyObject* arg = wxPyMake_wxObject(this, false); wxASSERT(arg != NULL); PyObject* py_mpl_width = PyFloat_FromDouble(mpl_width); wxASSERT(py_mpl_width != NULL); PyObject* py_mpl_height = PyFloat_FromDouble(mpl_height); wxASSERT(py_mpl_height != NULL); PyObject* figsize = PyTuple_New(2); PyTuple_SET_ITEM(figsize, 0, py_mpl_width); PyTuple_SET_ITEM(figsize, 1, py_mpl_height); PyObject* argtuple = PyTuple_New(2); PyTuple_SET_ITEM(argtuple, 0, arg); PyTuple_SET_ITEM(argtuple, 1, figsize); result = PyObject_CallObject(func, argtuple); Py_DECREF(argtuple); Py_DECREF(py_mpl_width); Py_DECREF(py_mpl_height); Py_DECREF(figsize); // Was there an exception? if (! result) { PyErr_Print(); wxGetApp().ErrorMsg(wxT("Couldn't create window for the python shell")); wxPyEndBlockThreads(blocked); return NULL; } else { // Otherwise, get the returned window out of Python-land and // into C++-ville... #if PY_MAJOR_VERSION >= 3 if (!wxPyConvertWrappedPtr(result, (void**)&window, _T("wxWindow"))) { #else if (!wxPyConvertSwigPtr(result, (void**)&window, _T("wxWindow"))) { #endif PyErr_Print(); wxGetApp().ErrorMsg(wxT("Returned object was not a wxWindow!")); wxPyEndBlockThreads(blocked); return NULL; } Py_DECREF(result); } // Release the python objects we still have Py_DECREF(globals); // Finally, after all Python stuff is done, release the GIL wxPyEndBlockThreads(blocked); if (!full) { if (isfloat) { m_mgr.AddPane( window, wxAuiPaneInfo().Name(stf::std2wx(mgr_name)). CloseButton(true). Show(show).Caption(stf::std2wx(caption)).Float(). BestSize(width, height) ); } else { m_mgr.AddPane( window, wxAuiPaneInfo().Name(stf::std2wx(mgr_name)). CloseButton(true). Show(show).Caption(stf::std2wx(caption)).Dockable(true).Bottom(). BestSize(width, height) ); } } else { m_mgr.AddPane( window, wxAuiPaneInfo().Name(stf::std2wx(mgr_name)). Floatable(false).CaptionVisible(false). BestSize(GetClientSize().GetWidth(),GetClientSize().GetHeight()).Fixed() ); } m_mgr.Update(); return new_wxwindow(window, result); } std::vector wxStfApp::LoadExtensions() { std::vector< stf::Extension > extList; // As always, first grab the GIL wxPyBlock_t blocked = wxPyBeginBlockThreads(); // import extensions.py: PyObject* pModule = PyImport_ImportModule("extensions"); if (!pModule) { PyErr_Print(); #ifdef _STFDEBUG wxGetApp().ErrorMsg(wxT("Couldn't load extensions.py")); #endif wxPyEndBlockThreads(blocked); return extList; } PyObject* pExtList = PyObject_GetAttrString(pModule, "extensionList"); if (!pExtList) { PyErr_Print(); wxGetApp().ErrorMsg(wxT("Couldn't find extensionList in extensions.py")); wxPyEndBlockThreads(blocked); Py_DECREF(pModule); return extList; } if (!PyList_Check(pExtList)) { PyErr_Print(); wxGetApp().ErrorMsg(wxT("extensionList is not a Python list in extensions.py")); wxPyEndBlockThreads(blocked); Py_DECREF(pExtList); Py_DECREF(pModule); return extList; } // retrieve values from list: for (int i=0; i= (int)GetExtensionLib().size() || id<0) { wxString msg(wxT("Couldn't find extension function")); ErrorMsg( msg ); return; } // As always, first grab the GIL wxPyBlock_t blocked = wxPyBeginBlockThreads(); // retrieve function PyObject* pPyFunc = (PyObject*)(GetExtensionLib()[id].pyFunc); // retrieve function name wxString FuncName = stf::std2wx(GetExtensionLib()[id].menuEntry); if (!pPyFunc || !PyCallable_Check(pPyFunc)) { wxString msg(FuncName << wxT(" Couldn't call extension function ")); ErrorMsg( msg ); wxPyEndBlockThreads(blocked); return; } // call function PyObject* res = PyObject_CallObject(pPyFunc, NULL); if (!res) { PyErr_Print(); wxString msg(FuncName << wxT(" call failed")); ErrorMsg( msg ); wxPyEndBlockThreads(blocked); return; } if (res==Py_False) { wxString msg(FuncName << wxT(" returned False")); ErrorMsg( msg ); } Py_XDECREF(res); // Finally, after all Python stuff is done, release the GIL wxPyEndBlockThreads(blocked); } bool wxStfDoc::LoadTDMS(const std::string& filename, Recording& ReturnData) { // Grab the Global Interpreter Lock. wxPyBlock_t blocked = wxPyBeginBlockThreads(); PyObject* stf_mod = PyImport_ImportModule("tdms"); if (!stf_mod) { PyErr_Print(); #ifdef _STFDEBUG wxGetApp().ErrorMsg(wxT("Couldn't load tdms.py")); #endif wxPyEndBlockThreads(blocked); return false; } PyObject* py_fn = PyString_FromString(filename.c_str()); PyObject* stf_tdms_f = PyObject_GetAttrString(stf_mod, "tdms_open"); PyObject* stf_tdms_res = NULL; if (PyCallable_Check(stf_tdms_f)) { PyObject* stf_tdms_args = PyTuple_Pack(1, py_fn); stf_tdms_res = PyObject_CallObject(stf_tdms_f, stf_tdms_args); PyErr_Print(); Py_DECREF(stf_mod); Py_DECREF(py_fn); Py_DECREF(stf_tdms_args); } else { Py_DECREF(stf_mod); Py_DECREF(py_fn); return false; } if (stf_tdms_res == Py_None) { wxGetApp().ErrorMsg( wxT("nptdms module unavailable. Cannot read tdms files.")); Py_DECREF(stf_tdms_res); return false; } if (!PyTuple_Check(stf_tdms_res)) { wxGetApp().ErrorMsg(wxT("Return value of tdms_open is not a tuple. Aborting now.")); Py_DECREF(stf_tdms_res); return false; } if (PyTuple_Size(stf_tdms_res) != 2) { wxGetApp().ErrorMsg( wxT("Return value of tdms_open is not a 2-tuple. Aborting now.")); Py_DECREF(stf_tdms_res); return false; } PyObject* data_list = PyTuple_GetItem(stf_tdms_res, 0); PyObject* py_dt = PyTuple_GetItem(stf_tdms_res, 1); double dt = PyFloat_AsDouble(py_dt); // Py_DECREF(py_dt); Py_ssize_t nchannels = PyList_Size(data_list); ReturnData.resize(nchannels); int nchannels_nonempty = 0; for (int nc=0; nc #ifndef WX_PRECOMP #include #endif #include #include #include #include #include #include "./app.h" #include "./doc.h" #include "./view.h" #include "./parentframe.h" #include "./childframe.h" #include "./printout.h" #include "./dlgs/cursorsdlg.h" #include "./dlgs/smalldlgs.h" #include "./usrdlg/usrdlg.h" #include "./graph.h" #include "./../../libstfnum/measure.h" #ifdef _STFDEBUG #include #endif #if !defined(isnan) #define isnan std::isnan #endif // #define BENCHMARK // uncomment to run benchmark #ifdef BENCHMARK //def _STFDEBUG #include #include #include #include #ifdef __MACH__ #include #include #endif /* From https://gist.github.com/jbenet/1087739 */ void current_utc_time(struct timespec *ts) { #ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); ts->tv_sec = mts.tv_sec; ts->tv_nsec = mts.tv_nsec; #else clock_gettime(CLOCK_REALTIME, ts); #endif } static const double BILLION = 1000000000L; double tdiff(timespec time1, timespec time0) { return ( time1.tv_sec - time0.tv_sec ) + ( time1.tv_nsec - time0.tv_nsec ) / BILLION; } double t2d(timespec time1) { return time1.tv_sec + time1.tv_nsec / BILLION; } #endif BEGIN_EVENT_TABLE(wxStfGraph, wxWindow) EVT_MENU(ID_ZOOMHV,wxStfGraph::OnZoomHV) EVT_MENU(ID_ZOOMH,wxStfGraph::OnZoomH) EVT_MENU(ID_ZOOMV,wxStfGraph::OnZoomV) EVT_MOUSE_EVENTS(wxStfGraph::OnMouseEvent) EVT_KEY_DOWN( wxStfGraph::OnKeyDown ) #if defined __WXMAC__ && !(wxCHECK_VERSION(2, 9, 0)) EVT_PAINT( wxStfGraph::OnPaint ) #endif END_EVENT_TABLE() // Define a constructor for my canvas wxStfGraph::wxStfGraph(wxView *v, wxStfChildFrame *frame, const wxPoint& pos, const wxSize& size, long style): wxScrolledWindow(frame, wxID_ANY, pos, size, style),pFrame(frame), isZoomRect(false),no_gimmicks(false),isPrinted(false),isLatex(false),firstPass(true),isSyncx(false), printRect(),boebbel(boebbelStd),boebbelPrint(boebbelStd), #ifdef __WXGTK__ printScale(1.0),printSizePen1(4),printSizePen2(8),printSizePen4(16), #else printScale(1.0),printSizePen1(4),printSizePen2(8),printSizePen4(16), #endif downsampling(1),eventPos(0), llz_x(0.0),ulz_x(1.0),llz_y(0.0),ulz_y(1.0),llz_y2(0.0),ulz_y2(1.0), results1(wxT("\0")),results2(wxT("\0")),results3(wxT("\0")),results4(wxT("\0")),results5(wxT("\0")),results6(wxT("\0")), standardPen(*wxBLACK,1,wxPENSTYLE_SOLID), //Solid black line standardPen2(*wxRED,1,wxPENSTYLE_SOLID), //Solid red line standardPen3(wxColour(255,192,192),1,wxPENSTYLE_SOLID), //Solid red line scalePen(*wxBLACK,2,wxPENSTYLE_SOLID), //Solid black line scalePen2(*wxRED,2,wxPENSTYLE_SOLID), //Solid red line peakPen(*wxRED,1,wxPENSTYLE_SHORT_DASH), //Dashed red line peakLimitPen(*wxRED,1,wxPENSTYLE_DOT), //Dotted red line basePen(*wxGREEN,1,wxPENSTYLE_SHORT_DASH), //Dashed green line baseLimitPen(*wxGREEN,1,wxPENSTYLE_DOT), //Dotted green line decayLimitPen(wxColour(127,127,127),1,wxPENSTYLE_DOT), //Dotted dark blue line ZoomRectPen(*wxLIGHT_GREY,1,wxPENSTYLE_DOT), //Dotted grey line fitPen(wxColour(127,127,127),4,wxPENSTYLE_SOLID), //Solid dark grey line fitSelectedPen(wxColour(192,192,192),2,wxPENSTYLE_SOLID), //Solid dark grey line selectPen(wxColour(127,127,127),1,wxPENSTYLE_SOLID), //Solid grey line averagePen(*wxBLUE,1,wxPENSTYLE_SOLID), //Solid light blue line rtPen(*wxGREEN,2,wxPENSTYLE_SOLID), //Solid green line hdPen(*wxCYAN,2,wxPENSTYLE_SOLID), //Solid violet line rdPen(*wxRED,2,wxPENSTYLE_SOLID), //Solid dark violet line #ifdef WITH_PSLOPE slopePen(*wxBLUE,2,wxPENSTYLE_SOLID), //Solid blue line #endif latencyPen(*wxBLUE,1,wxPENSTYLE_DOT), alignPen(*wxBLUE,1,wxPENSTYLE_SHORT_DASH), measPen(*wxBLACK,1,wxPENSTYLE_DOT), eventPen(*wxBLUE,2,wxPENSTYLE_SOLID), #ifdef WITH_PSLOPE PSlopePen(wxColor(30,144,255), 1, wxDOT), // Dotted bright blue line #endif standardPrintPen(*wxBLACK,printSizePen1,wxPENSTYLE_SOLID), //Solid black line standardPrintPen2(*wxRED,printSizePen1,wxPENSTYLE_SOLID), //Solid red line standardPrintPen3(wxColour(255,192,192),printSizePen1,wxPENSTYLE_SOLID), //Solid red line scalePrintPen(*wxBLACK,printSizePen2,wxPENSTYLE_SOLID), //Solid black line scalePrintPen2(*wxRED,printSizePen2,wxPENSTYLE_SOLID), //Solid red line measPrintPen(*wxBLACK,printSizePen1,wxPENSTYLE_DOT), peakPrintPen(*wxRED,printSizePen1,wxPENSTYLE_SHORT_DASH), //Dashed red line peakLimitPrintPen(*wxRED,printSizePen1,wxPENSTYLE_DOT), //Dotted red line basePrintPen(*wxGREEN,printSizePen1,wxPENSTYLE_SHORT_DASH), //Dashed green line baseLimitPrintPen(*wxGREEN,printSizePen1,wxPENSTYLE_DOT), //Dotted green line decayLimitPrintPen(wxColour(63,63,63),printSizePen1,wxPENSTYLE_DOT), //Dotted dark blue line fitPrintPen(wxColour(63,63,63),printSizePen2,wxPENSTYLE_SOLID), //Solid dark grey line fitSelectedPrintPen(wxColour(128,128,128),printSizePen2,wxPENSTYLE_SOLID), //Solid dark grey line selectPrintPen(wxColour(31,31,31),printSizePen1,wxPENSTYLE_SOLID), //Solid grey line averagePrintPen(*wxBLUE,printSizePen1,wxPENSTYLE_SOLID), //Solid light blue line rtPrintPen(*wxGREEN,printSizePen2,wxPENSTYLE_SOLID), //Solid green line hdPrintPen(*wxCYAN,printSizePen2,wxPENSTYLE_SOLID), //Solid violet line rdPrintPen(*wxRED,printSizePen2,wxPENSTYLE_SOLID), //Solid dark violet line #ifdef WITH_PSLOPE slopePrintPen(*wxBLUE,printSizePen4,wxPENSTYLE_SOLID), //Solid blue line #endif resultsPrintPen(*wxLIGHT_GREY,printSizePen2,wxPENSTYLE_SOLID),//Solid light grey line latencyPrintPen(*wxBLUE,printSizePen1,wxPENSTYLE_DOT),//Dotted violett line PSlopePrintPen(wxColour(30,144,255), printSizePen1, wxPENSTYLE_DOT), // Dotted bright blue line baseBrush(*wxLIGHT_GREY,wxBRUSHSTYLE_BDIAGONAL_HATCH), zeroBrush(*wxLIGHT_GREY,wxBRUSHSTYLE_FDIAGONAL_HATCH), lastLDown(0,0), yzoombg(), m_zoomContext( new wxMenu ), m_eventContext( new wxMenu ) { m_zoomContext->Append( ID_ZOOMHV, wxT("Expand zoom window horizontally && vertically") ); m_zoomContext->Append( ID_ZOOMH, wxT("Expand zoom window horizontally") ); m_zoomContext->Append( ID_ZOOMV, wxT("Expand zoom window vertically") ); m_eventContext->Append( ID_EVENT_ADDEVENT, wxT("Add an event that starts here") ); m_eventContext->Append( ID_EVENT_ERASE, wxT("Erase all events") ); m_eventContext->Append( ID_EVENT_EXTRACT, wxT("Extract selected events") ); SetBackgroundColour(*wxWHITE); view = (wxStfView*)v; wxString perspective=wxGetApp().wxGetProfileString(wxT("Settings"),wxT("Windows"),wxT("")); /* if (perspective != wxT("")) { // load the stored perspective: frame->GetMgr()->LoadPerspective(perspective); } else { // or the default: frame->GetMgr()->LoadPerspective(defaultPersp); } */ } wxStfParentFrame* wxStfGraph::ParentFrame() { return (wxStfParentFrame*)wxGetApp().GetTopWindow(); } // Defines the repainting behaviour void wxStfGraph::OnDraw( wxDC& DC ) { if ( !view || Doc()->get().empty() || !Doc()->IsInitialized() ) return; // ugly hack to force active document update: #if defined(__WXGTK__) || defined(__WXMAC__) view->Activate(true); #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) if (!HasFocus()) #else if (wxWindow::FindFocus()!=(wxWindow*)this) #endif SetFocus(); #endif wxRect WindowRect(GetRect()); if (isPrinted) { PrintScale(WindowRect); } if (firstPass) { firstPass = false; InitPlot(); } //Creates scale bars and labelings for display or print out //Calculate scale bars and labelings CreateScale(&DC); //Create additional rulers/lines and circles on display if (!no_gimmicks) { PlotGimmicks(DC); } //Plot all selected traces and fitted functions if at least one trace ist selected //and 'is selected' is selected in the trace navigator/control box //Polyline() is used for printing to avoid separation of traces //in postscript files //LineTo()is used for display for performance reasons //Plot fit curves (including current trace) DrawFit(&DC); if (!Doc()->GetSelectedSections().empty() && pFrame->ShowSelected()) { PlotSelected(DC); } //End plot all selected traces //Plot average if (Doc()->GetIsAverage()) { PlotAverage(DC); } //End plot average // Plot integral boundaries try { if (Doc()->GetCurrentSectionAttributes().isIntegrated) { DrawIntegral(&DC); } } catch (const std::out_of_range& e) { /* Do nothing for now */ } //Zoom window is displayed (see OnLeftButtonUp()) if (isZoomRect) { DrawZoomRect(DC); } //End zoom //Plot of the second channel //Trace one when displayed first time if ((Doc()->size()>1) && pFrame->ShowSecond()) { if (!isPrinted) { //Draw current trace on display //For display use point to point drawing DC.SetPen(standardPen2); PlotTrace(&DC,Doc()->get()[Doc()->GetSecChIndex()][Doc()->GetCurSecIndex()].get(), reference); } else { //Draw second channel for print out //For print out use polyline tool DC.SetPen(standardPrintPen2); PrintTrace(&DC,Doc()->get()[Doc()->GetSecChIndex()][Doc()->GetCurSecIndex()].get(), reference); } // End display or print out } //End plot of the second channel if ((Doc()->size()>1) && pFrame->ShowAll()) { for (std::size_t n=0; n < Doc()->size(); ++n) { if (!isPrinted) { //Draw current trace on display //For display use point to point drawing DC.SetPen(standardPen3); PlotTrace(&DC,Doc()->get()[n][Doc()->GetCurSecIndex()].get(), background, n); } } } //End plot of the second channel //Standard plot of the current trace //Trace one when displayed first time if (!isPrinted) { //Draw current trace on display //For display use point to point drawing DC.SetPen(standardPen); PlotTrace(&DC,Doc()->get()[Doc()->GetCurChIndex()][Doc()->GetCurSecIndex()].get()); } else { //For print out use polyline tool DC.SetPen(standardPrintPen); PrintTrace(&DC,Doc()->get()[Doc()->GetCurChIndex()][Doc()->GetCurSecIndex()].get()); } // End display or print out //End plot of the current trace //Ensure old scaling after print out if(isPrinted) { for (std::size_t n=0; n < Doc()->size(); ++n) { Doc()->GetYZoomW(n) = Doc()->GetYZoomW(n) * (1.0/printScale); } Doc()->GetXZoomW() = Doc()->GetXZoomW() * (1.0/printScale); WindowRect=printRect; } //End ensure old scaling after print out view->OnDraw(& DC); } void wxStfGraph::InitPlot() { if (wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewScaleBars"),1)) { if (pFrame->GetMenuBar() && pFrame->GetMenuBar()->GetMenu(2)) { pFrame->GetMenuBar()->GetMenu(2)->Check(ID_SCALE,true); } wxGetApp().set_isBars(true); } else { if (pFrame->GetMenuBar() && pFrame->GetMenuBar()->GetMenu(2)) { pFrame->GetMenuBar()->GetMenu(2)->Check(ID_SCALE,false); } wxGetApp().set_isBars(false); } if (wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewSyncx"),1)) { isSyncx=true; } else { isSyncx=false; } // Ensure proper dimensioning // Determine scaling factors and Units // Zoom and offset variables are currently not part of the settings dialog => // Read from registry // Return a negative value upon first program start so that the trace is // fit to the window dimensions YZW()=(double)(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("zoom.yZoom"), -1) / 100000.0); SPYW()=wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("zoom.startPosY"), 0); XZW()=(double)(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("zoom.xZoom"), -1) / 100000.0); SPXW()=wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("zoom.startPosX"), 0); if (XZ() <= 0 || YZ() <= 0 || fabs(double(SPY())) >= 1e15) Fittowindow(false); if ((Doc()->size()>1)) { //Second channel is not part of the settings dialog =>read from registry SPY2W() = wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("Zoom.startPosY2"), 1); YZ2W() = (double)(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("Zoom.yZoom2"), 1) / 100000.0); //Ensure proper dimensioning if (YZ2() <=0) FitToWindowSecCh(false); } } void wxStfGraph::PlotSelected(wxDC& DC) { if (!isPrinted) { //Draw traces on display DC.SetPen(selectPen); for (unsigned m=0; m < Doc()->GetSelectedSections().size(); ++m) { //For display use point to point drawing PlotTrace( &DC, Doc()->get()[Doc()->GetCurChIndex()][Doc()->GetSelectedSections()[m]].get() ); } } //End draw traces on display else { //Draw traces for print out DC.SetPen(selectPrintPen); for (unsigned m=0; m < Doc()->GetSelectedSections().size() && Doc()->GetSelectedSections().size()>0; ++m) { PrintTrace(&DC,Doc()->get()[Doc()->GetCurChIndex()][Doc()->GetSelectedSections()[m]].get()); } //End draw for print out } //End if display or print out } void wxStfGraph::PlotAverage(wxDC& DC) { //Average is calculated but not plotted if (!isPrinted) { //Draw Average on display //For display use point to point drawing DC.SetPen(averagePen); PlotTrace(&DC,Doc()->GetAverage()[0][0].get()); } //End draw Average on display else { //Draw average for print out //For print out use polyline tool DC.SetPen(averagePrintPen); PrintTrace(&DC,Doc()->GetAverage()[0][0].get()); } //End draw average for print out } void wxStfGraph::DrawZoomRect(wxDC& DC) { DC.SetPen(ZoomRectPen); wxPoint ZoomPoints[4]; wxPoint Ul_Corner((int)llz_x, (int)llz_y); wxPoint Ur_Corner((int)ulz_x, (int)llz_y); wxPoint Lr_Corner((int)ulz_x, (int)ulz_y); wxPoint Ll_Corner((int)llz_x, (int)ulz_y); ZoomPoints[0]=Ul_Corner; ZoomPoints[1]=Ur_Corner; ZoomPoints[2]=Lr_Corner; ZoomPoints[3]=Ll_Corner; DC.DrawPolygon(4,ZoomPoints); } void wxStfGraph::PlotGimmicks(wxDC& DC) { // crosshair through measurement cursor: int crosshairSize=20; DrawCrosshair(DC, measPen, measPrintPen, crosshairSize, Doc()->GetMeasCursor(), Doc()->GetMeasValue()); // crosshair through threshold: DrawCrosshair(DC, peakPen, peakPrintPen, crosshairSize/2.0, Doc()->GetThrT(), Doc()->GetThreshold()); // creates vertical ruler through measurement peak if needed if ( Doc()->GetMeasRuler() ) DrawVLine(&DC, Doc()->GetMeasCursor(), measPen, measPrintPen); //creates red vertical and horizontal dashed lines through the peak DrawVLine(&DC,Doc()->GetMaxT(), peakPen, peakPrintPen); DrawHLine(&DC,Doc()->GetPeak(), peakPen, peakPrintPen); //and red dotted lines through peak calculation limits DrawVLine(&DC,Doc()->GetPeakBeg(), peakLimitPen, peakLimitPrintPen); DrawVLine(&DC,Doc()->GetPeakEnd(), peakLimitPen, peakLimitPrintPen); //creates a green horizontal dashed line through the base DrawHLine(&DC,Doc()->GetBase(), basePen, basePrintPen); //and green dotted lines through Doc()->GetBase() calculation limits DrawVLine(&DC,Doc()->GetBaseBeg(), baseLimitPen, baseLimitPrintPen); DrawVLine(&DC,Doc()->GetBaseEnd(), baseLimitPen, baseLimitPrintPen); //Create darkblue dotted lines through decay calculation limits DrawVLine(&DC,Doc()->GetFitBeg(), decayLimitPen, decayLimitPrintPen); DrawVLine(&DC,Doc()->GetFitEnd(), decayLimitPen, decayLimitPrintPen); // Create dotted line as a latency cursor DrawVLine(&DC,Doc()->GetLatencyBeg(), latencyPen, latencyPrintPen); DrawVLine(&DC,Doc()->GetLatencyEnd(), latencyPen, latencyPrintPen); // Create double-arrow between latency cursors: int latStart=xFormat(Doc()->GetLatencyBeg()); int latEnd=xFormat(Doc()->GetLatencyEnd()); if (latStart < 0) latStart = 0; if (latEnd > GetRect().width) latEnd = GetRect().width; DC.DrawLine(latStart,20,latEnd,20); // left arrowhead: DC.DrawLine(latStart+1,20,latStart+6,15); DC.DrawLine(latStart+1,20,latStart+6,25); // right arrowhead: DC.DrawLine(latEnd-1,20,latEnd-6,15); DC.DrawLine(latEnd-1,20,latEnd-6,25); #ifdef WITH_PSLOPE // Create dotted bright blue line as slope cursor DrawVLine(&DC, Doc()->GetPSlopeBeg(), PSlopePen, PSlopePrintPen); DrawVLine(&DC, Doc()->GetPSlopeEnd(), PSlopePen, PSlopePrintPen); #endif //Set circle size depending on output if (!isPrinted) boebbel=boebbelStd; else boebbel=boebbelPrint; //draws green circles around the Lo% and the Hi% rise times double reference = Doc()->GetBase(); if ( !Doc()->GetFromBase() && Doc()->GetThrT() >= 0 ) { reference = Doc()->GetThreshold(); } double Low = Doc()->GetRTFactor()/100.; double High = 1-Low; DrawCircle( &DC,Doc()->GetTLoReal(), High*reference + Low*Doc()->GetPeak(), rtPen, rtPrintPen); DrawCircle( &DC,Doc()->GetTHiReal(), Low*reference + High*Doc()->GetPeak(), rtPen, rtPrintPen); //draws circles around the half duration limits DrawCircle(&DC,Doc()->GetT50LeftReal(),Doc()->GetT50Y(), hdPen, hdPrintPen); DrawCircle(&DC,Doc()->GetT50RightReal(),Doc()->GetT50Y(), hdPen, hdPrintPen); //draws dark violet circles around the points of steepest rise/decay DrawCircle(&DC,Doc()->GetMaxRiseT(),Doc()->GetMaxRiseY(), rdPen, rdPrintPen); DrawCircle(&DC,Doc()->GetMaxDecayT(),Doc()->GetMaxDecayY(), rdPen, rdPrintPen); try { stf::SectionAttributes sec_attr = Doc()->GetCurrentSectionAttributes(); if (!sec_attr.eventList.empty()) { PlotEvents(DC); } if (!sec_attr.pyMarkers.empty()) { DC.SetPen(eventPen); for (c_marker_it it = sec_attr.pyMarkers.begin(); it != sec_attr.pyMarkers.end(); ++it) { // Create circles indicating the peak of an event: DC.DrawRectangle( xFormat(it->x), yFormat(it->y), boebbel*2.0, boebbel*2.0 ); } } } catch (const std::out_of_range& e) { /* Do nothing for now */ } } void wxStfGraph::PlotEvents(wxDC& DC) { const int MAX_EVENTS_PLOT = 200; stf::SectionAttributes sec_attr; try { sec_attr = Doc()->GetCurrentSectionAttributes(); } catch (const std::out_of_range& e) { return; } DC.SetPen(eventPen); for (c_event_it it = sec_attr.eventList.begin(); it != sec_attr.eventList.end(); ++it) { // Create small arrows indicating the start of an event: eventArrow(&DC, (int)it->GetEventStartIndex()); // Create circles indicating the peak of an event: try { DrawCircle( &DC, it->GetEventPeakIndex(), Doc()->cursec().at(it->GetEventPeakIndex()), eventPen, eventPen ); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal ) ); return; } } // Only draw check boxes if there are less than 1000 events (takes too long // to draw them and it's impossible to check them anyway) wxRect WindowRect=GetRect(); if (isPrinted) WindowRect=wxRect(printRect); int right=WindowRect.width; int nevents_plot = 0; for (event_it it2 = sec_attr.eventList.begin(); it2 != sec_attr.eventList.end(); ++it2) { nevents_plot += (xFormat(it2->GetEventStartIndex()) < right && xFormat(it2->GetEventStartIndex()) > 0); } if (nevents_plot < MAX_EVENTS_PLOT) { for (event_it it2 = sec_attr.eventList.begin(); it2 != sec_attr.eventList.end(); ++it2) { if (xFormat(it2->GetEventStartIndex()) < right && xFormat(it2->GetEventStartIndex()) > 0) { it2->GetCheckBox()->Move(wxPoint(xFormat(it2->GetEventStartIndex()), 0)); it2->GetCheckBox()->Show(true); } else { it2->GetCheckBox()->Show(false); } } } else { for (event_it it2 = sec_attr.eventList.begin(); it2 != sec_attr.eventList.end(); ++it2) { it2->GetCheckBox()->Show(false); } } // return focus to frame: SetFocus(); } void wxStfGraph::ClearEvents() { stf::SectionAttributes sec_attr; try { sec_attr = Doc()->GetCurrentSectionAttributes(); } catch (const std::out_of_range& e) { return; } for (event_it it2 = sec_attr.eventList.begin(); it2 != sec_attr.eventList.end(); ++it2) { it2->GetCheckBox()->Destroy(); } } void wxStfGraph::DrawCrosshair( wxDC& DC, const wxPen& pen, const wxPen& printPen, int crosshairSize, double xch, double ych) { if (isnan(xch) || isnan(ych)) { return; } wxPen chpen = pen; if (isPrinted) { chpen = printPen; crosshairSize=(int)(crosshairSize*printScale); } DC.SetPen(chpen); try { // circle: wxRect frame(wxPoint( xFormat(xch)-crosshairSize, yFormat(ych)-crosshairSize ), wxPoint( xFormat(xch)+crosshairSize, yFormat(ych)+crosshairSize )); DC.DrawEllipse(frame); // vertical part: DC.DrawLine( xFormat(xch), yFormat(ych)-crosshairSize, xFormat(xch), yFormat(ych)+crosshairSize ); if (wxGetApp().GetCursorsDialog()!=NULL && wxGetApp().GetCursorsDialog()->IsShown()) { //if (wxGetApp().GetCursorsDialog()->GetRuler()) if ( Doc()->GetMeasRuler() ) { DrawVLine(&DC,xch, pen, printPen); } } // horizontal part: DC.DrawLine( xFormat(xch)-crosshairSize, yFormat(ych), xFormat(xch)+crosshairSize, yFormat(ych) ); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal ) ); return; } } double wxStfGraph::get_plot_xmin() const { return -SPX()/XZ() * DocC()->GetXScale(); } double wxStfGraph::get_plot_xmax() const { wxRect WindowRect=GetRect(); int right=WindowRect.width; return (right-SPX())/XZ() * DocC()->GetXScale(); } double wxStfGraph::get_plot_ymin() const { wxRect WindowRect=GetRect(); int top=WindowRect.height; return (SPY()-top)/YZ(); } double wxStfGraph::get_plot_ymax() const { return SPY()/YZ(); } double wxStfGraph::get_plot_y2min() const { wxRect WindowRect=GetRect(); int top=WindowRect.height; return (SPY2()-top)/YZ2(); } double wxStfGraph::get_plot_y2max() const { return SPY2()/YZ2(); } void wxStfGraph::PlotTrace( wxDC* pDC, const Vector_double& trace, plottype pt, int bgno ) { // speed up drawing by omitting points that are outside the window: // find point before left window border: // xFormat=toFormat * zoom.xZoom + zoom.startPosX // for xFormat==0: // toFormat=-zoom.startPosX/zoom.xZoom std::size_t start=0; int x0i=int(-SPX()/XZ()); if (x0i>=0 && x0i<(int)trace.size()-1) start=x0i; // find point after right window border: // for xFormat==right: // toFormat=(right-zoom.startPosX)/zoom.xZoom std::size_t end=trace.size(); wxRect WindowRect=GetRect(); if (isPrinted) WindowRect=wxRect(printRect); int right=WindowRect.width; int xri = int((right-SPX())/XZ())+1; if (xri>=0 && xri<(int)trace.size()-1) end=xri; // apply filter at half the new sampling frequency: DoPlot(pDC, trace, start, end, 1, pt, bgno); } void wxStfGraph::DoPlot( wxDC* pDC, const Vector_double& trace, int start, int end, int step, plottype pt, int bgno) { #if (__cplusplus < 201103) boost::function yFormatFunc; #else std::function yFormatFunc; #endif switch (pt) { case active: yFormatFunc = std::bind( std::mem_fn(&wxStfGraph::yFormatD), this, std::placeholders::_1); break; case reference: yFormatFunc = std::bind( std::mem_fn(&wxStfGraph::yFormatD2), this, std::placeholders::_1); break; case background: Vector_double::const_iterator max_el = std::max_element(trace.begin(), trace.end()); Vector_double::const_iterator min_el = std::min_element(trace.begin(), trace.end()); double min = *min_el; if (min>1.0e12) min= 1.0e12; if (min<-1.0e12) min=-1.0e12; double max = *max_el; if (max>1.0e12) max= 1.0e12; if (max<-1.0e12) max=-1.0e12; wxRect WindowRect=GetRect(); WindowRect.height /= Doc()->size(); FittorectY(yzoombg, WindowRect, min, max, 1.0); yzoombg.startPosY += bgno*WindowRect.height; yFormatFunc = std::bind( std::mem_fn(&wxStfGraph::yFormatDB), this, std::placeholders::_1); break; } int x_last = xFormat(start); int y_last = yFormatFunc( trace[start] ); int x_next = 0; int y_next = 0; #ifdef BENCHMARK //def _STFDEBUG struct timespec time0, time1; current_utc_time(&time0); #else wxRect WindowRect(GetRect()); if (end-start < 2*WindowRect.width+2) { #endif for (int n=start; nDrawLine( x_last, y_last, x_next, y_next ); x_last = x_next; y_last = y_next; } #ifdef BENCHMARK //def _STFDEBUG current_utc_time(&time1); double accum = tdiff(time1, time0)*1e3; std::string fn_platform = "plt_bench_" + stf::wx2std(wxGetOsDescription()) + ".txt"; std::ofstream plt_bench; plt_bench.open(fn_platform.c_str(), std::ios::out | std::ios::app); plt_bench << end-start << "\t" << accum << "\t"; current_utc_time(&time0); x_last = xFormat(start); #else } else { #endif double y_max = trace[start]; double y_min = trace[start]; for (int n=start; n y_max) { y_max = trace[n+1]; } } else { // plot line between extrema of previous column: pDC->DrawLine( x_last, yFormatFunc(y_min), x_last, yFormatFunc(y_max) ); // plot line between last point of previous and first point of this column: pDC->DrawLine( x_last, yFormatFunc(trace[n]), x_next, yFormatFunc(trace[n+1]) ); y_min = trace[n+1]; y_max = trace[n+1]; x_last = x_next; } } #ifdef BENCHMARK //def _STFDEBUG current_utc_time(&time1); accum = tdiff(time1, time0)*1e3; plt_bench << accum << std::endl; plt_bench.close(); #else } #endif } void wxStfGraph::PrintScale(wxRect& WindowRect) { //enhance resolution for printing - see OnPrint() //Ensures the scaling of all pixel dependent drawings for (std::size_t n=0; n < Doc()->size(); ++n) { Doc()->GetYZoomW(n) = Doc()->GetYZoomW(n) * printScale; } Doc()->GetXZoomW() = Doc()->GetXZoomW() * printScale; WindowRect=printRect; //Calculate scaling variables boebbelPrint=(int)(boebbelStd * printScale); if ( boebbelPrint < 1 ) boebbelPrint=2; printSizePen1=(int)(1 * printScale); if ( printSizePen1 < 1 ) boebbelPrint=1; printSizePen2=(int)(2 * printScale); if ( printSizePen2 < 1 ) boebbelPrint=2; printSizePen4=(int)(4 * printScale); if ( printSizePen4 < 1 ) boebbelPrint=4; } void wxStfGraph::PrintTrace( wxDC* pDC, const Vector_double& trace, plottype ptype ) { // speed up drawing by omitting points that are outside the window: // find point before left window border: // xFormat=toFormat * zoom.xZoom + zoom.startPosX // for xFormat==0: // toFormat=-zoom.startPosX/zoom.xZoom std::size_t start=0; int x0i=int(-SPX()/XZ()); if (x0i>=0 && x0i<(int)trace.size()-1) start=x0i; // find point after right window border: // for xFormat==right: // toFormat=(right-zoom.startPosX)/zoom.xZoom std::size_t end=trace.size(); wxRect WindowRect=GetRect(); if (isPrinted) WindowRect=wxRect(printRect); int right=WindowRect.width; int xri=int((right-SPX())/XZ())+1; if (xri>=0 && xri<(int)trace.size()-1) end=xri; DoPrint(pDC, trace, start, end, ptype); } void wxStfGraph::DoPrint( wxDC* pDC, const Vector_double& trace, int start, int end, plottype ptype) { #if (__cplusplus < 201103) boost::function yFormatFunc; #else std::function yFormatFunc; #endif switch (ptype) { case active: yFormatFunc = std::bind( std::mem_fn(&wxStfGraph::yFormatD), this, std::placeholders::_1); break; default: yFormatFunc = std::bind( std::mem_fn(&wxStfGraph::yFormatD2), this, std::placeholders::_1); break; } std::vector points; int x_last = xFormat(start); int y_last = yFormatFunc( trace[start] ); int y_max = y_last; int y_min = y_last; int x_next = 0; int y_next = 0; points.push_back( wxPoint(x_last,y_last) ); for (int n=start; n y_max) { y_max = y_next; } } else { // else, always draw and reset extrema: if (y_min != y_next) { points.push_back( wxPoint(x_last, y_min) ); } if (y_max != y_next) { points.push_back( wxPoint(x_last, y_max) ); } points.push_back( wxPoint(x_next, y_next) ); y_min = y_next; y_max = y_next; x_last = x_next; } } pDC->DrawLines((int)points.size(),&points[0]); } void wxStfGraph::DrawCircle(wxDC* pDC, double x, double y, const wxPen& pen, const wxPen& printPen) { if (isPrinted) { pDC->SetPen(printPen); } else { pDC->SetPen(pen); } wxRect Frame( wxPoint(xFormat(x)-boebbel,yFormat(y)-boebbel), wxPoint(xFormat(x)+boebbel,yFormat(y)+boebbel) ); pDC->DrawEllipse(Frame); } void wxStfGraph::DrawVLine(wxDC* pDC, double x, const wxPen& pen, const wxPen& printPen) { wxRect WindowRect(GetRect()); if (isPrinted) { //Set WindowRect to print coordinates (page size) WindowRect=printRect; pDC->SetPen(printPen); } else { pDC->SetPen(pen); } pDC->DrawLine(xFormat(x),0,xFormat(x),WindowRect.height); } void wxStfGraph::DrawHLine(wxDC* pDC, double y, const wxPen& pen, const wxPen& printPen) { wxRect WindowRect(GetRect()); if (isPrinted) { //Set WindowRect to print coordinates (page size) WindowRect=printRect; pDC->SetPen(printPen); } else { pDC->SetPen(pen); } pDC->DrawLine(0, yFormat(y),WindowRect.width,yFormat(y)); } void wxStfGraph::eventArrow(wxDC* pDC, int eventIndex) { // we only need that if it's within the screen: wxRect WindowRect(GetRect()); if (xFormat(eventIndex)<0 || xFormat(eventIndex)>WindowRect.width) { return; } if (isPrinted) { //Set WindowRect to print coordinates (page size) WindowRect=printRect; } pDC->DrawLine(xFormat(eventIndex), 20, xFormat(eventIndex), 0); // arrow head: pDC->DrawLine(xFormat(eventIndex)-5, 15, xFormat(eventIndex), 20); pDC->DrawLine(xFormat(eventIndex)+5, 15, xFormat(eventIndex), 20); } void wxStfGraph::DrawFit(wxDC* pDC) { try { // go through selected traces: if ( isPrinted ) pDC->SetPen(fitSelectedPrintPen); else pDC->SetPen(fitSelectedPen); for ( std::size_t n_sel = 0; n_sel < Doc()->GetSelectedSections().size(); ++n_sel ) { std::size_t sel_index = Doc()->GetSelectedSections()[ n_sel ]; // Check whether this section contains a fit: try { stf::SectionAttributes sec_attr = Doc()->GetSectionAttributes(Doc()->GetCurChIndex(), sel_index); if ( sec_attr.isFitted && pFrame->ShowSelected() ) { PlotFit( pDC, stf::SectionPointer( &((*Doc())[Doc()->GetCurChIndex()][sel_index]), sec_attr ) ); } } catch (const std::out_of_range& e) { /* Do nothing */ } } // Active trace if ( isPrinted ) pDC->SetPen(fitPrintPen); else pDC->SetPen(fitPen); stf::SectionAttributes sec_attr = Doc()->GetCurrentSectionAttributes(); if (sec_attr.isFitted) { PlotFit( pDC, stf::SectionPointer( &((*Doc())[Doc()->GetCurChIndex()][Doc()->GetCurSecIndex()]), sec_attr) ); } } catch (const std::out_of_range& e) { } } void wxStfGraph::PlotFit( wxDC* pDC, const stf::SectionPointer& Sec ) { wxRect WindowRect = GetRect(); if (isPrinted) { //Set WindowRect to print coordinates (page size) WindowRect=printRect; } int firstPixel = xFormat( Sec.sec_attr.storeFitBeg ); if ( firstPixel < 0 ) firstPixel = 0; int lastPixel = xFormat( Sec.sec_attr.storeFitEnd ); if ( lastPixel > WindowRect.width + 1 ) lastPixel = WindowRect.width + 1; if (!isPrinted) { //Draw Fit on display //For display use point to point drawing double fit_time_1 = ( ((double)firstPixel - (double)SPX()) / XZ() - (double)Sec.sec_attr.storeFitBeg )* Doc()->GetXScale(); for ( int n_px = firstPixel; n_px < lastPixel-1; n_px++ ) { // Calculate pixel back to time (GetStoreFitBeg() is t=0) double fit_time_2 = ( ((double)n_px+1.0 - (double)SPX()) / XZ() - (double)Sec.sec_attr.storeFitBeg ) * Doc()->GetXScale(); // undo xFormat = (int)(toFormat * XZ() + SPX()); pDC->DrawLine( n_px, yFormat(Sec.sec_attr.fitFunc->func( fit_time_1, Sec.sec_attr.bestFitP)), n_px + 1, yFormat(Sec.sec_attr.fitFunc->func(fit_time_2, Sec.sec_attr.bestFitP)) ); fit_time_1 = fit_time_2; } } else { //Draw Fit for print out // For print out use polyline std::vector f_print( lastPixel - firstPixel ); for ( int n_px = firstPixel; n_px < lastPixel; n_px++ ) { // Calculate pixel back to time (GetStoreFitBeg() is t=0) double fit_time = ( ((double)n_px - (double)SPX()) / XZ() -(double)Sec.sec_attr.storeFitBeg ) * Doc()->GetXScale(); // undo xFormat = (int)(toFormat * XZ() + SPX()); f_print[n_px-firstPixel].x = n_px; f_print[n_px-firstPixel].y = yFormat( Sec.sec_attr.fitFunc->func( fit_time, Sec.sec_attr.bestFitP) ); } pDC->DrawLines( f_print.size(), &f_print[0] ); } //End if display or print out } void wxStfGraph::DrawIntegral(wxDC* pDC) { // Draws a polygon around the integral. Note that the polygon will be drawn // out of screen as well. stf::SectionAttributes sec_attr; try { sec_attr = Doc()->GetCurrentSectionAttributes(); } catch (const std::out_of_range& e) { return; } if (!isPrinted) { pDC->SetPen(scalePen); } else { pDC->SetPen(scalePrintPen); } bool even = std::div((int)sec_attr.storeIntEnd-(int)sec_attr.storeIntBeg, 2).rem==0; int firstPixel=xFormat(sec_attr.storeIntBeg); // last pixel: int lastPixel= even ? xFormat(sec_attr.storeIntEnd) : xFormat(sec_attr.storeIntEnd-1); std::size_t qt_size= lastPixel-firstPixel + // part that covers the trace 2; // straight line through base or 0 if (!even) qt_size++; //straight line for trapezoidal part std::vector quadTrace; quadTrace.reserve(qt_size); quadTrace.push_back(wxPoint(firstPixel,yFormat(Doc()->GetBase()))); // "Simpson part" (piecewise quadratic functions through three adjacent points): for (int n_pixel=firstPixel; n_pixel < lastPixel; ++n_pixel) { // (lower) index corresponding to pixel: int n_relIndex = (int)(((double)n_pixel-(double)SPX())/(double)XZ()-sec_attr.storeIntBeg); if (n_relIndex >= 0 && (unsigned int)(n_relIndex/2)*3+2 < sec_attr.quad_p.size()) { double n_absIndex = ((double)n_pixel-(double)SPX())/(double)XZ(); // quadratic parameters at this point: double a = sec_attr.quad_p[(int)(n_relIndex/2)*3]; double b = sec_attr.quad_p[(int)(n_relIndex/2)*3+1]; double c = sec_attr.quad_p[(int)(n_relIndex/2)*3+2]; double y = a*n_absIndex*n_absIndex + b*n_absIndex + c; quadTrace.push_back(wxPoint(n_pixel,yFormat(y))); } } // add trapezoidal integration part if uneven: if (!even) { // draw a straight line: quadTrace.push_back( wxPoint( xFormat(sec_attr.storeIntEnd), yFormat(Doc()->cursec()[sec_attr.storeIntEnd]) )); } quadTrace.push_back( wxPoint( xFormat(sec_attr.storeIntEnd), yFormat(Doc()->GetBase()) )); // Polygon from base: pDC->SetBrush(baseBrush); pDC->DrawPolygon((int)quadTrace.size(),&quadTrace[0]); // Polygon from 0: quadTrace[0]=wxPoint(firstPixel,yFormat(0L)); quadTrace[quadTrace.size()-1]= wxPoint( xFormat(sec_attr.storeIntEnd), yFormat(0L) ); pDC->SetBrush(zeroBrush); pDC->DrawPolygon((int)quadTrace.size(),&quadTrace[0]); pDC->SetBrush(*wxTRANSPARENT_BRUSH); } void wxStfGraph::Snapshotwmf() { wxStfPreprintDlg myDlg(this,true); if (myDlg.ShowModal()!=wxID_OK) return; set_downsampling(myDlg.GetDownSampling()); // Get size of Graph, in pixels: wxRect screenRect(GetRect()); // Get size of page, in pixels: // assuming the screen is ~ 96 dpi, but we want ~ 720: printRect = wxRect(wxPoint(0,0), wxSize(GetRect().GetSize()*4)); double scale=(double)printRect.width/(double)screenRect.width; #if _WINDOWS // FIXME: for non-Windows platforms wxMetafileDC wmfDC; if (!wmfDC.IsOk()) #endif { wxGetApp().ErrorMsg(wxT("Error while creating clipboard data")); return; } set_noGimmicks(true); set_isPrinted(true); printScale=scale; #if _WINDOWS // FIXME: for non-Windows platforms OnDraw(wmfDC); #endif set_isPrinted(false); no_gimmicks=false; #if _WINDOWS // FIXME: for non-Windows platforms wxMetafile* mf = wmfDC.Close(); if (mf && mf->IsOk()) { mf->SetClipboard(); delete mf; } else #endif { wxGetApp().ErrorMsg(wxT("Error while copying to clipboard")); } } void wxStfGraph::OnMouseEvent(wxMouseEvent& event) { // event.Skip(); if (!view) return; if (event.LeftDown()) LButtonDown(event); if (event.RightDown()) RButtonDown(event); if (event.LeftUp()) LButtonUp(event); } void wxStfGraph::LButtonDown(wxMouseEvent& event) { // event.Skip(); if (!view) return; view->Activate(true); #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) if (!HasFocus()) #else if (wxWindow::FindFocus()!=(wxWindow*)this) #endif SetFocusIgnoringChildren(); wxClientDC dc(this); PrepareDC(dc); lastLDown = event.GetLogicalPosition(dc); switch (ParentFrame()->GetMouseQual()) { //Depending on the radio buttons (Mouse field) //in the (trace navigator) control box case stf::measure_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetMeasCursor( stf::round( ((double)lastLDown.x - (double)SPX())/XZ() ) ); //second 'double' added // in this case, update results string without waiting for "Return": pFrame->UpdateResults(); break; case stf::peak_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetPeakBeg( stf::round( ((double)lastLDown.x - (double)SPX())/XZ() ) ); //second 'double' added //Set x-value as lower limit of the peak calculation dialog box break; case stf::base_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetBaseBeg( stf::round( ((double)lastLDown.x - (double)SPX())/XZ() ) ); //second 'double' added break; case stf::decay_cursor: //conversion of pixel on screen to time (inversion of xFormat()) if (wxGetApp().GetCursorsDialog() != NULL && wxGetApp().GetCursorsDialog()->GetStartFitAtPeak()) { wxGetApp().ErrorMsg( wxT("Fit will start at the peak. Change cursor settings (Edit->Cursor settings) to set manually.") ); break; } Doc()->SetFitBeg( stf::round( ((double)lastLDown.x - (double)SPX())/XZ() ) ); //second 'double' added break; case stf::latency_cursor: if (Doc()->GetLatencyStartMode() != stf::manualMode) { Doc()->SetLatencyStartMode( stf::manualMode ); wxGetApp().ErrorMsg( wxT("The first latency cursor is set to manual mode") ); } Doc()->SetLatencyBeg(((double)lastLDown.x-(double)SPX())/XZ()); Refresh(); break; case stf::zoom_cursor: llz_x=(double)lastLDown.x; llz_y=(double)lastLDown.y; llz_y2=llz_y; break; #ifdef WITH_PSLOPE case stf::pslope_cursor: Doc()->SetPSlopeBegMode(stf::psBeg_manualMode); // set left cursor to manual // conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetPSlopeBeg( stf::round( ((double)lastLDown.x - (double)SPX())/XZ() ) ); // second 'double' added break; #endif default: break; } //End switch TraceNav->GetMouseQual() if (wxGetApp().GetCursorsDialog()!=NULL && wxGetApp().GetCursorsDialog()->IsShown()) { try { wxGetApp().GetCursorsDialog()->UpdateCursors(); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal) ); } } } void wxStfGraph::RButtonDown(wxMouseEvent& event) { // event.Skip(); if (!view) return; view->Activate(true); #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) if (!HasFocus()) #else if (wxWindow::FindFocus()!=(wxWindow*)this) #endif SetFocusIgnoringChildren(); wxClientDC dc(this); PrepareDC(dc); wxPoint point(event.GetLogicalPosition(dc)); switch (ParentFrame()->GetMouseQual()) { case stf::peak_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetPeakEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); break; case stf::base_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetBaseEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); break; case stf::decay_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetFitEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); break; case stf::latency_cursor: if (Doc()->GetLatencyEndMode() != stf::manualMode) { Doc()->SetLatencyEndMode( stf::manualMode ); wxGetApp().ErrorMsg( wxT("The second latency cursor is set to manual mode") ); } Doc()->SetLatencyEnd(((double)point.x-(double)SPX())/XZ()); Refresh(); break; case stf::zoom_cursor: if (isZoomRect) { PopupMenu(m_zoomContext.get()); } else { wxGetApp().ErrorMsg(wxT("Draw a zoom window with the left mouse button first")); } break; case stf::event_cursor: try { if (!Doc()->GetCurrentSectionAttributes().eventList.empty()) { // store the position that has been clicked: eventPos = stf::round( ((double)point.x - (double)SPX())/XZ() ); PopupMenu(m_eventContext.get()); } else { wxGetApp().ErrorMsg(wxT("No events have been detected yet")); } } catch (const std::out_of_range& e) { } break; #ifdef WITH_PSLOPE case stf::pslope_cursor: Doc()->SetPSlopeEndMode(stf::psEnd_manualMode); // set right cursor to manual mode Doc()->SetPSlopeEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); break; #endif default: ; } //End switch TraceNav->GetMouseQual() if (wxGetApp().GetCursorsDialog()!=NULL && wxGetApp().GetCursorsDialog()->IsShown()) { try { wxGetApp().GetCursorsDialog()->UpdateCursors(); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal) ); } } Refresh(); } void wxStfGraph::LButtonUp(wxMouseEvent& event) { // event.Skip(); wxClientDC dc(this); PrepareDC(dc); wxPoint point(event.GetLogicalPosition(dc)); if (point == lastLDown) { Refresh(); return; } switch (ParentFrame()->GetMouseQual()) { case stf::peak_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetPeakEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); break; case stf::base_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetBaseEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); break; case stf::decay_cursor: //conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetFitEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); break; #ifdef WITH_PSLOPE case stf::pslope_cursor: // conversion of pixel on screen to time (inversion of xFormat()) Doc()->SetPSlopeEnd( stf::round( ((double)point.x - (double)SPX())/XZ() ) ); #endif case stf::latency_cursor: if (Doc()->GetLatencyEndMode() != stf::manualMode) { wxGetApp().ErrorMsg( wxT("The latency cursor can not be set in the current mode\n \ Choose manual mode to set the latency cursor manually") ); break; } Doc()->SetLatencyEnd(((double)point.x-(double)SPX())/XZ()); break; case stf::zoom_cursor: ulz_x=(double)point.x; ulz_y=(double)point.y; ulz_y2=ulz_y; if (llz_x>ulz_x) std::swap(llz_x,ulz_x); if (llz_y>ulz_y) std::swap(llz_y,ulz_y); if (llz_y2>ulz_y2) std::swap(llz_y2,ulz_y2); isZoomRect=true; break; default: break; } Refresh(); } void wxStfGraph::OnKeyDown(wxKeyEvent& event) { // event.Skip(); if (!view) return; view->Activate(true); int kc = event.GetKeyCode(); #ifdef _STFDEBUG std::cout << "User pressed " << char(kc) << ", corresponding keycode is " << kc << std::endl; std::cout << "Mouse Cursor Mode " << ParentFrame()->GetMouseQual() << std::endl; #endif wxRect WindowRect(GetRect()); switch (kc) { case WXK_LEFT: //left cursor if (event.ControlDown()) { OnLeft(); return; } if (event.ShiftDown()) { SPXW() = SPX()-WindowRect.width; Refresh(); return; } OnPrevious(); return; case WXK_RIGHT: {//right cursor if (event.ControlDown()) { OnRight(); return; } if (event.ShiftDown()) { SPXW() = SPX()+WindowRect.width; Refresh(); return; } OnNext(); return; } case WXK_DOWN: //down cursor if (event.ControlDown()) { ChanScroll(-1); } else { OnDown(); } return; case WXK_UP: //up cursor if (event.ControlDown()) { ChanScroll(1); } else { OnUp(); } return; case 49: //1 ParentFrame()->SetZoomQual(stf::zoomch1); return; case 50: //2 if (Doc()->size()>1) ParentFrame()->SetZoomQual(stf::zoomch2); return; case 51: //3 if (Doc()->size()>1) ParentFrame()->SetZoomQual(stf::zoomboth); return; case 69: // e case 101: ParentFrame()->SetMouseQual(stf::event_cursor); return; case 70: case 102: // f Fittowindow(true); return; case 77: // m case 109: ParentFrame()->SetMouseQual(stf::measure_cursor); return; case 80: // p case 112: ParentFrame()->SetMouseQual(stf::peak_cursor); return; case 65: // 'a' case 97: // Select all traces: if (event.ControlDown()) { wxCommandEvent com; Doc()->Selectall(com); return; } return; case 66: // b case 98: ParentFrame()->SetMouseQual(stf::base_cursor); return; #ifdef WITH_PSLOPE case 79: // key 'o' to activate PSlope cursors case 111: ParentFrame()->SetMouseQual(stf::pslope_cursor); return; #endif case 68: // d case 100: ParentFrame()->SetMouseQual(stf::decay_cursor); return; case 90: // z case 122: ParentFrame()->SetMouseQual(stf::zoom_cursor); return; case 76: // l case 108: ParentFrame()->SetMouseQual(stf::latency_cursor); return; case WXK_RETURN: //Enter or Return { wxGetApp().OnPeakcalcexecMsg(); pFrame->UpdateResults(); return; } case 83: // Invalidate();//s case 115: { Doc()->Select(); return; } case 88: // x case 120: { wxCommandEvent foo; Doc()->OnSwapChannels(foo); return; } case 82: // Invalidate();//r case 114: { Doc()->Remove(); return; } } switch (char(kc)) { case '0': case '=': case '+': if (event.ControlDown()) { OnXenllo(); return; } OnYenllo(); return; case '-': if (event.ControlDown()) { OnXshrinklo(); return; } OnYshrinklo(); return; } } void wxStfGraph::OnZoomHV(wxCommandEvent& event) { OnZoomH(event); OnZoomV(event); } void wxStfGraph::OnZoomH(wxCommandEvent& WXUNUSED(event)) { wxRect WindowRect=GetRect(); llz_x=(llz_x - SPX()) / XZ(); ulz_x=(ulz_x - SPX()) / XZ(); int points=(int)(ulz_x - llz_x); XZW()=(double)WindowRect.width / points; SPXW()=(int)(-llz_x * XZ()); isZoomRect=false; } void wxStfGraph::OnZoomV(wxCommandEvent& WXUNUSED(event)) { wxRect WindowRect=GetRect(); llz_y=(SPY() - llz_y) / YZ(); ulz_y=(SPY() - ulz_y) / YZ(); YZW()=WindowRect.height/fabs(ulz_y-llz_y); SPYW()=(int)(WindowRect.height + ulz_y * YZ()); if (Doc()->size() > 1) { llz_y2=(SPY2()-llz_y2)/YZ2(); ulz_y2=(SPY2()-ulz_y2)/YZ2(); YZ2W()=WindowRect.height/fabs(ulz_y2-llz_y2); SPY2W()=(int)(WindowRect.height + ulz_y2 * YZ2()); } isZoomRect=false; } #if defined __WXMAC__ && !(wxCHECK_VERSION(2, 9, 0)) void wxStfGraph::OnPaint(wxPaintEvent &WXUNUSED(event)) { wxPaintDC PDC(this); OnDraw(PDC); } #endif double prettyNumber( double fDistance, double pixelDistance, int limit ) { double fScaled = 1.0; for (;;) { //set stepsize int nZeros = (int)log10(fScaled); int prev10e = (int)(pow(10.0, nZeros)); int next10e = prev10e * 10; int step = prev10e < 1 ? 1 : prev10e; if ( fScaled / prev10e > 5 ) { fScaled = next10e; step = next10e; } //check whether f scale is ok if ((fScaled/fDistance) * pixelDistance > limit || fScaled>1e9) break; else { //suggest a new f scale: fScaled += step; } } return fScaled; } void wxStfGraph::CreateScale(wxDC* pDC) { // catch bizarre y-Zooms: double fstartPosY=(double)SPY(); if (fabs(fstartPosY)>(double)1.0e15) SPYW()=0; if (fabs(YZ())>1e15) YZW()=1.0; if (!isPrinted) { wxFont font((int)(8*printScale), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); pDC->SetFont(font); } //Copy main window coordinates to 'WindowRect' wxRect WindowRect(GetRect()); if (isPrinted) { //Set WindowRect to print coordinates (page size) WindowRect=printRect; } //1. Creation of x-(time-)scale: //distance between two neigboured time steps in pixels: XZW()=XZ()>0 ? XZ() : 1.0; double pixelDistance=XZ(); //distance between time steps in msec: //(it might be more elegant to read out the equalspaced step size // directly from the Doc()) double timeDistance=1.0/Doc()->GetSR(); //i.e., 1 timeDistance corresponds to 1 pixelDistance //get an integer time value which comes close to 150 pixels: int limit=(int)(100*printScale); double timeScaled = prettyNumber(timeDistance, pixelDistance, limit); int barLength=(int)((timeScaled/timeDistance) * pixelDistance); //2. creation of y-(voltage- or current-)scale //distance between two neigboured yValues in pixels: YZW()=YZ()>1e-9 ? YZ() : 1.0; double pixelDistanceY=YZ(); //real distance (difference) between two neighboured Values: double realDistanceY=1.0; //get an integer y-value which comes close to 150 pixels: double yScaled = prettyNumber(realDistanceY, pixelDistanceY, limit); int barLengthY=(int)((yScaled/realDistanceY) * pixelDistanceY); //3. creation of y-scale for the second channel //Fit scale of second channel to window //distance between two neigboured yValues in pixels: int barLengthY2=100; double yScaled2 =1.0; double pixelDistanceY2= 1.0; //real distance (difference) between two neighboured Values: double realDistanceY2 = 1.0; if ((Doc()->size()>1)) { pixelDistanceY2= YZ2(); //get an entire y-value which comes close to 150 pixels: yScaled2 = prettyNumber(realDistanceY2, pixelDistanceY2, limit); barLengthY2=(int)((yScaled2/realDistanceY2) * pixelDistanceY2); } //End creation y-scale of the 2nd Channel if (wxGetApp().get_isBars()) { // Use scale bars std::vector Scale(5); // Distance of scale bar from bottom and right border of window: int bottomDist=(int)(50*printScale); int rightDist=(int)(60*printScale); // leave space for a second scale bar: if ((Doc()->size()>1)) rightDist*=2; // Set end points for the scale bar Scale[0]=wxPoint(WindowRect.width-rightDist-barLength, WindowRect.height-bottomDist); Scale[1]=wxPoint(WindowRect.width-rightDist, WindowRect.height-bottomDist); Scale[2]=wxPoint(WindowRect.width-rightDist, WindowRect.height-bottomDist-barLengthY); if (Doc()->size()>1 && pFrame->ShowSecond()) { //Set end points for the second channel y-bar Scale[3]=wxPoint(WindowRect.width-rightDist/2, WindowRect.height-bottomDist); Scale[4]=wxPoint(WindowRect.width-rightDist/2, WindowRect.height-bottomDist-barLengthY2); } // Set scalebar labels wxString scaleXString; scaleXString << (int)timeScaled << wxT(" ms"); // Center of x-scalebar: int xCenter=WindowRect.width-(Scale[1].x-Scale[0].x)/2-rightDist; wxRect TextFrameX( wxPoint(xCenter-(int)(40*printScale),WindowRect.height-bottomDist+(int)(5.0*(double)printScale)), wxPoint(xCenter+(int)(40*printScale),WindowRect.height-bottomDist+(int)(25.0*(double)printScale)) ); if (!isLatex) { pDC->DrawLabel( scaleXString,TextFrameX,wxALIGN_CENTRE_HORIZONTAL | wxALIGN_TOP ); } else { #if 0 wxLatexDC* pLatexDC = (wxLatexDC*)pDC; pLatexDC->DrawLabelLatex( scaleXString, TextFrameX,wxALIGN_CENTRE_HORIZONTAL | wxALIGN_TOP ); #endif } wxString scaleYString; #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) scaleYString << (int)yScaled << wxT(" ") << Doc()->at(Doc()->GetCurChIndex()).GetYUnits() << wxT("\0"); #else scaleYString << (int)yScaled << wxT(" ") << wxString(Doc()->at(Doc()->GetCurChIndex()).GetYUnits().c_str(), wxConvUTF8) << wxT("\0"); #endif // Center of y-scalebar: int yCenter=WindowRect.height-bottomDist-(Scale[1].y-Scale[2].y)/2; wxRect TextFrameY( wxPoint(WindowRect.width-rightDist+(int)(5*printScale),yCenter-(int)(10*printScale)), wxPoint(WindowRect.width,yCenter+(int)(10*printScale)) ); if (!isLatex) { pDC->DrawLabel(scaleYString,TextFrameY,wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); } else { #if 0 wxLatexDC* pLatexDC = (wxLatexDC*)pDC; pLatexDC->DrawLabelLatex(scaleYString,TextFrameY,wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); #endif } if (Doc()->size()>1 && pFrame->ShowSecond()) { wxString scaleYString2; scaleYString2 << (int)yScaled2 << wxT(" ") #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) << Doc()->at(Doc()->GetSecChIndex()).GetYUnits(); #else << wxString(Doc()->at(Doc()->GetSecChIndex()).GetYUnits().c_str(), wxConvUTF8); #endif // Center of y2-scalebar: int y2Center=WindowRect.height-bottomDist-(Scale[3].y-Scale[4].y)/2; wxRect TextFrameY2( wxPoint(WindowRect.width-rightDist/2+(int)(5*printScale),y2Center-(int)(10*printScale)), wxPoint(WindowRect.width,y2Center+(int)(10*printScale)) ); pDC->SetTextForeground(*wxRED); if (!isLatex) { pDC->DrawLabel(scaleYString2,TextFrameY2,wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); } else { #if 0 wxLatexDC* pLatexDC = (wxLatexDC*)pDC; pLatexDC->DrawLabelLatex(scaleYString2,TextFrameY2,wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); #endif } pDC->SetTextForeground(*wxBLACK); } //Set PenStyle if (!isPrinted) pDC->SetPen(scalePen); else pDC->SetPen(scalePrintPen); //Plot them pDC->DrawLine(Scale[0],Scale[1]); pDC->DrawLine(Scale[1],Scale[2]); if (Doc()->size()>1 && pFrame->ShowSecond()) { if (!isPrinted) pDC->SetPen(scalePen2); else pDC->SetPen(scalePrintPen2); pDC->DrawLine(Scale[3],Scale[4]); } } else { // Use grid // Added 11/02/2006, CSH // Distance of coordinates from bottom, left, top and right border of window: int bottomDist=(int)(50*printScale); int leftDist=(int)(50*printScale); int topDist=(int)(20*printScale); int rightDist=(int)(20*printScale); // upper left corner: pDC->DrawLine(leftDist,topDist,leftDist,WindowRect.height-bottomDist); // lower right corner: pDC->DrawLine(leftDist,WindowRect.height-bottomDist, WindowRect.width-rightDist,WindowRect.height-bottomDist); // second y-axis: if (Doc()->size()>1 && pFrame->ShowSecond()) { pDC->SetPen(scalePen2); // upper left corner: pDC->DrawLine(leftDist*2,topDist,leftDist*2,WindowRect.height-bottomDist); } //Set PenStyle if (!isPrinted) pDC->SetPen(scalePen); else pDC->SetPen(scalePrintPen); // Set ticks: int tickLength=(int)(10*printScale); // Find first y-axis tick: // Get y-value of bottomDist: double yBottom=(SPY()-(WindowRect.height-bottomDist))/YZ(); // Find next-higher integer multiple of barLengthY: int nextTickMult=(int)(yBottom/yScaled); // nextTickMult is truncated; hence, negative and positive values // have to be treated separately: if (yBottom>0) { nextTickMult++; } // pixel position of this tick: double yFirst=nextTickMult*yScaled; int yFirstTick=yFormat(yFirst); // How many times does the y-scale bar fit into the window? int yScaleInWindow=(yFirstTick-topDist)/barLengthY; // y-Axis ticks: for (int n_tick_y=0;n_tick_y<=yScaleInWindow;++n_tick_y) { pDC->DrawLine(leftDist-tickLength, yFirstTick-n_tick_y*barLengthY, leftDist, yFirstTick-n_tick_y*barLengthY); // Create a rectangle from the left window border to the tick: wxRect TextFrame( wxPoint(0,yFirstTick-n_tick_y*barLengthY-(int)(10*printScale)), wxPoint(leftDist-tickLength-1,yFirstTick-n_tick_y*barLengthY+(int)(10*printScale)) ); // Draw Text: int y=(int)(yScaled*n_tick_y+yFirst); wxString yLabel;yLabel << y; pDC->DrawLabel(yLabel,TextFrame,wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); } // Write y units: // Length of y-axis: int yLength=WindowRect.height-topDist-bottomDist; // position of vertical center: int vCenter=topDist+yLength/2; wxRect TextFrame( wxPoint(2,vCenter-(int)(10*printScale)), wxPoint(leftDist-tickLength-1,vCenter+(int)(10*printScale)) ); pDC->DrawLabel( #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) Doc()->at(Doc()->GetCurChIndex()).GetYUnits(), #else wxString(Doc()->at(Doc()->GetCurChIndex()).GetYUnits().c_str(), wxConvUTF8), #endif TextFrame, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL ); // y-Axis of second channel: if (Doc()->size()>1 && pFrame->ShowSecond()) { pDC->SetPen(scalePen2); // Find first y-axis tick: // Get y-value of bottomDist: double y2Bottom=(SPY2()-(WindowRect.height-bottomDist))/YZ2(); // Find next-higher integer multiple of barLengthY: int nextTickMult=(int)(y2Bottom/yScaled2); // nextTickMult is truncated; hence, negative and positive values // have to be treated separately: if (y2Bottom>0) { nextTickMult++; } // pixel position of this tick: double y2First=nextTickMult*yScaled2; int y2FirstTick=yFormat2(y2First); // How many times does the y-scale bar fit into the window? int y2ScaleInWindow = 1; if (barLengthY2 > 0) { y2ScaleInWindow = (y2FirstTick-topDist)/barLengthY2; } else { y2ScaleInWindow = (y2FirstTick-topDist)/1e-15; } // y-Axis ticks: for (int n_tick_y=0;n_tick_y<=y2ScaleInWindow;++n_tick_y) { pDC->DrawLine(leftDist*2-tickLength, y2FirstTick-n_tick_y*barLengthY2, leftDist*2, y2FirstTick-n_tick_y*barLengthY2); // Create a rectangle from the left window border to the tick: wxRect TextFrame2( wxPoint(0,y2FirstTick-n_tick_y*barLengthY2-(int)(10*printScale)), wxPoint(leftDist*2-tickLength-1,y2FirstTick-n_tick_y*barLengthY2+(int)(10*printScale)) ); // Draw Text: int y2=(int)(yScaled2*n_tick_y+y2First); wxString y2Label; y2Label << y2; pDC->SetTextForeground(*wxRED); pDC->DrawLabel(y2Label,TextFrame2,wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); pDC->SetTextForeground(*wxBLACK); } // Write y units: // Length of y-axis: int y2Length=WindowRect.height-topDist-bottomDist; // position of vertical center: int v2Center=topDist+y2Length/2; wxRect TextFrame2( wxPoint(2+leftDist,v2Center-(int)(10*printScale)), wxPoint(leftDist*2-tickLength-1,v2Center+(int)(10*printScale)) ); pDC->SetTextForeground(*wxRED); pDC->DrawLabel( #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) Doc()->at(Doc()->GetSecChIndex()).GetYUnits(), #else wxString(Doc()->at(Doc()->GetSecChIndex()).GetYUnits().c_str(), wxConvUTF8), #endif TextFrame2, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL ); pDC->SetTextForeground(*wxBLACK); } // x-Axis ticks: // if x axis starts with the beginning of the trace, find first tick: int xFirstTick=leftDist; double xFirst=0.0; if (isSyncx) { // Find first x-axis tick: // Get x-value of leftDist: double xLeft=(leftDist-SPX())/XZ()*Doc()->GetXScale(); // Find next-higher integer multiple of barLengthX: int nextTickMult=(int)(xLeft/timeScaled); // nextTickMult is truncated; hence, negative and positive values // have to be treated separately: if (xLeft>0) { nextTickMult++; } // pixel position of this tick: xFirst=nextTickMult*timeScaled; double xFirstSamplingPoint=xFirst/Doc()->GetXScale(); // units of sampling points xFirstTick=xFormat(xFirstSamplingPoint); } // How many times does the x-scale bar fit into the window? int xScaleInWindow=(WindowRect.width-xFirstTick-rightDist)/barLength; pDC->SetPen(scalePen); for (int n_tick_x=0;n_tick_x<=xScaleInWindow;++n_tick_x) { pDC->DrawLine(xFirstTick+n_tick_x*barLength, WindowRect.height-bottomDist+tickLength, xFirstTick+n_tick_x*barLength, WindowRect.height-bottomDist); // Create a rectangle: wxRect TextFrame( wxPoint( xFirstTick+n_tick_x*barLength-(int)(40*printScale), WindowRect.height-bottomDist+tickLength ), wxPoint( xFirstTick+n_tick_x*barLength+(int)(40*printScale), WindowRect.height-bottomDist+tickLength+(int)(20*printScale) ) ); // Draw Text: int x=(int)(timeScaled*n_tick_x+xFirst); wxString xLabel; xLabel << x; pDC->DrawLabel(xLabel,TextFrame,wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); } // Draw x-units: // Length of x-axis: int xLength=WindowRect.width-leftDist-rightDist; // position of horizontal center: int hCenter=leftDist+xLength/2; wxRect xTextFrame( wxPoint( hCenter-(int)(40*printScale), WindowRect.height-bottomDist+tickLength+(int)(20*printScale) ), wxPoint( hCenter+(int)(40*printScale), WindowRect.height-bottomDist+tickLength+(int)(40*printScale) ) ); #if (wxCHECK_VERSION(2, 9, 0) || defined(MODULE_ONLY)) pDC->DrawLabel(Doc()->GetXUnits(),xTextFrame,wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); #else pDC->DrawLabel(wxString(Doc()->GetXUnits().c_str(), wxConvUTF8),xTextFrame,wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); #endif } } inline long wxStfGraph::xFormat(double toFormat) { return (int)(toFormat * XZ() + SPX()); } inline long wxStfGraph::xFormat(long toFormat) { return (long)(toFormat * XZ() + SPX()); } inline long wxStfGraph::xFormat(int toFormat) { return (long)(toFormat * XZ() + SPX()); } inline long wxStfGraph::xFormat(std::size_t toFormat) { return (long)(toFormat * XZ() + SPX()); } inline long wxStfGraph::yFormat(double toFormat) { return (long)(SPY() - toFormat * YZ()); } inline long wxStfGraph::yFormat(long toFormat) { return (long)(SPY() - toFormat * YZ()); } inline long wxStfGraph::yFormat(int toFormat) { return (long)(SPY() - toFormat * YZ()); } inline long wxStfGraph::yFormat2(double toFormat) { return (long)(SPY2() - toFormat * YZ2()); } inline long wxStfGraph::yFormat2(long toFormat){ return (long)(SPY2() - toFormat * YZ2()); } inline long wxStfGraph::yFormat2(int toFormat){ return (long)(SPY2() - toFormat * YZ2()); } inline long wxStfGraph::yFormatB(double toFormat) { return (long)(yzoombg.startPosY - toFormat * yzoombg.yZoom); } inline long wxStfGraph::yFormatB(long toFormat){ return (long)(yzoombg.startPosY - toFormat * yzoombg.yZoom); } inline long wxStfGraph::yFormatB(int toFormat){ return (long)(yzoombg.startPosY - toFormat * yzoombg.yZoom); } void wxStfGraph::FittorectY(YZoom& yzoom, const wxRect& rect, double min, double max, double screen_part) { yzoom.yZoom = (rect.height/fabs(max-min))*screen_part; yzoom.startPosY = (long)(((screen_part+1.0)/2.0)*rect.height + min * yzoom.yZoom); } void wxStfGraph::Fittowindow(bool refresh) { const double screen_part=0.5; //part of the window to be filled std::size_t points=Doc()->cursec().size(); if (points==0) { wxGetApp().ErrorMsg(wxT("Array of size zero in wxGraph::Fittowindow()")); return; } #if (__cplusplus < 201103) Vector_double::const_iterator max_el = std::max_element(Doc()->cursec().get().begin(), Doc()->cursec().get().end()); Vector_double::const_iterator min_el = std::min_element(Doc()->cursec().get().begin(), Doc()->cursec().get().end()); #else Vector_double::const_iterator max_el = std::max(Doc()->cursec().get().begin(), Doc()->cursec().get().end()); Vector_double::const_iterator min_el = std::min(Doc()->cursec().get().begin(), Doc()->cursec().get().end()); #endif double min = *min_el; if (min>1.0e12) min= 1.0e12; if (min<-1.0e12) min=-1.0e12; double max = *max_el; if (max>1.0e12) max= 1.0e12; if (max<-1.0e12) max=-1.0e12; wxRect WindowRect(GetRect()); switch (ParentFrame()->GetZoomQual()) { //Depending on the zoom radio buttons (Mouse field) //in the (trace navigator) control box case stf::zoomboth: if(!(Doc()->size()>1)) return; //Fit to window Ch2 FitToWindowSecCh(false); //Fit to window Ch1 XZW()=(double)WindowRect.width /points; SPXW()=0; FittorectY(Doc()->GetYZoomW(Doc()->GetCurChIndex()), WindowRect, min, max, screen_part); break; case stf::zoomch2: //ErrorMsg if no second channel available if(!(Doc()->size()>1)) return; //Fit to window Ch2 FitToWindowSecCh(false); break; default: //ErrorMsg if no second channel available // Invalidate(); //Fit to window Ch1 XZW()=(double)WindowRect.width /points; SPXW()=0; FittorectY(Doc()->GetYZoomW(Doc()->GetCurChIndex()), WindowRect, min, max, screen_part); break; } if (refresh) Refresh(); } void wxStfGraph::FitToWindowSecCh(bool refresh) { if (Doc()->size()>1) { //Get coordinates of the main window wxRect WindowRect(GetRect()); const double screen_part=0.5; //part of the window to be filled std::size_t secCh=Doc()->GetSecChIndex(); #undef min #undef max #if (__cplusplus < 201103) Vector_double::const_iterator max_el = std::max_element(Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().begin(), Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().end()); Vector_double::const_iterator min_el = std::min_element(Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().begin(), Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().end()); #else Vector_double::const_iterator max_el = std::max(Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().begin(), Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().end()); Vector_double::const_iterator min_el = std::min(Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().begin(), Doc()->get()[secCh][Doc()->GetCurSecIndex()].get().end()); #endif double min=*min_el; double max=*max_el; FittorectY(Doc()->GetYZoomW(Doc()->GetSecChIndex()), WindowRect, min, max, screen_part); if (refresh) Refresh(); } } //End FitToWindowSecCh() void wxStfGraph::ChangeTrace(std::size_t trace) { stf::SectionAttributes sec_attr = Doc()->GetCurrentSectionAttributes(); if (!sec_attr.eventList.empty() && trace != Doc()->GetCurSecIndex()) { for (event_it it2 = sec_attr.eventList.begin(); it2 != sec_attr.eventList.end(); ++it2) { it2->GetCheckBox()->Show(false); } } Doc()->SetSection(trace); wxGetApp().OnPeakcalcexecMsg(); pFrame->SetCurTrace(trace); Refresh(); } void wxStfGraph::OnPrevious() { if (Doc()->get()[Doc()->GetCurChIndex()].size()==1) return; std::size_t curSection=Doc()->GetCurSecIndex(); if (Doc()->GetCurSecIndex() > 0) curSection--; else curSection=Doc()->get()[Doc()->GetCurChIndex()].size()-1; ChangeTrace(curSection); } void wxStfGraph::OnFirst() { if (Doc()->GetCurSecIndex()==0) return; ChangeTrace(0); } void wxStfGraph::OnLast() { if (Doc()->GetCurSecIndex()==Doc()->get()[Doc()->GetCurChIndex()].size()-1) return; std::size_t curSection=Doc()->get()[Doc()->GetCurChIndex()].size()-1; ChangeTrace(curSection); } void wxStfGraph::OnNext() { if (Doc()->get()[Doc()->GetCurChIndex()].size()==1) return; std::size_t curSection=Doc()->GetCurSecIndex(); if (curSection < Doc()->get()[Doc()->GetCurChIndex()].size()-1) curSection++; else curSection=0; ChangeTrace(curSection); } void wxStfGraph::OnUp() { switch (ParentFrame()->GetZoomQual()) { //Depending on the zoom radio buttons (Mouse field) //in the (trace navigator) control box case stf::zoomboth: //ErrorMsg if no second channel available //yZooms of Ch1 are performed keeping the base constant SPYW()=SPY() - 20; if(!(Doc()->size()>1)) break; //Ymove of Ch2 is performed SPY2W()=SPY2() - 20; break; case stf::zoomch2: if(!(Doc()->size()>1)) break; //Ymove of Ch2 is performed SPY2W()=SPY2() - 20; break; default: //Ymove of Ch1 is performed SPYW()=SPY() - 20; break; } Refresh(); } void wxStfGraph::OnDown() { switch (ParentFrame()->GetZoomQual()) { //Depending on the zoom radio buttons (Mouse field) //in the (trace navigator) control box case stf::zoomboth: //yZooms of Ch1 are performed keeping the base constant SPYW()=SPY() + 20; if(!(Doc()->size()>1)) break; //Ymove of Ch2 is performed SPY2W()=SPY2() + 20; break; case stf::zoomch2: if(!(Doc()->size()>1)) break; //Ymove of Ch2 is performed SPY2W()=SPY2() + 20; break; default: //Ymove of Ch1 is performed SPYW()=SPY() + 20; break; } Refresh(); } void wxStfGraph::ChanScroll(int direction) { /* on Control + cursor press, adjust the active channel up or down. */ // direction is either +1, or -1 int ref_chan = Doc()->GetSecChIndex(); int new_chan = Doc()->GetCurChIndex() + direction; int last_chan = Doc()->size()-1; // Exit early if there is only one channel if (Doc()->size() == 1) { return; } /*Rollover conditions ------------------- I ended up resorting to ternery operators because I need to check both that we haven't gone over the document range and that we aren't hitting the reference channel */ if (new_chan == ref_chan) { // Skip the reference channel new_chan += direction; // move one unit past the ref channel. } if (new_chan > last_chan) { // Rollover to start if channel out of range // making sure to skip the reference channel new_chan = (ref_chan == 0)? 1 : 0; } else if (new_chan < 0) { // Rollover to end if channel out of range // making sure to skip the reference channel new_chan = (ref_chan == last_chan)? last_chan-1 : last_chan; } /*Update the window ----------------- */ // Pointer to wxStfChildFrame to access Channel selection combo wxStfChildFrame* pFrame = (wxStfChildFrame*)Doc()->GetDocumentWindow(); if (!pFrame) { return; } // set the channel selection combo //pFrame->SetChannels( actDoc()->GetCurChIndex(), actDoc()->GetSecChIndex()); pFrame->SetChannels(new_chan, ref_chan); pFrame->UpdateChannels(); // update according to the combo Refresh(); } void wxStfGraph::OnRight() { SPXW()=SPX() + 20; Refresh(); } void wxStfGraph::OnLeft() { SPXW()=SPX() - 20; Refresh(); } void wxStfGraph::OnXenlhi() { ChangeXScale(2.0); } void wxStfGraph::OnXenllo() { ChangeXScale(1.1); } void wxStfGraph::OnXshrinklo() { ChangeXScale(1.0/1.1); } void wxStfGraph::OnXshrinkhi() { ChangeXScale(0.5); } void wxStfGraph::ChangeXScale(double factor) { wxRect WindowRect(GetRect()); //point in the middle: double middle=(WindowRect.width/2.0 - SPX()) / XZ(); //new setting for xZoom XZW()=XZ() * factor; //calculation of new start position SPXW()=(int)(WindowRect.width/2.0 - middle * XZ()); Refresh(); } void wxStfGraph::OnYenlhi() { ChangeYScale(2.0); } void wxStfGraph::OnYenllo() { ChangeYScale(1.1); } void wxStfGraph::OnYshrinklo() { ChangeYScale(1/1.1); } void wxStfGraph::OnYshrinkhi() { ChangeYScale(0.5); } void wxStfGraph::ChangeYScale(double factor) { switch (ParentFrame()->GetZoomQual()) { // Depending on the zoom radio buttons (Mouse field) // in the (trace navigator) control box case stf::zoomboth: //yZooms of Ch1 are performed keeping the base constant SPYW()=(int)(SPY() + Doc()->GetBase() * (YZ() * factor - YZ())); YZW()=YZ() * factor; //ErrorMsg if no second channel available if (Doc()->size()<=1) break; //yZooms of Ch2 are performed keeping the base constant SPY2W()=(int)(SPY2() + Doc()->GetBase() * (YZ2() * factor - YZ2())); YZ2W()=YZ2() * factor; break; case stf::zoomch2: if (Doc()->size()<=1) break; //yZooms of Ch2 are performed keeping the base constant SPY2W()=(int)(SPY2() + Doc()->GetBase() * (YZ2() * factor - YZ2())); YZ2W()=YZ2() * factor; break; default: //yZooms of Ch1 are performed keeping the base constant SPYW()=(int)(SPY() + Doc()->GetBase() * (YZ() * factor - YZ())); YZW()=YZ() * factor; break; } Refresh(); } void wxStfGraph::Ch2base() { if ((Doc()->size()>1)) { double base2=0.0; try { double var2=0.0; base2=stfnum::base(Doc()->GetBaselineMethod(),var2,Doc()->get()[Doc()->GetSecChIndex()][Doc()->GetCurSecIndex()].get(), Doc()->GetBaseBeg(),Doc()->GetBaseEnd()); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal ) ); return; } double base1=Doc()->GetBase(); int base1_onScreen=yFormat(base1); // Adjust startPosY2 so that base2 is the same as base1 on the screen; // i.e. yFormat2(base2) == yFormat(base1) // this is what yFormat2(toFormat) does: // return (int)(zoom.startPosY2 - toFormat * zoom.yZoom2); // Solved for startPosY2, this gets: SPY2W()=(int)(base1_onScreen+base2*YZ2()); Refresh(); } } void wxStfGraph::Ch2pos() { if ((Doc()->size()>1)) { SPY2W()=SPY(); Refresh(); } } void wxStfGraph::Ch2zoom() { if ((Doc()->size()>1)) { YZ2W()=YZ(); Refresh(); } } void wxStfGraph::Ch2basezoom() { if ((Doc()->size()>1)) { // Adjust y-scale without refreshing: YZ2W()=YZ(); // Adjust baseline: double base2=0.0; try { double var2=0.0; base2=stfnum::base(Doc()->GetBaselineMethod(),var2,Doc()->get()[Doc()->GetSecChIndex()][Doc()->GetCurSecIndex()].get(), Doc()->GetBaseBeg(),Doc()->GetBaseEnd()); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal ) ); return; } double base1=Doc()->GetBase(); int base1_onScreen=yFormat(base1); // Adjust startPosY2 so that base2 is the same as base1 on the screen; // i.e. yFormat2(base2) == yFormat(base1) // this is what yFormat2(toFormat) does: // return (int)(zoom.startPosY2 - toFormat * zoom.yZoom2); // Solved for startPosY2, this gets: SPY2W()=(int)(base1_onScreen+base2*YZ2()); Refresh(); } } void wxStfGraph::set_isPrinted(bool value) { if (value==false) { printScale=1.0; no_gimmicks=false; } else { #if defined __WXGTK__ || defined __APPLE__ printScale=0.25; #endif // store zoom settings upon switching from normal to print view: if (isPrinted==false) { // zoomOld=zoom; } } isPrinted=value; } stimfit-0.16.7/src/stimfit/gui/view.h0000775000175000017500000000673014750344764013153 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file view.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfView. */ #ifndef _VIEW_H #define _VIEW_H /*! \addtogroup wxstf * @{ */ #include class wxStfDoc; class wxStfGraph; //! The view class, derived from wxView. /*! It is used to model the viewing and editing component of the file-based data. * It is part of the document/view framework supported by wxWidgets. Note that * this class does almost nothing in stimfit. Its only purpose is to adhere to * the doc/view paradigm. All of the actual drawing happens in wxStfGraph. */ class wxStfView : public wxView { public: //! Constructor wxStfView(); //! Destructor ~wxStfView() {} //! Override default view creation /*! Creates a child frame and a graph, sets the window title. * \param doc Pointer to the attached document. * \param flags View creation flags. * \return true upon successful view creation, false otherwise. */ virtual bool OnCreate(wxDocument *doc, long flags); //! The drawing function (note that actual drawing happens in wxStfGraph::OnDraw()) /*! \param dc Pointer to the device context. * \sa wxStfGraph::OnDraw() */ virtual void OnDraw(wxDC *dc); //! Override default updating behaviour /*! Called when the graph should be refreshed. * \param sender Pointer to the view that requested the update. * \param hint Unused. */ virtual void OnUpdate(wxView *sender, wxObject *hint = (wxObject *) NULL); //! Override default file closing behaviour /*! \param deleteWindow true if the child frame should be deleted. * \return true if file closing was successful. */ virtual bool OnClose(bool deleteWindow = true); //! Retrieve the attached graph /*! \return A pointer to the attached graph. */ wxStfGraph* GetGraph() { return graph; } //! Retrieve the attached document /*! \return A pointer to the attached document. */ wxStfDoc* Doc(); //! Retrieve the attached document /*! \return A pointer to the attached document. */ wxStfDoc* DocC() const; protected: //! Called when the view is activated; dialogs and menus are then updated. /*! \param activate true if this view is being activated. * \param activeView Pointer to the view that is now active. * \param deactiveView Pointer to the view that has just been deactivated. */ virtual void OnActivateView(bool activate, wxView *activeView, wxView *deactiveView); private: DECLARE_DYNAMIC_CLASS(wxStfView) DECLARE_EVENT_TABLE() wxStfGraph *graph; wxStfChildFrame *childFrame; }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/copygrid.h0000775000175000017500000000650514750344764014021 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file copygrid.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfGrid. Derived from wxGrid to allow copying to clipboard. */ #ifndef _COPYGRID_H #define _COPYGRID_H /*! \addtogroup wxstf * @{ */ //! Derived from wxGrid. Allows to copy cells to the clipboard. class wxStfGrid : public wxGrid { DECLARE_CLASS(wxStfGrid) public: //! Constructor /*! \param parent Pointer to the parent window. * \param id Window id. * \param pos Initial window position. * \param size Initial window size. * \param style Grid style. * \param name Name of this grid. */ wxStfGrid( wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS, const wxString& name = wxGridNameStr ); //! Get the selection. /*! \return The selected cells as a string. */ wxString GetSelection() const {return selection;} // Get the context menu. /*! \return A pointer to the context menu. */ wxMenu* get_labelMenu() {return m_labelContext.get();} //! Updates the context menu. void ViewResults(); private: wxString selection; void Copy(wxCommandEvent& event); void OnRClick(wxGridEvent& event); void OnLabelRClick(wxGridEvent& event); void OnKeyDown(wxKeyEvent& event); void ViewCrosshair(wxCommandEvent& event); void ViewBaseline(wxCommandEvent& event); void ViewBaseSD(wxCommandEvent& event); void ViewThreshold(wxCommandEvent& event); void ViewPeakzero(wxCommandEvent& event); void ViewPeakbase(wxCommandEvent& event); void ViewPeakthreshold(wxCommandEvent& event); void ViewRTLoHi(wxCommandEvent& event); void ViewInnerRiseTime(wxCommandEvent& event); void ViewOuterRiseTime(wxCommandEvent& event); void ViewT50(wxCommandEvent& event); void ViewRD(wxCommandEvent& event); void ViewSloperise(wxCommandEvent& event); void ViewSlopedecay(wxCommandEvent& event); void ViewLatency(wxCommandEvent& event); #ifdef WITH_PSLOPE void ViewPSlope(wxCommandEvent& event); #endif void ViewCursors(wxCommandEvent& event); void SetCheckmark(const wxString& RegEntry, int id); #if (__cplusplus < 201103) boost::shared_ptr m_context; boost::shared_ptr m_labelContext; #else std::shared_ptr m_context; std::shared_ptr m_labelContext; #endif DECLARE_EVENT_TABLE() }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/zoom.cpp0000775000175000017500000000041514750344764013512 #include "./zoom.h" YZoom YZoom::operator*( double factor ) { return YZoom( long(startPosY*(double)factor), yZoom*factor, isLogScaleY ); } XZoom XZoom::operator*( double factor ) { return XZoom( long(startPosX*(double)factor), xZoom*factor, isLogScaleX ); } stimfit-0.16.7/src/stimfit/gui/doc.cpp0000775000175000017500000036370614752207205013300 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // doc.cpp // The document class, derived from both wxDocument and recording // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg // For compilers that support precompilation, includes "wx/wx.h". #include #include #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #if !wxUSE_DOC_VIEW_ARCHITECTURE #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h! #endif #include "./app.h" #include "./view.h" #include "./parentframe.h" #include "./childframe.h" #include "./dlgs/smalldlgs.h" #include "./dlgs/fitseldlg.h" #include "./dlgs/eventdlg.h" #include "./dlgs/cursorsdlg.h" #include "./../../libstfnum/stfnum.h" #include "./../../libstfnum/fit.h" #include "./../../libstfnum/funclib.h" #include "./../../libstfnum/measure.h" #include "./../../libstfio/stfio.h" #ifdef WITH_PYTHON #include "./../../pystfio/pystfio.h" #endif #include "./usrdlg/usrdlg.h" #include "./doc.h" #include "./graph.h" IMPLEMENT_DYNAMIC_CLASS(wxStfDoc, wxDocument) BEGIN_EVENT_TABLE( wxStfDoc, wxDocument ) EVT_MENU( ID_SWAPCHANNELS, wxStfDoc::OnSwapChannels ) EVT_MENU( ID_FILEINFO, wxStfDoc::Fileinfo) EVT_MENU( ID_NEWFROMSELECTEDTHIS, wxStfDoc::OnNewfromselectedThisMenu ) EVT_MENU( ID_MYSELECTALL, wxStfDoc::Selectall ) EVT_MENU( ID_UNSELECTALL, wxStfDoc::Deleteselected ) EVT_MENU( ID_SELECTSOME, wxStfDoc::Selectsome ) EVT_MENU( ID_UNSELECTSOME, wxStfDoc::Unselectsome ) EVT_MENU( ID_SELECT_AND_ADD, wxStfDoc::SelectTracesOfType ) EVT_MENU( ID_SELECT_AND_REMOVE, wxStfDoc::UnselectTracesOfType ) EVT_MENU( ID_CONCATENATE_MULTICHANNEL, wxStfDoc::ConcatenateMultiChannel ) EVT_MENU( ID_BATCH, wxStfDoc::OnAnalysisBatch ) EVT_MENU( ID_INTEGRATE, wxStfDoc::OnAnalysisIntegrate ) EVT_MENU( ID_DIFFERENTIATE, wxStfDoc::OnAnalysisDifferentiate ) EVT_MENU( ID_MULTIPLY, wxStfDoc::Multiply) EVT_MENU( ID_SUBTRACTBASE, wxStfDoc::SubtractBaseMenu ) EVT_MENU( ID_FIT, wxStfDoc::FitDecay) EVT_MENU( ID_LFIT, wxStfDoc::LFit) EVT_MENU( ID_LOG, wxStfDoc::LnTransform) EVT_MENU( ID_FILTER,wxStfDoc::Filter) EVT_MENU( ID_POVERN,wxStfDoc::P_over_N) EVT_MENU( ID_PLOTCRITERION,wxStfDoc::Plotcriterion) EVT_MENU( ID_PLOTCORRELATION,wxStfDoc::Plotcorrelation) EVT_MENU( ID_PLOTDECONVOLUTION,wxStfDoc::Plotdeconvolution) EVT_MENU( ID_EXTRACT,wxStfDoc::MarkEvents ) EVT_MENU( ID_THRESHOLD,wxStfDoc::Threshold) EVT_MENU( ID_VIEWTABLE, wxStfDoc::Viewtable) EVT_MENU( ID_EVENT_EXTRACT, wxStfDoc::Extract ) EVT_MENU( ID_EVENT_ERASE, wxStfDoc::InteractiveEraseEvents ) EVT_MENU( ID_EVENT_ADDEVENT, wxStfDoc::AddEvent ) END_EVENT_TABLE() static const int baseline=100; // static const double rtfrac = 0.2; // now expressed in percentage, see RTFactor wxStfDoc::wxStfDoc() : Recording(),peakAtEnd(false), startFitAtPeak(false), initialized(false),progress(true), Average(0), latencyStartMode(stf::riseMode), latencyEndMode(stf::footMode), latencyWindowMode(stf::defaultMode), direction(stfnum::both), #ifdef WITH_PSLOPE pslopeBegMode(stf::psBeg_manualMode), pslopeEndMode(stf::psEnd_manualMode), #endif baseBeg(0), baseEnd(0), peakBeg(0), peakEnd(0), fitBeg(0), fitEnd(0), baselineMethod(stfnum::mean_sd), #ifdef WITH_PSLOPE PSlopeBeg(0), PSlopeEnd(0), DeltaT(0), viewPSlope(true), #endif measCursor(0), ShowRuler(false), latencyStartCursor(0.0), latencyEndCursor(0.0), latency(0.0), base(0.0), APBase(0.0), baseSD(0.0), threshold(0.0), slopeForThreshold(20.0), peak(0.0), APPeak(0.0), tLoReal(0), tHiReal(0), t50LeftReal(0), t50RightReal(0), maxT(0.0), thrT(-1.0), maxRiseY(0.0), maxRiseT(0.0), maxDecayY(0.0), maxDecayT(0.0), maxRise(0.0), maxDecay(0.0), t50Y(0.0), APMaxT(0.0), APMaxRiseY(0.0), APMaxRiseT(0.0), APt50LeftReal(0.0), APrtLoHi(0.0), APtLoReal(0.0), APtHiReal(0.0), APt0Real(0.0), #ifdef WITH_PSLOPE PSlope(0.0), #endif rtLoHi(0.0), InnerLoRT(NAN), InnerHiRT(NAN), OuterLoRT(NAN), OuterHiRT(NAN), halfDuration(0.0), slopeRatio(0.0), t0Real(0.0), pM(1), RTFactor(20), tLoIndex(0), tHiIndex(0), t50LeftIndex(0), t50RightIndex(0), APt50LeftIndex(0), APt50RightIndex(0), APtLoIndex(0), APtHiIndex(0), fromBase(true), viewCrosshair(true), viewBaseline(true), viewBaseSD(true), viewThreshold(false), viewPeakzero(true), viewPeakbase(true), viewPeakthreshold(false), viewRTLoHi(true), viewInnerRiseTime(false), viewOuterRiseTime(false), viewT50(true), viewRD(true), viewSloperise(true), viewSlopedecay(true), viewLatency(true), viewCursors(true), xzoom(XZoom(0, 0.1, false)), yzoom(size(), YZoom(500,0.1,false)), sec_attr(size()) { for (std::size_t nchannel=0; nchannel < sec_attr.size(); ++nchannel) { sec_attr[nchannel].resize(at(nchannel).size()); } } wxStfDoc::~wxStfDoc() {} bool wxStfDoc::OnOpenPyDocument(const wxString& filename) { progress = false; bool success = OnOpenDocument( filename ); progress = true; return success; } bool wxStfDoc::OnOpenDocument(const wxString& filename) { // Check whether the file exists: if ( !wxFileName::FileExists( filename ) ) { wxString msg; msg << wxT("Couldn't find ") << filename; wxGetApp().ErrorMsg( msg ); return false; } // Store directory: wxFileName wxfFilename( filename ); wxGetApp().wxWriteProfileString( wxT("Settings"), wxT("Last directory"), wxfFilename.GetPath() ); if (wxDocument::OnOpenDocument(filename)) { //calls base class function wxString filter(wxT("*.") + wxfFilename.GetExt()); stfio::filetype type = stfio::findType(stf::wx2std(filter)); #if 0 // TODO: backport ascii if (type==stf::ascii) { if (!wxGetApp().get_directTxtImport()) { wxStfTextImportDlg ImportDlg( GetDocumentWindow(), stf::CreatePreview(filename), 1, false ); if (ImportDlg.ShowModal()!=wxID_OK) { get().clear(); return false; } // store settings in application: wxGetApp().set_txtImportSettings(ImportDlg.GetTxtImport()); } } #endif if (type == stfio::tdms) { #ifdef WITH_PYTHON if (!LoadTDMS(stf::wx2std(filename), *this)) { wxString errorMsg(wxT("Error opening file\n")); #else { wxString errorMsg(wxT("Error opening file - TDMS requires python \n")); #endif wxGetApp().ExceptMsg(errorMsg); get().clear(); return false; } } else { try { if (progress) { stf::wxProgressInfo progDlg("Reading file", "Opening file", 100); stfio::importFile(stf::wx2std(filename), type, *this, wxGetApp().GetTxtImport(), progDlg); } else { stfio::StdoutProgressInfo progDlg("Reading file", "Opening file", 100, true); stfio::importFile(stf::wx2std(filename), type, *this, wxGetApp().GetTxtImport(), progDlg); } } catch (const std::runtime_error& e) { wxString errorMsg(wxT("Error opening file\n")); errorMsg += wxString( e.what(),wxConvLocal ); wxGetApp().ExceptMsg(errorMsg); get().clear(); return false; } catch (const std::exception& e) { wxString errorMsg(wxT("Error opening file\n")); errorMsg += wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(errorMsg); get().clear(); return false; } catch (...) { wxString errorMsg(wxT("Error opening file\n")); wxGetApp().ExceptMsg(errorMsg); get().clear(); return false; } } if (get().empty()) { wxGetApp().ErrorMsg(wxT("File is probably empty\n")); get().clear(); return false; } if (get()[0].get().empty()) { wxGetApp().ErrorMsg(wxT("File is probably empty\n")); get().clear(); return false; } if (get()[0][0].get().empty()) { wxGetApp().ErrorMsg(wxT("File is probably empty\n")); get().clear(); return false; } wxStfParentFrame* pFrame = wxGetApp().GetMainFrame(); if (pFrame == NULL) { throw std::runtime_error("pFrame is 0 in wxStfDoc::OnOpenDocument"); } pFrame->SetSingleChannel( size() <= 1 ); if (InitCursors()!=wxID_OK) { get().clear(); wxGetApp().ErrorMsg(wxT( "Couldn't initialize cursors\n" )); return false; } //Select active channel to be displayed if (get().size()>1) { try { if (ChannelSelDlg() != true) { wxGetApp().ErrorMsg(wxT( "File is probably empty\n" )); get().clear(); return false; } } catch (const std::out_of_range& e) { wxString msg(wxT( "Channel could not be selected:" )); msg += wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(msg); get().clear(); return false; } } } else { wxGetApp().ErrorMsg(wxT( "Failure in wxDocument::OnOpenDocument\n" )); get().clear(); return false; } // Make sure curChannel and secondChannel are not out of range // so that we can use them safely without range checking: wxString msg(wxT( "Error while checking range:\nParts of the file might be empty\nClosing file now" )); if (!(get().size()>1)) { if (cursec().size()==0) { wxGetApp().ErrorMsg(msg); get().clear(); return false; } } else { if (cursec().size()==0 || secsec().size()==0) { wxGetApp().ErrorMsg(msg); get().clear(); return false; } } wxFileName fn(GetFilename()); SetTitle(fn.GetFullName()); PostInit(); return true; } void wxStfDoc::SetData( const Recording& c_Data, const wxStfDoc* Sender, const wxString& title ) { resize(c_Data.size()); std::copy(c_Data.get().begin(),c_Data.get().end(),get().begin()); CopyAttributes(c_Data); // Make sure curChannel and curSection are not out of range: std::out_of_range e("Data empty in wxStimfitDoc::SetData()"); if (get().empty()) { throw e; } wxStfParentFrame* pFrame = wxGetApp().GetMainFrame(); if (pFrame == NULL) { throw std::runtime_error("pFrame is 0 in wxStfDoc::SetData"); } pFrame->SetSingleChannel( size() <= 1 ); // If the title is not a zero string... if (title != wxT("\0")) { // ... reset its title ... SetTitle(title); } //Read object variables and ensure correct and appropriate values: if (Sender!=NULL) { CopyCursors(*Sender); SetLatencyBeg( Sender->GetLatencyBeg() ); SetLatencyEnd( Sender->GetLatencyEnd() ); //Get value of the reset latency cursor box //0=Off, 1=Peak, 2=Rise SetLatencyStartMode( Sender->GetLatencyStartMode() ); SetLatencyEndMode( Sender->GetLatencyEndMode() ); //SetLatencyWindowMode( Sender->GetLatencyWindowMode() ); #ifdef WITH_PSLOPE SetPSlopeBegMode ( Sender->GetPSlopeBegMode() ); SetPSlopeEndMode ( Sender->GetPSlopeEndMode() ); #endif // Update menu checks: // UpdateMenuCheckmarks(); //Get value of the peak direction dialog box SetDirection( Sender->GetDirection() ); SetFromBase( Sender->GetFromBase() ); CheckBoundaries(); } else { if (InitCursors()!=wxID_OK) { get().clear(); return; } } //Number of channels to display (1 or 2 only!) if (get().size()>1) { //Select active channel to be displayed try { if (ChannelSelDlg()!=true) { get().clear(); throw std::runtime_error("Couldn't select channels"); } } catch (...) { throw; } } //Latency Cursor: OFF-Mode only if one channel is selected! if (!(get().size()>1) && GetLatencyStartMode()!=stf::manualMode && GetLatencyEndMode()!=stf::manualMode) { SetLatencyStartMode(stf::manualMode); SetLatencyEndMode(stf::manualMode); // UpdateMenuCheckmarks(); } // Make sure once again curChannel and curSection are not out of range: if (!(get().size()>1)) { if (cursec().size()==0) { throw e; } } else { if (cursec().size()==0 || secsec().size()==0) { throw e; } } PostInit(); } //Dialog box to display the specific settings of the current CFS file. int wxStfDoc::InitCursors() { //Get values from .Stimfit and ensure proper settings SetMeasCursor(wxGetApp().wxGetProfileInt(wxT("Settings"), wxT("MeasureCursor"), 1)); SetMeasRuler( wxGetApp().wxGetProfileInt(wxT("Settings"), wxT("ShowRuler"), 0) ); SetBaseBeg(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("BaseBegin"), 1)); SetBaseEnd(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("BaseEnd"), 20)); int ibase_method = wxGetApp().wxGetProfileInt(wxT("Settings"), wxT("BaselineMethod"),0); switch (ibase_method) { case 0: SetBaselineMethod(stfnum::mean_sd); break; case 1: SetBaselineMethod(stfnum::median_iqr); break; default: SetBaselineMethod(stfnum::mean_sd); } SetPeakBeg(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("PeakBegin"), (int)cursec().size()-100)); SetPeakEnd(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("PeakEnd"), (int)cursec().size()-50)); int iDirection = wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("Direction"),2); switch (iDirection) { case 0: SetDirection(stfnum::up); break; case 1: SetDirection(stfnum::down); break; case 2: SetDirection(stfnum::both); break; default: SetDirection(stfnum::undefined_direction); } SetFromBase( true ); // reset at every program start wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("FromBase"),1) ); SetPeakAtEnd( wxGetApp().wxGetProfileInt(wxT("Settings"), wxT("PeakAtEnd"), 0)); SetFitBeg(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("FitBegin"), 10)); SetFitEnd(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("FitEnd"), 100)); SetStartFitAtPeak( wxGetApp().wxGetProfileInt(wxT("Settings"), wxT("StartFitAtPeak"), 0)); SetLatencyWindowMode(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("LatencyWindowMode"),1)); SetLatencyBeg(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("LatencyStartCursor"), 0)); /*CSH*/ SetLatencyEnd(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("LatencyEndCursor"), 2)); /*CSH*/ SetLatencyStartMode( wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("LatencyStartMode"),0) ); SetLatencyEndMode( wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("LatencyEndMode"),0) ); // Set corresponding menu checkmarks: // UpdateMenuCheckmarks(); SetPM(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("PeakMean"),1)); SetRTFactor(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("RTFactor"),20)); wxString wxsSlope = wxGetApp().wxGetProfileString(wxT("Settings"),wxT("Slope"),wxT("20.0")); double fSlope = 0.0; wxsSlope.ToDouble(&fSlope); SetSlopeForThreshold( fSlope ); if (!(get().size()>1) && GetLatencyStartMode()!=stf::manualMode && GetLatencyEndMode()!=stf::manualMode) { wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("LatencyStartMode"),stf::manualMode); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("LatencyEndMode"),stf::manualMode); SetLatencyStartMode(stf::manualMode); SetLatencyEndMode(stf::manualMode); } #ifdef WITH_PSLOPE // read PSlope Beg mode from Stimfit registry int iPSlopeMode = wxGetApp().wxGetProfileInt( wxT("Settings"), wxT("PSlopeStartMode"), stf::psBeg_manualMode ); switch (iPSlopeMode) { case 0: SetPSlopeBegMode( stf::psBeg_manualMode ); break; case 1: SetPSlopeBegMode( stf::psBeg_footMode ); break; case 2: SetPSlopeBegMode( stf::psBeg_thrMode ); break; case 3: SetPSlopeBegMode( stf::psBeg_t50Mode ); break; default: SetPSlopeBegMode( stf::psBeg_undefined ); } // read PSlope End mode from Stimfit registry iPSlopeMode = wxGetApp().wxGetProfileInt( wxT("Settings"), wxT("PSlopeEndMode"), stf::psEnd_manualMode ); switch (iPSlopeMode) { case 0: SetPSlopeEndMode( stf::psEnd_manualMode ); break; case 1: SetPSlopeEndMode( stf::psEnd_t50Mode ); break; case 2: SetPSlopeEndMode( stf::psEnd_DeltaTMode ); break; case 3: SetPSlopeEndMode( stf::psEnd_peakMode ); break; default: SetPSlopeEndMode( stf::psEnd_undefined ); } #endif CheckBoundaries(); return wxID_OK; } //End SettingsDlg() void wxStfDoc::PostInit() { wxStfChildFrame *pFrame = (wxStfChildFrame*)GetDocumentWindow(); if ( pFrame == NULL ) { wxGetApp().ErrorMsg( wxT("Zero pointer in wxStfDoc::PostInit") ); return; } // Update some vector sizes sec_attr.resize(size()); for (std::size_t nchannel=0; nchannel < sec_attr.size(); ++nchannel) { sec_attr[nchannel].resize(at(nchannel).size()); } yzoom.resize(size()); try { pFrame->CreateMenuTraces(get().at(GetCurChIndex()).size()); if ( size() > 1 ) { wxArrayString channelNames; channelNames.Alloc( size() ); for (std::size_t n_c=0; n_c < size(); ++n_c) { wxString channelStream; channelStream << n_c << wxT(" (") << stf::std2wx( at(n_c).GetChannelName() ) << wxT(")"); channelNames.Add( channelStream ); } pFrame->CreateComboChannels( channelNames ); pFrame->SetChannels( GetCurChIndex(), GetSecChIndex() ); } } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal ) ); return; } if (GetSR()>1000) { wxString highSampling; highSampling << wxT("Sampling rate seems very high (") << GetSR() << wxT(" kHz).\n") << wxT("Divide by 1000?"); if (wxMessageDialog( GetDocumentWindow(), highSampling, wxT("Adjust sampling rate"), wxYES_NO ).ShowModal()==wxID_YES) { SetXScale(GetXScale()*1000.0); } } // Read results table settings from registry: SetViewCrosshair(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewCrosshair"),1)==1); SetViewBaseline(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewBaseline"),1)==1); SetViewBaseSD(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewBaseSD"),1)==1); SetViewThreshold(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewThreshold"),1)==1); SetViewPeakZero(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewPeakzero"),1)==1); SetViewPeakBase(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewPeakbase"),1)==1); SetViewPeakThreshold(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewPeakthreshold"),1)==1); SetViewRTLoHi(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewRTLoHi"),1)==1); SetViewInnerRiseTime(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewInnerRiseTime"),1)==1); SetViewOuterRiseTime(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewOuterRiseTime"),1)==1); SetViewT50(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewT50"),1)==1); SetViewRD(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewRD"),1)==1); SetViewSlopeRise(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewSloperise"),1)==1); SetViewSlopeDecay(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewSlopedecay"),1)==1); #ifdef WITH_PSLOPE //SetViewPSlope(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewPSlope"),1)==1); SetViewPSlope(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewPSlope"),1)==1); //SetPSlopeBegMode( wxGetApp().wxGetProfileInt( wxT("Settings"), wxT("PSlopeStartMode"), 1)==1); #endif SetViewLatency(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewLatency"),1)==1); SetViewCursors(wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewCursors"),1)==1); // refresh the view once we are through: initialized=true; pFrame->SetCurTrace(0); UpdateSelectedButton(); wxGetApp().OnPeakcalcexecMsg(); wxStfParentFrame* parentFrame = wxGetApp().GetMainFrame(); if (parentFrame) { parentFrame->SetFocus(); } wxStfView* pView=(wxStfView*)GetFirstView(); if (pView != NULL) { wxStfGraph* pGraph = pView->GetGraph(); if (pGraph != NULL) { pGraph->Refresh(); pGraph->Enable(); // Set the focus: pGraph->SetFocus(); } } } //Dialog box to select channel to be displayed bool wxStfDoc::ChannelSelDlg() { // Set default channels: if ( size() < 2 ) { return false; } // SetCurChIndex(); done in Recording constructor // SetSecCh( 1 ); return true; } //End ChannelSelDlg() void wxStfDoc::CheckBoundaries() { //Security check base if (GetBaseBeg() > GetBaseEnd()) { std::size_t aux=GetBaseBeg(); SetBaseBeg((int)GetBaseEnd()); SetBaseEnd((int)aux); wxGetApp().ErrorMsg(wxT("Base cursors are reversed,\nthey will be exchanged")); } //Security check peak if (GetPeakBeg() > GetPeakEnd()) { std::size_t aux=GetPeakBeg(); SetPeakBeg((int)GetPeakEnd()); SetPeakEnd((int)aux); wxGetApp().ErrorMsg(wxT("Peak cursors are reversed,\nthey will be exchanged")); } //Security check decay if (GetFitBeg() > GetFitEnd()) { std::size_t aux=GetFitBeg(); SetFitBeg((int)GetFitEnd()); SetFitEnd((int)aux); wxGetApp().ErrorMsg(wxT("Decay cursors are reversed,\nthey will be exchanged")); } if (GetPM() > (int)cursec().size()) { SetPM((int)cursec().size()-1); } if (GetPM() == 0) { SetPM(1); } } bool wxStfDoc::OnNewDocument() { // correct caption: wxString title(GetTitle()); wxStfChildFrame* wnd=(wxStfChildFrame*)GetDocumentWindow(); wnd->SetLabel(title); // call base class member: return true; // return wxDocument::OnNewDocument(); } void wxStfDoc::Fileinfo(wxCommandEvent& WXUNUSED(event)) { //Create CFileOpenDlg object 'dlg' std::ostringstream oss1, oss2; oss1 << "Number of Channels: " << static_cast(get().size()); oss2 << "Number of Sweeps: " << static_cast(get()[GetCurChIndex()].size()); char buf[128]; struct tm t = GetDateTime(); snprintf(buf, 128, "Date:\t%04i-%02i-%02i\nTime:\t%02i:%02i:%02i\n", t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); std::string general = buf + oss1.str() + "\n" + oss2.str() + "\n" + "Comment:\n" + GetComment(); wxStfFileInfoDlg dlg( GetDocumentWindow(), general, GetFileDescription(), GetGlobalSectionDescription() ); dlg.ShowModal(); } bool wxStfDoc::OnCloseDocument() { if (!get().empty()) { WriteToReg(); } // Remove file menu from file menu list: #ifndef __WXGTK__ wxGetApp().GetDocManager()->GetFileHistory()->RemoveMenu( doc_file_menu ); #endif // Tell the App: wxGetApp().CleanupDocument(this); return wxDocument::OnCloseDocument(); //Note that the base class version will delete all the document's data } bool wxStfDoc::SaveAs() { // Override file save dialog to display only writeable // file types wxString filters; filters += wxT("hdf5 file (*.h5)|*.h5|"); filters += wxT("CED filing system (*.dat;*.cfs)|*.dat;*.cfs|"); filters += wxT("Axon text file (*.atf)|*.atf|"); filters += wxT("Igor binary wave (*.ibw)|*.ibw|"); filters += wxT("Mantis TDMS file (*.tdms)|*.tdms|"); filters += wxT("Text file series (*.txt)|*.txt|"); #if defined(WITH_BIOSIG) filters += wxT("GDF file (*.gdf)|*.gdf"); #endif wxFileDialog SelectFileDialog( GetDocumentWindow(), wxT("Save file"), wxT(""), wxT(""), filters, wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxFD_PREVIEW ); if(SelectFileDialog.ShowModal()==wxID_OK) { wxString filename = SelectFileDialog.GetPath(); Recording writeRec(ReorderChannels()); if (writeRec.size() == 0) return false; try { stf::wxProgressInfo progDlg("Reading file", "Opening file", 100); stfio::filetype type; switch (SelectFileDialog.GetFilterIndex()) { case 0: type=stfio::hdf5; break; case 1: type=stfio::cfs; break; case 2: type=stfio::atf; break; case 3: type=stfio::igor; break; case 4: type=stfio::tdms; break; case 5: type=stfio::ascii; break; #if defined(WITH_BIOSIG) default: type=stfio::biosig; #else default: type=stfio::hdf5; #endif } return stfio::exportFile(stf::wx2std(filename), type, writeRec, progDlg); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(stf::std2wx(e.what())); return false; } } else { return false; } } Recording wxStfDoc::ReorderChannels() { // Re-order channels? std::vector< wxString > channelNames(size()); wxs_it it = channelNames.begin(); for (c_ch_it cit = get().begin(); cit != get().end() && it != channelNames.end(); cit++) { *it = stf::std2wx( cit->GetChannelName() ); it++; } std::vector channelOrder(size()); if (size()>1) { wxStfOrderChannelsDlg orderDlg(GetDocumentWindow(),channelNames); if (orderDlg.ShowModal() != wxID_OK) { return Recording(0); } channelOrder=orderDlg.GetChannelOrder(); } else { int n_c = 0; for (int_it it = channelOrder.begin(); it != channelOrder.end(); it++) { *it = n_c++; } } Recording writeRec(size()); writeRec.CopyAttributes(*this); std::size_t n_c = 0; for (c_int_it cit2 = channelOrder.begin(); cit2 != channelOrder.end(); cit2++) { writeRec.InsertChannel(get()[*cit2],n_c); // correct units: writeRec[n_c++].SetYUnits( at(*cit2).GetYUnits() ); } return writeRec; } bool wxStfDoc::DoSaveDocument(const wxString& filename) { Recording writeRec(ReorderChannels()); if (writeRec.size() == 0) return false; try { stf::wxProgressInfo progDlg("Reading file", "Opening file", 100); if (stfio::exportFile(stf::wx2std(filename), stfio::hdf5, writeRec, progDlg)) return true; else return false; } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(stf::std2wx(e.what())); return false; } } void wxStfDoc::WriteToReg() { //Write file length wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("FirstPoint"), 1); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("LastPoint"), (int)cursec().size()-1); //Write cursors if (!outOfRange(GetBaseBeg())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("BaseBegin"), (int)GetBaseBeg()); if (!outOfRange(GetBaseEnd())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("BaseEnd"), (int)GetBaseEnd()); if (!outOfRange(GetPeakBeg())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("PeakBegin"), (int)GetPeakBeg()); if (!outOfRange(GetPeakEnd())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("PeakEnd"), (int)GetPeakEnd()); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("PeakMean"),(int)GetPM()); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("RTFactor"),(int)GetRTFactor()); wxString wxsSlope; wxsSlope << GetSlopeForThreshold(); wxGetApp().wxWriteProfileString(wxT("Settings"),wxT("Slope"),wxsSlope); //if (wxGetApp().GetCursorsDialog() != NULL) { // wxGetApp().wxWriteProfileInt( // wxT("Settings"),wxT("StartFitAtPeak"),(int)wxGetApp().GetCursorsDialog()->GetStartFitAtPeak() // ); //} if (!outOfRange(GetFitBeg())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("FitBegin"), (int)GetFitBeg()); if (!outOfRange(GetFitEnd())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("FitEnd"), (int)GetFitEnd()); wxGetApp().wxWriteProfileInt( wxT("Settings"),wxT("StartFitAtPeak"),(int)GetStartFitAtPeak() ); if (!outOfRange((size_t)GetLatencyBeg())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("LatencyStartCursor"), (int)GetLatencyBeg()); if (!outOfRange((size_t)GetLatencyEnd())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("LatencyEndCursor"), (int)GetLatencyEnd()); #ifdef WITH_PSLOPE if (!outOfRange((size_t)GetPSlopeBeg())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("PSlopeStartCursor"), GetPSlopeBeg() ); if (!outOfRange((size_t)GetPSlopeEnd())) wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("PSlopeEndCursor"), GetPSlopeEnd() ); wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("PSlopeStartMode"), (int)GetPSlopeBegMode()); wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("PSlopeEndMode"), (int)GetPSlopeEndMode()); wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("DeltaT"), GetDeltaT() ); #endif // Write Zoom wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("Zoom.xZoom"), (int)GetXZoom().xZoom*100000); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("Zoom.yZoom"), GetYZoom(GetCurChIndex()).yZoom*100000); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("Zoom.startPosX"), (int)GetXZoom().startPosX); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("Zoom.startPosY"), GetYZoom(GetCurChIndex()).startPosY); if ((get().size()>1)) { wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("Zoom.yZoom2"), (int)GetYZoom(GetSecChIndex()).yZoom*100000); wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("Zoom.startPosY2"), GetYZoom(GetSecChIndex()).startPosY); } } bool wxStfDoc::SetSection(std::size_t section){ // Check range: if (!(get().size()>1)) { if (section>=get()[GetCurChIndex()].size()) { wxGetApp().ErrorMsg(wxT("subscript out of range\nwhile calling CStimfitDoc::SetSection()")); return false; } if (get()[GetCurChIndex()][section].size()==0) { wxGetApp().ErrorMsg(wxT("Section is empty")); return false; } } else { if (section>=get()[GetCurChIndex()].size() || section>=get()[GetSecChIndex()].size()) { wxGetApp().ErrorMsg(wxT("subscript out of range\nwhile calling CStimfitDoc::SetSection()")); return false; } if (get()[GetCurChIndex()][section].size()==0 || get()[GetSecChIndex()][section].size()==0) { wxGetApp().ErrorMsg(wxT("Section is empty")); return false; } } CheckBoundaries(); SetCurSecIndex(section); UpdateSelectedButton(); return true; } void wxStfDoc::OnSwapChannels(wxCommandEvent& WXUNUSED(event)) { if ( size() > 1) { // Update combo boxes: wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); if ( pFrame == NULL ) { wxGetApp().ErrorMsg( wxT("Frame is zero in wxStfDoc::SwapChannels")); return; } pFrame->SetChannels( GetSecChIndex(), GetCurChIndex() ); pFrame->UpdateChannels(); } } void wxStfDoc::ToggleSelect() { // get current selection status of this trace: bool selected = false; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end() && !selected; ++cit) { if (*cit == GetCurSecIndex()) { selected = true; } } if (selected) { Remove(); } else { Select(); } } void wxStfDoc::Select() { if (GetSelectedSections().size() == get()[GetCurChIndex()].size()) { wxGetApp().ErrorMsg(wxT("No more traces can be selected\nAll traces are selected")); return; } //control whether trace has already been selected: bool already=false; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end() && !already; ++cit) { if (*cit == GetCurSecIndex()) { already = true; } } //add trace number to selected numbers, print number of selected traces if (!already) { SelectTrace(GetCurSecIndex(), baseBeg, baseEnd); //String output in the trace navigator wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->SetSelected(GetSelectedSections().size()); } else { wxGetApp().ErrorMsg(wxT("Trace is already selected")); return; } Focus(); } void wxStfDoc::Remove() { if (UnselectTrace(GetCurSecIndex())) { //Message update in the trace navigator wxStfChildFrame* pFrame = (wxStfChildFrame*)GetDocumentWindow(); if (pFrame) pFrame->SetSelected(GetSelectedSections().size()); } else { wxGetApp().ErrorMsg(wxT("Trace is not selected")); } Focus(); } void wxStfDoc::ConcatenateMultiChannel(wxCommandEvent &WXUNUSED(event)) { if (GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("Select sweeps first")); return; } stf::wxProgressInfo progDlg("Concatenating sections", "Starting...", 100); try { Recording Concatenated = stfio::concatenate(*this, GetSelectedSections(), progDlg); wxGetApp().NewChild(Concatenated,this,wxString(GetTitle()+wxT(", concatenated"))); } catch (const std::runtime_error& e) { wxGetApp().ErrorMsg(wxT("Error concatenating sections:\n") + stf::std2wx(e.what())); } } void wxStfDoc::CreateAverage( bool calcSD, bool align //align to steepest rise of other channel? ) { if(GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("Select traces first")); return; } wxBusyCursor wc; //array indicating how many indices to shift when aligning, //has to be filled with zeros: std::vector shift(GetSelectedSections().size(),0); int shift_size = 0; /* Aligned average */ //find alignment points in the reference (==second) channel: if (align) { // check that we have more than one channel wxStfAlignDlg AlignDlg(GetDocumentWindow(), size()>1); if (AlignDlg.ShowModal() != wxID_OK) return; //store current section and channel index: std::size_t section_old=GetCurSecIndex(); std::size_t channel_old=GetCurChIndex(); //initialize the lowest and the highest index: std::size_t min_index=0; try { if (AlignDlg.UseReference()) min_index=get()[GetSecChIndex()].at(GetSelectedSections().at(0)).size()-1; else min_index=get()[GetCurChIndex()].at(GetSelectedSections().at(0)).size()-1; } catch (const std::out_of_range& e) { wxString msg(wxT("Error while aligning\nIt is safer to re-start the program\n")); msg+=wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(msg); return; } // swap channels temporarily: // if (AlignDlg.UseReference()) // SetCurChIndex(GetSecChIndex()); std::size_t max_index=0; int_it it = shift.begin(); //loop through all selected sections: for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end() && it != shift.end(); cit++) { //Set the selected section as the current section temporarily: SetSection(*cit); if (peakAtEnd) { SetPeakEnd((int)get()[GetSecChIndex()][*cit].size()-1); } // Calculate all variables for the current settings // APMaxSlopeT will be calculated for the second (==reference) // channel, so channels may not be changed! try { Measure(); } catch (const std::out_of_range& e) { Average.resize(0); SetSection(section_old); SetCurChIndex(channel_old); wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return; } std::size_t alignIndex; //check whether the current index is a max or a min, //and if so, store it: switch (AlignDlg.AlignRise()) { case 0: // align to peak time if (AlignDlg.UseReference()) alignIndex = lround(GetAPMaxT()); else alignIndex = lround(GetMaxT()); break; case 1: // align to steepest slope time if (AlignDlg.UseReference()) alignIndex = lround(GetAPMaxRiseT()); else alignIndex = lround(GetMaxRiseT()); break; case 2: // align to half amplitude time if (AlignDlg.UseReference()) alignIndex = lround(GetAPT50LeftReal()); else alignIndex = lround(GetT50LeftReal()); break; case 3: // align to onset if (AlignDlg.UseReference()) alignIndex = lround(GetAPT0Real()); else alignIndex = lround(GetT0Real()); break; default: wxGetApp().ExceptMsg(wxT("Invalid alignment method")); return; } *it = alignIndex; if (alignIndex > max_index) { max_index=alignIndex; } if (alignIndex < min_index) { min_index=alignIndex; } it++; } //now that max and min indices are known, calculate the number of //points that need to be shifted: for (int_it it = shift.begin(); it != shift.end(); it++) { (*it) -= (int)min_index; } //restore section and channel settings: SetSection(section_old); SetCurChIndex(channel_old); shift_size = (max_index-min_index); } //number of points in average: size_t average_size = cursec().size(); for (c_st_it sit = GetSelectedSections().begin(); sit != GetSelectedSections().end(); sit++) { if (curch().get()[*sit].size() < average_size) { average_size = curch().get()[*sit].size(); } } average_size -= shift_size; //initialize temporary sections and channels: Average.resize(size()); std::size_t n_c = 0; for (c_ch_it cit = get().begin(); cit != get().end(); cit++) { Section TempSection(average_size), TempSig(average_size); try { MakeAverage(TempSection, TempSig, n_c, GetSelectedSections(), calcSD, shift); } catch (const std::out_of_range& e) { Average.resize(0); wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return; } TempSection.SetXScale(get()[n_c][0].GetXScale()); // set xscale for channel n_c and the only section TempSection.SetSectionDescription(stf::wx2std(GetTitle()) +std::string(", average")); Channel TempChannel(TempSection); TempChannel.SetChannelName(cit->GetChannelName()); try { Average.InsertChannel(TempChannel,n_c); } catch (const std::out_of_range& e) { Average.resize(0); wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return; } n_c++; } Average.CopyAttributes(*this); wxString title; title << GetFilename() << wxT(", average of ") << (int)GetSelectedSections().size() << wxT(" traces"); wxGetApp().NewChild(Average,this,title); } //End of CreateAverage(.,.,.) void wxStfDoc::FitDecay(wxCommandEvent& WXUNUSED(event)) { int fselect=-2; wxStfFitSelDlg FitSelDialog(GetDocumentWindow(), this); if (FitSelDialog.ShowModal() != wxID_OK) return; wxBeginBusyCursor(); fselect=FitSelDialog.GetFSelect(); if (outOfRange(GetFitBeg()) || outOfRange(GetFitEnd())) { wxGetApp().ErrorMsg(wxT("Subscript out of range in wxStfDoc::FitDecay()")); return; } //number of parameters to be fitted: std::size_t n_params=0; //number of points: std::size_t n_points = GetFitEnd()-GetFitBeg(); if (n_points<=1) { wxGetApp().ErrorMsg(wxT("Check fit limits")); return; } std::string fitInfo; try { n_params=(int)wxGetApp().GetFuncLib().at(fselect).pInfo.size(); } catch (const std::out_of_range& e) { wxString msg(wxT("Could not retrieve function from library:\n")); msg+=wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(msg); return; } Vector_double params ( FitSelDialog.GetInitP() ); int warning = 0; try { std::size_t fitSize = GetFitEnd() - GetFitBeg(); Vector_double x( fitSize ); //fill array: std::copy(&cursec()[GetFitBeg()], &cursec()[GetFitBeg()+fitSize], &x[0]); if (params.size() != n_params) { throw std::runtime_error("Wrong size of params in wxStfDoc::lmFit()"); } double chisqr = stfnum::lmFit( x, GetXScale(), wxGetApp().GetFuncLib()[fselect], FitSelDialog.GetOpts(), FitSelDialog.UseScaling(), params, fitInfo, warning ); SetIsFitted( GetCurChIndex(), GetCurSecIndex(), params, wxGetApp().GetFuncLibPtr(fselect), chisqr, GetFitBeg(), GetFitEnd() ); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg( wxString(e.what(), wxConvLocal) ); return; } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg( wxString(e.what(), wxConvLocal) ); return; } // Refresh the graph to show the fit before // the dialog pops up: wxStfView* pView=(wxStfView*)GetFirstView(); if (pView!=NULL && pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); wxStfFitInfoDlg InfoDialog(GetDocumentWindow(), stf::std2wx(fitInfo)); wxEndBusyCursor(); InfoDialog.ShowModal(); wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); wxString label; label << wxT("Fit, Section #") << (int)GetCurSecIndex()+1; try { pFrame->ShowTable(sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).bestFit, label); } catch (std::out_of_range const& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } void wxStfDoc::LFit(wxCommandEvent& WXUNUSED(event)) { wxBusyCursor wc; if (outOfRange(GetFitBeg()) || outOfRange(GetFitEnd())) { wxGetApp().ErrorMsg(wxT("Subscript out of range in wxStfDoc::FitDecay()")); return; } //number of parameters to be fitted: std::size_t n_params=0; //number of points: std::size_t n_points=GetFitEnd()-GetFitBeg(); if (n_points<=1) { wxGetApp().ErrorMsg(wxT("Check fit limits")); return; } std::string fitInfo; n_params=2; Vector_double params( n_params ); //fill array: Vector_double x(n_points); std::copy(&cursec()[GetFitBeg()], &cursec()[GetFitBeg()+n_points], &x[0]); Vector_double t(x.size()); for (std::size_t n_t=0;n_tGetGraph()!=NULL) pView->GetGraph()->Refresh(); std::ostringstream fitInfoStr; fitInfoStr << wxT("slope = ") << params[0] << wxT("\n1/slope = ") << 1.0/params[0] << wxT("\ny-intercept = ") << params[1]; fitInfo += fitInfoStr.str(); wxStfFitInfoDlg InfoDialog(GetDocumentWindow(), stf::std2wx(fitInfo)); InfoDialog.ShowModal(); wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); wxString label; label << wxT("Fit, Section #") << (int)GetCurSecIndex(); try { pFrame->ShowTable(sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).bestFit, label); } catch (std::out_of_range const& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } void wxStfDoc::LnTransform(wxCommandEvent& WXUNUSED(event)) { Channel TempChannel(GetSelectedSections().size(), get()[GetCurChIndex()][GetSelectedSections()[0]].size()); std::size_t n = 0; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end(); cit++) { Section TempSection(size()); std::transform(get()[GetCurChIndex()][*cit].get().begin(), get()[GetCurChIndex()][*cit].get().end(), TempSection.get_w().begin(), #if defined(_WINDOWS) && !defined(__MINGW32__) std::logl); #else (double(*)(double))log); #endif TempSection.SetXScale(get()[GetCurChIndex()][*cit].GetXScale()); TempSection.SetSectionDescription( get()[GetCurChIndex()][*cit].GetSectionDescription()+ ", transformed (ln)"); try { TempChannel.InsertSection(TempSection,n); } catch (std::out_of_range const& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } n++; } if (TempChannel.size()>0) { Recording Transformed(TempChannel); Transformed.CopyAttributes(*this); wxString title(GetTitle()); title+=wxT(", transformed (ln)"); wxGetApp().NewChild(Transformed,this,title); } } void wxStfDoc::Viewtable(wxCommandEvent& WXUNUSED(event)) { wxBusyCursor wc; try { wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->ShowTable( CurAsTable(), stf::std2wx( cursec().GetSectionDescription() ) ); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return; } } void wxStfDoc::Multiply(wxCommandEvent& WXUNUSED(event)) { if (GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("Select traces first")); return; } //insert standard values: std::vector labels(1); Vector_double defaults(labels.size()); labels[0]="Multiply with:";defaults[0]=1; stf::UserInput init(labels,defaults,"Set factor"); wxStfUsrDlg MultDialog(GetDocumentWindow(),init); if (MultDialog.ShowModal()!=wxID_OK) return; Vector_double input(MultDialog.readInput()); if (input.size()!=1) return; double factor=input[0]; try { Recording Multiplied = stfio::multiply(*this, GetSelectedSections(), GetCurChIndex(), factor); wxGetApp().NewChild(Multiplied, this, wxString(GetTitle()+wxT(", multiplied"))); } catch (const std::exception& e) { wxGetApp().ErrorMsg(wxT("Error during multiplication:\n") + stf::std2wx(e.what())); } } bool wxStfDoc::SubtractBase( ) { if (GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("Select traces first")); return false; } Channel TempChannel(GetSelectedSections().size(), get()[GetCurChIndex()][GetSelectedSections()[0]].size()); std::size_t n = 0; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end(); cit++) { Section TempSection(stfio::vec_scal_minus(get()[GetCurChIndex()][*cit].get(), GetSelectBase()[n])); TempSection.SetXScale(get()[GetCurChIndex()][*cit].GetXScale()); TempSection.SetSectionDescription( get()[GetCurChIndex()][*cit].GetSectionDescription()+ ", baseline subtracted"); try { TempChannel.InsertSection(TempSection,n); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return false; } n++; } if (TempChannel.size()>0) { Recording SubBase(TempChannel); SubBase.CopyAttributes(*this); wxString title(GetTitle()); title+=wxT(", baseline subtracted"); wxGetApp().NewChild(SubBase,this,title); } else { wxGetApp().ErrorMsg( wxT("Channel is empty.") ); return false; } return true; } void wxStfDoc::OnAnalysisBatch(wxCommandEvent &WXUNUSED(event)) { // event.Skip(); if (GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("No selected traces")); return; } std::size_t section_old=GetCurSecIndex(); // wxStfBatchDlg SaveYtDialog(GetDocumentWindow()); if (SaveYtDialog.ShowModal()!=wxID_OK) return; std::vector colTitles; //Write the header of the SaveYt file in a string if (SaveYtDialog.PrintBase()) { colTitles.push_back("Base"); } if (SaveYtDialog.PrintBaseSD()) { colTitles.push_back("Base SD"); } if (SaveYtDialog.PrintThreshold()) { colTitles.push_back("Slope threshold"); } if (SaveYtDialog.PrintSlopeThresholdTime()) { colTitles.push_back("Slope threshold time"); } if (SaveYtDialog.PrintPeakZero()) { colTitles.push_back("Peak (from 0)"); } if (SaveYtDialog.PrintPeakBase()) { colTitles.push_back("Peak (from baseline)"); } if (SaveYtDialog.PrintPeakThreshold()) { colTitles.push_back("Peak (from threshold)"); } if (SaveYtDialog.PrintPeakTime()) { colTitles.push_back("Peak time"); } if (SaveYtDialog.PrintRTLoHi()) { colTitles.push_back("RT Lo-Hi%"); } if (SaveYtDialog.PrintInnerRTLoHi()) { colTitles.push_back("inner Rise Time Lo-Hi%"); } if (SaveYtDialog.PrintOuterRTLoHi()) { colTitles.push_back("Outer Rise Time Lo-Hi%"); } if (SaveYtDialog.PrintT50()) { colTitles.push_back("duration Amp/2"); } if (SaveYtDialog.PrintT50SE()) { colTitles.push_back("start Amp/2"); colTitles.push_back("end Amp/2"); } if (SaveYtDialog.PrintSlopes()) { colTitles.push_back("Max. slope rise"); colTitles.push_back("Max. slope decay"); } if (SaveYtDialog.PrintSlopeTimes()) { colTitles.push_back("Time of max. rise"); colTitles.push_back("Time of max. decay"); } if (SaveYtDialog.PrintLatencies()) { colTitles.push_back("Latency"); } int fselect=-2; std::size_t n_params=0; wxStfFitSelDlg FitSelDialog(GetDocumentWindow(), this); if (SaveYtDialog.PrintFitResults()) { while (fselect<0) { FitSelDialog.SetNoInput(true); if (FitSelDialog.ShowModal()!=wxID_OK) { SetSection(section_old); return; } fselect=FitSelDialog.GetFSelect(); } try { n_params=(int)wxGetApp().GetFuncLib().at(fselect).pInfo.size(); } catch (const std::out_of_range& e) { wxString msg(wxT("Error while retrieving function from library:\n")); msg += stf::std2wx(e.what()); wxGetApp().ExceptMsg(msg); SetSection(section_old); return; } for (std::size_t n_pf=0;n_pf(1, thrS.str()), Vector_double (1,0.0), "Set threshold"); wxStfUsrDlg myDlg( GetDocumentWindow(), Input ); if (myDlg.ShowModal()!=wxID_OK) { return; } threshold=myDlg.readInput()[0]; } wxProgressDialog progDlg( wxT("Batch analysis in progress"), wxT("Starting batch analysis"), 100, GetDocumentWindow(), wxPD_SMOOTH | wxPD_AUTO_HIDE | wxPD_APP_MODAL ); stfnum::Table table(GetSelectedSections().size(),colTitles.size()); for (std::size_t nCol=0;nColGetStartFitAtPeak()) if ( startFitAtPeak ) SetFitBeg(GetMaxT()); Vector_double params; int fitWarning = 0; if (SaveYtDialog.PrintFitResults()) { try { n_params=(int)wxGetApp().GetFuncLib().at(fselect).pInfo.size(); } catch (const std::out_of_range& e) { wxString msg(wxT("Could not retrieve function from library:\n")); msg+=wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(msg); return; } // in this case, initialize parameters from init function, // not from user input: Vector_double x(GetFitEnd()-GetFitBeg()); //fill array: std::copy(&cursec()[GetFitBeg()], &cursec()[GetFitEnd()], &x[0]); params.resize(n_params); wxGetApp().GetFuncLib().at(fselect).init( x, GetBase(), GetPeak(), GetRTLoHi(), GetHalfDuration(), GetXScale(), params ); std::string fitInfo; try { double chisqr = stfnum::lmFit( x, GetXScale(), wxGetApp().GetFuncLib()[fselect], FitSelDialog.GetOpts(), FitSelDialog.UseScaling(), params, fitInfo, fitWarning ); SetIsFitted( GetCurChIndex(), GetCurSecIndex(), params, wxGetApp().GetFuncLibPtr(fselect), chisqr, GetFitBeg(), GetFitEnd() ); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); SetSection(section_old); return; } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); SetSection(section_old); return; } catch (const std::exception& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); SetSection(section_old); return; } } // count number of threshold crossings if needed: std::size_t n_crossings=0; if (SaveYtDialog.PrintThr()) { n_crossings= stfnum::peakIndices( cursec().get(), threshold, 0 ).size(); } std::size_t nCol=0; //Write the variables of the current channel in a string try { table.SetRowLabel(n_s, cursec().GetSectionDescription()); if (SaveYtDialog.PrintBase()) table.at(n_s,nCol++)=GetBase(); if (SaveYtDialog.PrintBaseSD()) table.at(n_s,nCol++)=GetBaseSD(); if (SaveYtDialog.PrintThreshold()) table.at(n_s,nCol++)=GetThreshold(); if (SaveYtDialog.PrintSlopeThresholdTime()) table.at(n_s,nCol++)=GetThrT()*GetXScale(); if (SaveYtDialog.PrintPeakZero()) table.at(n_s,nCol++)=GetPeak(); if (SaveYtDialog.PrintPeakBase()) table.at(n_s,nCol++)=GetPeak()-GetBase(); if (SaveYtDialog.PrintPeakThreshold()) table.at(n_s,nCol++)=GetPeak()-GetThreshold(); if (SaveYtDialog.PrintPeakTime()) table.at(n_s,nCol++)=GetPeakTime()*GetXScale(); if (SaveYtDialog.PrintRTLoHi()) table.at(n_s,nCol++)=GetRTLoHi(); if (SaveYtDialog.PrintInnerRTLoHi()) table.at(n_s,nCol++)=GetInnerRiseTime(); if (SaveYtDialog.PrintOuterRTLoHi()) table.at(n_s,nCol++)=GetOuterRiseTime(); if (SaveYtDialog.PrintT50()) table.at(n_s,nCol++)=GetHalfDuration(); if (SaveYtDialog.PrintT50SE()) { table.at(n_s,nCol++)=GetT50LeftReal()*GetXScale(); table.at(n_s,nCol++)=GetT50RightReal()*GetXScale(); } if (SaveYtDialog.PrintSlopes()) { table.at(n_s,nCol++)=GetMaxRise(); table.at(n_s,nCol++)=GetMaxDecay(); } if (SaveYtDialog.PrintSlopeTimes()) { table.at(n_s,nCol++)=GetMaxRiseT()*GetXScale(); table.at(n_s,nCol++)=GetMaxDecayT()*GetXScale(); } if (SaveYtDialog.PrintLatencies()) { table.at(n_s,nCol++)=GetLatency()*GetXScale(); } if (SaveYtDialog.PrintFitResults()) { for (std::size_t n_pf=0;n_pfShowTable(table,wxT("Batch analysis results")); } void wxStfDoc::OnAnalysisIntegrate(wxCommandEvent &WXUNUSED(event)) { double integral_s = 0.0, integral_t = 0.0; const std::string units = at(GetCurChIndex()).GetYUnits() + " * " + GetXUnits(); try { integral_s = stfnum::integrate_simpson(cursec().get(),GetFitBeg(),GetFitEnd(),GetXScale()); integral_t = stfnum::integrate_trapezium(cursec().get(),GetFitBeg(),GetFitEnd(),GetXScale()); } catch (const std::exception& e) { wxGetApp().ErrorMsg(wxString( e.what(), wxConvLocal )); return; } stfnum::Table integralTable(6,1); try { integralTable.SetRowLabel(0, "Trapezium (linear)"); integralTable.SetRowLabel(1, "Integral (from 0)"); integralTable.SetRowLabel(2, "Integral (from base)"); integralTable.SetRowLabel(3, "Simpson (quadratic)"); integralTable.SetRowLabel(4, "Integral (from 0)"); integralTable.SetRowLabel(5, "Integral (from base)"); //integralTable.SetColLabel(0, "Results"); integralTable.SetColLabel(0, units); integralTable.SetEmpty(0,0); integralTable.at(1,0) = integral_t; integralTable.at(2,0) = integral_t - (GetFitEnd()-GetFitBeg())*GetXScale()*GetBase(); integralTable.SetEmpty(3,0); integralTable.at(4,0) = integral_s; integralTable.at(5,0) = integral_s - (GetFitEnd()-GetFitBeg())*GetXScale()*GetBase(); } catch (const std::out_of_range& e) { wxGetApp().ErrorMsg(wxString( e.what(), wxConvLocal )); return; } wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->ShowTable(integralTable,wxT("Integral")); try { Vector_double quad_p = stfnum::quad(cursec().get(), GetFitBeg(), GetFitEnd()); SetIsIntegrated(GetCurChIndex(), GetCurSecIndex(), true,GetFitBeg(),GetFitEnd(), quad_p); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } void wxStfDoc::OnAnalysisDifferentiate(wxCommandEvent &WXUNUSED(event)) { if (GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("Select traces first")); return; } Channel TempChannel(GetSelectedSections().size(), get()[GetCurChIndex()][GetSelectedSections()[0]].size()); std::size_t n = 0; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end(); cit++) { Section TempSection( stfnum::diff( get()[GetCurChIndex()][*cit].get(), GetXScale() ) ); TempSection.SetXScale(get()[GetCurChIndex()][*cit].GetXScale()); TempSection.SetSectionDescription( get()[GetCurChIndex()][*cit].GetSectionDescription()+ ", differentiated"); try { TempChannel.InsertSection(TempSection,n); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } n++; } if (TempChannel.size()>0) { Recording Diff(TempChannel); Diff.CopyAttributes(*this); Diff[0].SetYUnits(at(GetCurChIndex()).GetYUnits()+" / ms"); wxString title(GetTitle()); title+=wxT(", differentiated"); wxGetApp().NewChild(Diff,this,title); } } bool wxStfDoc::OnNewfromselectedThis( ) { if (GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("Select traces first")); return false; } Channel TempChannel(GetSelectedSections().size(), get()[GetCurChIndex()][GetSelectedSections()[0]].size()); std::size_t n = 0; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end(); cit++) { // Multiply the valarray in Data: Section TempSection(get()[GetCurChIndex()][*cit].get()); TempSection.SetXScale(get()[GetCurChIndex()][*cit].GetXScale()); TempSection.SetSectionDescription( get()[GetCurChIndex()][*cit].GetSectionDescription()+ ", new from selected"); try { TempChannel.InsertSection(TempSection,n); } catch (std::out_of_range const& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return false; } n++; } if (TempChannel.size()>0) { Recording Selected(TempChannel); Selected.CopyAttributes(*this); Selected[0].SetYUnits( at(GetCurChIndex()).GetYUnits() ); Selected[0].SetChannelName( at(GetCurChIndex()).GetChannelName() ); wxString title(GetTitle()); title+=wxT(", new from selected"); wxGetApp().NewChild(Selected,this,title); } else { wxGetApp().ErrorMsg( wxT("Channel is empty.") ); return false; } return true; } void wxStfDoc::Selectsome(wxCommandEvent &WXUNUSED(event)) { if (GetSelectedSections().size()>0) { wxGetApp().ErrorMsg(wxT("Unselect all")); return; } //insert standard values: std::vector labels(2); Vector_double defaults(labels.size()); labels[0]="Select every x-th trace:";defaults[0]=1; labels[1]="Starting with the y-th:";defaults[1]=1; stf::UserInput init(labels,defaults,"Select every n-th (1-based)"); wxStfUsrDlg EveryDialog(GetDocumentWindow(),init); if (EveryDialog.ShowModal()!=wxID_OK) return; Vector_double input(EveryDialog.readInput()); if (input.size()!=2) return; int everynth=(int)input[0]; int everystart=(int)input[1]; //div_t n_selected=div((int)get()[GetCurChIndex()].size(),everynth); for (int n=0; n*everynth+everystart-1 < (int)get()[GetCurChIndex()].size(); ++n) { try { SelectTrace(n*everynth+everystart-1, baseBeg, baseEnd); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg( wxString::FromAscii(e.what()) ); } } wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->SetSelected(GetSelectedSections().size()); Focus(); } void wxStfDoc::SelectTracesOfType(wxCommandEvent &WXUNUSED(event)) { // TODO: dialog should display possible selections //insert standard values: std::vector labels(1); Vector_double defaults(labels.size()); labels[0]="Select Trace of Type";defaults[0]=1; stf::UserInput init(labels,defaults,"Select trace of type"); wxStfUsrDlg EveryDialog(GetDocumentWindow(),init); if (EveryDialog.ShowModal()!=wxID_OK) return; Vector_double input(EveryDialog.readInput()); if (input.size()!=1) return; int selTyp=(int)input[0]; for (size_t n=0; n < get()[GetCurChIndex()].size(); ++n) { if (GetSectionType(n)==selTyp) SelectTrace(n, baseBeg, baseEnd); } wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->SetSelected(GetSelectedSections().size()); Focus(); } void wxStfDoc::UnselectTracesOfType(wxCommandEvent &WXUNUSED(event)) { // TODO: dialog should display possible selections //insert standard values: std::vector labels(1); Vector_double defaults(labels.size()); labels[0]="Unselect Traces of Type";defaults[0]=1; stf::UserInput init(labels,defaults,"Unselect trace of type"); wxStfUsrDlg EveryDialog(GetDocumentWindow(),init); if (EveryDialog.ShowModal()!=wxID_OK) return; Vector_double input(EveryDialog.readInput()); if (input.size()!=1) return; int selTyp=(int)input[0]; for (int n=0; n < (int)get()[GetCurChIndex()].size(); ++n) { if (GetSectionType(n)==selTyp) UnselectTrace(n); } wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->SetSelected(GetSelectedSections().size()); Focus(); } void wxStfDoc::Unselectsome(wxCommandEvent &WXUNUSED(event)) { if (GetSelectedSections().size() < get()[GetCurChIndex()].size()) { wxGetApp().ErrorMsg(wxT("Select all traces first")); return; } //insert standard values: std::vector labels(2); Vector_double defaults(labels.size()); labels[0]="Unselect every x-th trace:";defaults[0]=1; labels[1]="Starting with the y-th:";defaults[1]=1; stf::UserInput init(labels,defaults,"Unselect every n-th (1-based)"); wxStfUsrDlg EveryDialog(GetDocumentWindow(),init); if (EveryDialog.ShowModal()!=wxID_OK) return; Vector_double input(EveryDialog.readInput()); if (input.size()!=2) return; int everynth=(int)input[0]; int everystart=(int)input[1]; //div_t n_unselected=div((int)get()[GetCurChIndex()].size(),everynth); for (int n=0; n*everynth+everystart-1 < (int)get()[GetCurChIndex()].size(); ++n) { UnselectTrace(n*everynth+everystart-1); } wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->SetSelected(GetSelectedSections().size()); Focus(); } void wxStfDoc::Selectall(wxCommandEvent& event) { //Make sure all traces are unselected prior to selecting them all: if ( !GetSelectedSections().empty() ) Deleteselected(event); for (int n_s=0; n_s<(int)get()[GetCurChIndex()].size(); ++n_s) { SelectTrace(n_s, baseBeg, baseEnd); } wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); pFrame->SetSelected(GetSelectedSections().size()); Focus(); } void wxStfDoc::Deleteselected(wxCommandEvent &WXUNUSED(event)) { wxStfChildFrame* pFrame=(wxStfChildFrame*)GetDocumentWindow(); if( !GetSelectedSections().empty() ) { GetSelectedSectionsW().clear(); GetSelectBaseW().clear(); //Update selected traces string in the trace navigator pFrame->SetSelected(GetSelectedSections().size()); } else { wxGetApp().ErrorMsg(wxT("No selected trace to remove")); return; } // refresh the view once we are through: if (pFrame->ShowSelected()) { wxStfView* pView=(wxStfView*)GetFirstView(); if (pView!=NULL && pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } Focus(); } void wxStfDoc::Focus() { UpdateSelectedButton(); // refresh the view once we are through: wxStfView* pView=(wxStfView*)GetFirstView(); if (pView != NULL && pView->GetGraph() != NULL) { pView->GetGraph()->Enable(); pView->GetGraph()->SetFocus(); } } void wxStfDoc::UpdateSelectedButton() { // control whether trace has been selected: bool selected=false; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end() && !selected; ++cit) { if (*cit == GetCurSecIndex()) { selected = true; } } // Set status of selection button: wxStfParentFrame* parentFrame = wxGetApp().GetMainFrame(); if (parentFrame) { parentFrame->SetSelectedButton( selected ); } } void wxStfDoc::Filter(wxCommandEvent& WXUNUSED(event)) { #ifndef TEST_MINIMAL if (GetSelectedSections().empty()) { wxGetApp().ErrorMsg(wxT("No traces selected")); return; } //--For details on the Fast Fourier Transform see NR in C++, chapters 12 and 13 std::vector windowLabels(2); Vector_double windowDefaults(windowLabels.size()); windowLabels[0]="From point #:";windowDefaults[0]=0; windowLabels[1]="To point #:";windowDefaults[1]=(int)cursec().size()-1; stf::UserInput initWindow(windowLabels,windowDefaults,"Filter window"); wxStfUsrDlg FilterWindowDialog(GetDocumentWindow(),initWindow); if (FilterWindowDialog.ShowModal()!=wxID_OK) return; Vector_double windowInput(FilterWindowDialog.readInput()); if (windowInput.size()!=2) return; int llf=(int)windowInput[0]; int ulf=(int)windowInput[1]; wxStfFilterSelDlg FilterSelectDialog(GetDocumentWindow()); if (FilterSelectDialog.ShowModal()!=wxID_OK) return; int fselect=FilterSelectDialog.GetFilterSelect(); int size=0; bool inverse=true; switch (fselect) { case 1: size=3; break; case 2: case 3: size=1; break; } wxStfGaussianDlg FftDialog(GetDocumentWindow()); Vector_double a(size); switch (fselect) { case 1: if (FftDialog.ShowModal()!=wxID_OK) return; a[0]=(int)(FftDialog.Amp()*100000.0)/100000.0; /*amplitude from 0 to 1*/ a[1]=(int)(FftDialog.Center()*100000.0)/100000.0; /*center in kHz*/ a[2]=(int)(FftDialog.Width()*100000.0)/100000.0; /*width in kHz*/ break; case 2: case 3: { //insert standard values: std::vector labels(1); Vector_double defaults(labels.size()); labels[0]="Cutoff frequency (kHz):"; defaults[0]=10; stf::UserInput init(labels,defaults,"Set frequency"); wxStfUsrDlg FilterHighLowDialog(GetDocumentWindow(),init); if (FilterHighLowDialog.ShowModal()!=wxID_OK) return; Vector_double input(FilterHighLowDialog.readInput()); if (input.size()!=1) return; a[0]=(int)(input[0]*100000.0)/100000.0; /*midpoint of sigmoid curve in kHz*/ break; } } wxBusyCursor wc; //--I. Defining the parameters of the filter function /*sampling interval in ms*/ Channel TempChannel(GetSelectedSections().size(), get()[GetCurChIndex()][GetSelectedSections()[0]].size()); std::size_t n = 0; for (c_st_it cit = GetSelectedSections().begin(); cit != GetSelectedSections().end(); cit++) { try { switch (fselect) { case 3: { Section FftTemp(stfnum::filter(get()[GetCurChIndex()][*cit].get(), llf,ulf,a,(int)GetSR(),stfnum::fgaussColqu,false)); FftTemp.SetXScale(get()[GetCurChIndex()][*cit].GetXScale()); FftTemp.SetSectionDescription( get()[GetCurChIndex()][*cit].GetSectionDescription()+ ", filtered"); TempChannel.InsertSection(FftTemp, n); break; } case 2: { Section FftTemp(stfnum::filter(get()[GetCurChIndex()][*cit].get(), llf,ulf,a,(int)GetSR(),stfnum::fbessel4,false)); FftTemp.SetXScale(get()[GetCurChIndex()][*cit].GetXScale()); FftTemp.SetSectionDescription( get()[GetCurChIndex()][*cit].GetSectionDescription()+ ", filtered" ); TempChannel.InsertSection(FftTemp, n); break; } case 1: { Section FftTemp(stfnum::filter(get()[GetCurChIndex()][*cit].get(), llf,ulf,a,(int)GetSR(),stfnum::fgauss,inverse)); FftTemp.SetXScale(get()[GetCurChIndex()][*cit].GetXScale()); FftTemp.SetSectionDescription( get()[GetCurChIndex()][*cit].GetSectionDescription()+ std::string(", filtered") ); TempChannel.InsertSection(FftTemp, n); break; } } } catch (const std::exception& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } n++; } if (TempChannel.size()>0) { Recording Fft(TempChannel); Fft.CopyAttributes(*this); wxGetApp().NewChild(Fft, this,GetTitle()+wxT(", filtered")); } #endif } void wxStfDoc::P_over_N(wxCommandEvent& WXUNUSED(event)){ //insert standard values: std::vector labels(1); Vector_double defaults(labels.size()); labels[0]="N = (mind polarity!)";defaults[0]=-4; stf::UserInput init(labels,defaults,"P over N"); wxStfUsrDlg PonDialog(GetDocumentWindow(),init); if (PonDialog.ShowModal()!=wxID_OK) return; Vector_double input(PonDialog.readInput()); if (input.size()!=1) return; int PoN=(int)fabs(input[0]); int ponDirection=input[0]<0? -1:1; int new_sections=(int)get()[GetCurChIndex()].size()/(PoN+1); if (new_sections<1) { wxGetApp().ErrorMsg(wxT("Not enough traces for P/n correction")); return; } //File dialog box wxBusyCursor wc; Channel TempChannel(new_sections); //read and PoN for (int n_section=0; n_section < new_sections; n_section++) { //Section loop Section TempSection(get()[GetCurChIndex()][n_section].size()); TempSection.SetXScale(get()[GetCurChIndex()][n_section].GetXScale()); for (int n_point=0; n_point < (int)get()[GetCurChIndex()][n_section].size(); n_point++) TempSection[n_point]=0.0; //Addition of the PoN-values: for (int n_PoN=1; n_PoN < PoN+1; n_PoN++) for (int n_point=0; n_point < (int)get()[GetCurChIndex()][n_section].size(); n_point++) TempSection[n_point] += get()[GetCurChIndex()][n_PoN+(n_section*(PoN+1))][n_point]; //Subtraction from the original values: for (int n_point=0; n_point < (int)get()[GetCurChIndex()][n_section].size(); n_point++) TempSection[n_point] = get()[GetCurChIndex()][n_section*(PoN+1)][n_point]- TempSection[n_point]*ponDirection; std::ostringstream povernLabel; povernLabel << GetTitle() << ", #" << n_section << ", P over N"; TempSection.SetSectionDescription(povernLabel.str()); try { TempChannel.InsertSection(TempSection,n_section); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } if (TempChannel.size()>0) { Recording DataPoN(TempChannel); DataPoN.CopyAttributes(*this); wxGetApp().NewChild(DataPoN,this,GetTitle()+wxT(", p over n subtracted")); } } void wxStfDoc::Plotextraction(stf::extraction_mode mode) { std::vector sectionList(wxGetApp().GetSectionsWithFits()); if (sectionList.empty()) { wxGetApp().ErrorMsg( wxT("You have to create a template first\nby fitting a function to an event") ); return; } wxStfEventDlg MiniDialog(GetDocumentWindow(), sectionList, false); if (MiniDialog.ShowModal()!=wxID_OK) { return; } int nTemplate=MiniDialog.GetTemplate(); try { Vector_double templateWave( sectionList.at(nTemplate).sec_attr.storeFitEnd - sectionList.at(nTemplate).sec_attr.storeFitBeg); for ( std::size_t n_p=0; n_p < templateWave.size(); n_p++ ) { templateWave[n_p] = sectionList.at(nTemplate).sec_attr.fitFunc->func( n_p*GetXScale(), sectionList.at(nTemplate).sec_attr.bestFitP); } wxBusyCursor wc; #undef min #undef max // subtract offset and normalize: double fmax = *std::max_element(templateWave.begin(), templateWave.end()); double fmin = *std::min_element(templateWave.begin(), templateWave.end()); templateWave = stfio::vec_scal_minus(templateWave, fmax); double minim=fabs(fmin); templateWave = stfio::vec_scal_div(templateWave, minim); std::string section_description, window_title; Section TempSection(cursec().get().size()); switch (mode) { case stf::criterion: { stf::wxProgressInfo progDlg("Computing detection criterion...", "Computing detection criterion...", 100); TempSection = Section(stfnum::detectionCriterion( cursec().get(), templateWave, progDlg)); section_description = "Detection criterion of "; window_title = ", detection criterion"; break; } case stf::correlation: { stf::wxProgressInfo progDlg("Computing linear correlation...", "Computing linear correlation...", 100); TempSection = Section(stfnum::linCorr(cursec().get(), templateWave, progDlg)); section_description = "Template correlation of "; window_title = ", linear correlation"; break; } case stf::deconvolution: std::string usrInStr[2] = {"Lowpass (kHz)", "Highpass (kHz)"}; double usrInDbl[2] = {0.5, 0.0001}; stf::UserInput Input( std::vector(usrInStr, usrInStr+2), Vector_double (usrInDbl, usrInDbl+2), "Filter settings" ); wxStfUsrDlg myDlg( GetDocumentWindow(), Input ); if (myDlg.ShowModal()!=wxID_OK) return; Vector_double filter = myDlg.readInput(); stf::wxProgressInfo progDlg("Computing deconvolution...", "Starting deconvolution...", 100); TempSection = Section(stfnum::deconvolve(cursec().get(), templateWave, (int)GetSR(), filter[1], filter[0], progDlg)); section_description = "Template deconvolution from "; window_title = ", deconvolution"; break; } if (TempSection.size()==0) return; TempSection.SetXScale(cursec().GetXScale()); TempSection.SetSectionDescription(section_description + cursec().GetSectionDescription()); Channel TempChannel(TempSection); Recording detCrit(TempChannel); detCrit.CopyAttributes(*this); wxGetApp().NewChild(detCrit, this, GetTitle() + stf::std2wx(window_title)); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } catch (const std::exception& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } void wxStfDoc::Plotcriterion(wxCommandEvent& WXUNUSED(event)) { Plotextraction(stf::criterion); } void wxStfDoc::Plotcorrelation(wxCommandEvent& WXUNUSED(event)) { Plotextraction(stf::correlation); } void wxStfDoc::Plotdeconvolution(wxCommandEvent& WXUNUSED(event)) { Plotextraction(stf::deconvolution); } void wxStfDoc::MarkEvents(wxCommandEvent& WXUNUSED(event)) { std::vector sectionList(wxGetApp().GetSectionsWithFits()); if (sectionList.empty()) { wxGetApp().ErrorMsg( wxT( "You have to create a template first\nby fitting a function to an event" ) ); return; } wxStfEventDlg MiniDialog( GetDocumentWindow(), sectionList, true ); if ( MiniDialog.ShowModal()!=wxID_OK ) { return; } int nTemplate=MiniDialog.GetTemplate(); try { Vector_double templateWave( sectionList.at(nTemplate).sec_attr.storeFitEnd - sectionList.at(nTemplate).sec_attr.storeFitBeg); for ( std::size_t n_p=0; n_p < templateWave.size(); n_p++ ) { templateWave[n_p] = sectionList.at(nTemplate).sec_attr.fitFunc->func( n_p*GetXScale(), sectionList.at(nTemplate).sec_attr.bestFitP); } wxBusyCursor wc; #undef min #undef max // subtract offset and normalize: double fmax = *std::max_element(templateWave.begin(), templateWave.end()); double fmin = *std::min_element(templateWave.begin(), templateWave.end()); templateWave = stfio::vec_scal_minus(templateWave, fmax); double minim=fabs(fmin); templateWave = stfio::vec_scal_div(templateWave, minim); Vector_double detect( cursec().get().size() - templateWave.size() ); switch (MiniDialog.GetMode()) { case stf::criterion: { stf::wxProgressInfo progDlg("Computing detection criterion...", "Computing detection criterion...", 100); detect=stfnum::detectionCriterion(cursec().get(), templateWave, progDlg); break; } case stf::correlation: { stf::wxProgressInfo progDlg("Computing linear correlation...", "Computing linear correlation...", 100); detect=stfnum::linCorr(cursec().get(), templateWave, progDlg); break; } case stf::deconvolution: std::string usrInStr[2] = {"Lowpass (kHz)", "Highpass (kHz)"}; double usrInDbl[2] = {0.5, 0.0001}; stf::UserInput Input( std::vector(usrInStr, usrInStr+2), Vector_double (usrInDbl, usrInDbl+2), "Filter settings" ); wxStfUsrDlg myDlg( GetDocumentWindow(), Input ); if (myDlg.ShowModal()!=wxID_OK) return; Vector_double filter = myDlg.readInput(); stf::wxProgressInfo progDlg("Computing deconvolution...", "Starting deconvolution...", 100); detect=stfnum::deconvolve(cursec().get(), templateWave, (int)GetSR(), filter[1], filter[0], progDlg); break; } if (detect.empty()) { wxGetApp().ErrorMsg(wxT("Error: Detection criterion is empty.")); return; } std::vector startIndices( stfnum::peakIndices( detect, MiniDialog.GetThreshold(), MiniDialog.GetMinDistance() ) ); if (startIndices.empty()) { wxGetApp().ErrorMsg( wxT( "No events were found. Try to lower the threshold." ) ); return; } // erase old events: ClearEvents(GetCurChIndex(), GetCurSecIndex()); wxStfView* pView = (wxStfView*)GetFirstView(); wxStfGraph* pGraph = pView->GetGraph(); for (c_int_it cit = startIndices.begin(); cit != startIndices.end(); ++cit ) { sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.push_back( stf::Event( *cit, 0, templateWave.size(), new wxCheckBox( pGraph, -1, wxEmptyString) ) ); // Find peak in this event: double baselineMean=0; for ( int n_mean = *cit-baseline; n_mean < *cit; ++n_mean ) { if (n_mean < 0) { baselineMean += cursec().at(0); } else { baselineMean += cursec().at(n_mean); } } baselineMean /= baseline; double peakIndex=0; size_t eventl = templateWave.size(); if (*cit + eventl >= cursec().get().size()) { eventl = cursec().get().size()-1- (*cit); } stfnum::peak( cursec().get(), baselineMean, *cit, *cit + eventl, 1, stfnum::both, peakIndex ); if (peakIndex != peakIndex || peakIndex < 0 || peakIndex >= cursec().get().size()) { throw std::runtime_error("Error during peak detection (result is NAN)\n"); } // set peak index of this event: sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.back().SetEventPeakIndex((int)peakIndex); } if (pGraph != NULL) { pGraph->Refresh(); } } catch (std::out_of_range const& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal )); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal )); } catch (const std::exception& e) { wxGetApp().ExceptMsg( wxString( e.what(), wxConvLocal )); } } void wxStfDoc::Extract( wxCommandEvent& WXUNUSED(event) ) { try { stfnum::Table events(GetCurrentSectionAttributes().eventList.size(), 2); events.SetColLabel(0, "Time of event onset"); events.SetColLabel(1, "Inter-event interval"); // using the peak indices (these are the locations of the beginning of an optimal // template matching), new sections are created: // count non-discarded events: std::size_t n_real = 0; for (c_event_it cit = GetCurrentSectionAttributes().eventList.begin(); cit != GetCurrentSectionAttributes().eventList.end(); ++cit) { n_real += (int)(!cit->GetDiscard()); } Channel TempChannel2(n_real); std::vector peakIndices(n_real); n_real = 0; c_event_it lastEventIt = GetCurrentSectionAttributes().eventList.begin(); for (c_event_it it = GetCurrentSectionAttributes().eventList.begin(); it != GetCurrentSectionAttributes().eventList.end(); ++it) { if (!it->GetDiscard()) { wxString miniName; miniName << wxT( "Event #" ) << (int)n_real+1; events.SetRowLabel(n_real, stf::wx2std(miniName)); events.at(n_real,0) = (double)it->GetEventStartIndex() / GetSR(); events.at(n_real,1)= ((double)(it->GetEventStartIndex() - lastEventIt->GetEventStartIndex())) / GetSR(); // add some baseline at the beginning and end: std::size_t eventSize = it->GetEventSize() + 2*baseline; Section TempSection2( eventSize ); for ( std::size_t n_new = 0; n_new < eventSize; ++n_new ) { // make sure index is not out of range: int index = it->GetEventStartIndex() + n_new - baseline; if (index < 0) index = 0; if (index >= (int)cursec().size()) index = cursec().size()-1; TempSection2[n_new] = cursec()[index]; } std::ostringstream eventDesc; eventDesc << "Extracted event #" << (int)n_real; TempSection2.SetSectionDescription(eventDesc.str()); TempSection2.SetXScale(get()[GetCurChIndex()][GetCurSecIndex()].GetXScale()); TempChannel2.InsertSection( TempSection2, n_real ); n_real++; lastEventIt = it; } } if (TempChannel2.size()>0) { Recording Minis( TempChannel2 ); Minis.CopyAttributes( *this ); wxStfDoc* pDoc=wxGetApp().NewChild( Minis, this, GetTitle()+wxT(", extracted events") ); if (pDoc != NULL) { wxStfChildFrame* pChild=(wxStfChildFrame*)pDoc->GetDocumentWindow(); if (pChild!=NULL) { pChild->ShowTable(events,wxT("Extracted events")); } } } } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } catch (const std::exception& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } void wxStfDoc::InteractiveEraseEvents( wxCommandEvent& WXUNUSED(event) ) { if (wxMessageDialog( GetDocumentWindow(), wxT("Do you really want to erase all events?"), wxT("Erase all events"), wxYES_NO ).ShowModal()==wxID_YES) { try { ClearEvents(GetCurChIndex(), GetCurSecIndex()); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } } void wxStfDoc::AddEvent( wxCommandEvent& WXUNUSED(event) ) { try { // retrieve the position where to add the event: wxStfView* pView = (wxStfView*)GetFirstView(); wxStfGraph* pGraph = pView->GetGraph(); int newStartPos = pGraph->get_eventPos(); stf::Event newEvent(newStartPos, 0, GetCurrentSectionAttributes().eventList.at(0).GetEventSize(), new wxCheckBox(pGraph, -1, wxEmptyString)); // Find peak in this event: double baselineMean=0; for ( int n_mean = newStartPos - baseline; n_mean < newStartPos; ++n_mean ) { if (n_mean < 0) { baselineMean += cursec().at(0); } else { baselineMean += cursec().at(n_mean); } } baselineMean /= baseline; double peakIndex=0; stfnum::peak( cursec().get(), baselineMean, newStartPos, newStartPos + GetCurrentSectionAttributes().eventList.at(0).GetEventSize(), 1, stfnum::both, peakIndex ); // set peak index of last event: newEvent.SetEventPeakIndex( (int)peakIndex ); // find the position in the current event list where the new // event should be inserted: bool found = false; for (event_it it = sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.begin(); it != sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.end(); ++it) { if ( (int)(it->GetEventStartIndex()) > newStartPos ) { // insert new event before this event, then break: sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.insert( it, newEvent ); found = true; break; } } // if we are at the end of the list, append the event: if (!found) sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.push_back( newEvent ); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } catch (const std::exception& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } void wxStfDoc::Threshold(wxCommandEvent& WXUNUSED(event)) { // get threshold from user input: Vector_double threshold(0); std::ostringstream thrS; thrS << "Threshold (" << at(GetCurChIndex()).GetYUnits() << ")"; stf::UserInput Input( std::vector(1, thrS.str()), Vector_double (1,0.0), "Set threshold" ); wxStfUsrDlg myDlg( GetDocumentWindow(), Input ); if (myDlg.ShowModal()!=wxID_OK) { return; } threshold=myDlg.readInput(); std::vector startIndices( stfnum::peakIndices( cursec().get(), threshold[0], 0 ) ); if (startIndices.empty()) { wxGetApp().ErrorMsg( wxT("Couldn't find any events;\ntry again with lower threshold") ); } // clear table from previous detection wxStfView* pView=(wxStfView*)GetFirstView(); wxStfGraph* pGraph = pView->GetGraph(); sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.clear(); for (c_int_it cit = startIndices.begin(); cit != startIndices.end(); ++cit) { sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()).eventList.push_back( stf::Event(*cit, 0, baseline, new wxCheckBox(pGraph, -1, wxEmptyString))); } // show results in a table: stfnum::Table events(GetCurrentSectionAttributes().eventList.size(),2); events.SetColLabel( 0, "Time of event peak"); events.SetColLabel( 1, "Inter-event interval"); std::size_t n_event = 0; c_event_it lastEventCit = GetCurrentSectionAttributes().eventList.begin(); for (c_event_it cit2 = GetCurrentSectionAttributes().eventList.begin(); cit2 != GetCurrentSectionAttributes().eventList.end(); ++cit2) { wxString eventName; eventName << wxT("Event #") << (int)n_event+1; events.SetRowLabel(n_event, stf::wx2std(eventName)); events.at(n_event,0)= (double)cit2->GetEventStartIndex() / GetSR(); events.at(n_event,1)= ((double)(cit2->GetEventStartIndex() - lastEventCit->GetEventStartIndex()) ) / GetSR(); n_event++; lastEventCit = cit2; } wxStfChildFrame* pChild=(wxStfChildFrame*)GetDocumentWindow(); if (pChild!=NULL) { pChild->ShowTable(events,wxT("Extracted events")); } } //Function calculates the peak and respective measures: base, Lo/Hi rise time //half duration, ratio of rise/slope and maximum slope void wxStfDoc::Measure( ) { double var=0.0; if (cursec().get().size() == 0) return; try { cursec().at(0); } catch (const std::out_of_range&) { return; } long windowLength = 1; /* windowLength (defined in samples) determines the size of the window for computing slopes. if the window length larger than 1 is used, a kind of smoothing and low pass filtering is applied. If slope estimates from data with different sampling rates should be compared, the window should be choosen in such a way that the length in milliseconds is approximately the same. This reduces some variability, the slope estimates are more robust and comparible. Set window length to 0.05 ms, with a minimum of 1 sample. In this way, all data sampled with 20 kHz or lower, will use a 1 sample window, data with a larger sampling rate use a window of 0.05 ms for computing the slope. */ windowLength = lround(0.05 * GetSR()); // use window length of about 0.05 ms. if (windowLength < 1) windowLength = 1; // use a minimum window length of 1 sample //Begin peak and base calculation //------------------------------- try { base=stfnum::base(baselineMethod,var,cursec().get(),baseBeg,baseEnd); baseSD=sqrt(var); peak=stfnum::peak(cursec().get(),base, peakBeg,peakEnd,pM,direction,maxT); } catch (const std::out_of_range& e) { base=0.0; baseSD=0.0; peak=0.0; throw e; } try { threshold = stfnum::threshold( cursec().get(), peakBeg, peakEnd, slopeForThreshold/GetSR(), thrT, windowLength ); } catch (const std::out_of_range& e) { threshold = 0; throw e; } //Begin Lo to Hi% Rise Time calculation //------------------------------------- // 2009-06-05: reference is either from baseline or from threshold double reference = base; if (!fromBase && thrT >= 0) { reference = threshold; } double ampl=peak-reference; tLoReal=0.0; double factor= RTFactor*0.01; /* normalized value */ InnerLoRT=NAN; InnerHiRT=NAN; OuterLoRT=NAN; OuterHiRT=NAN; try { // 2008-04-27: changed limits to start from the beginning of the trace // 2013-06-16: changed to accept different rise-time proportions rtLoHi=stfnum::risetime2(cursec().get(),reference,ampl, (double)0/*(double)baseEnd*/, maxT, factor/*0.2*/, InnerLoRT, InnerHiRT, OuterLoRT, OuterHiRT); InnerLoRT/=GetSR(); InnerHiRT/=GetSR(); OuterLoRT/=GetSR(); OuterHiRT/=GetSR(); } catch (const std::out_of_range& e) { throw e; } try { // 2008-04-27: changed limits to start from the beginning of the trace // 2013-06-16: changed to accept different rise-time proportions rtLoHi=stfnum::risetime(cursec().get(),reference,ampl, (double)0/*(double)baseEnd*/, maxT, factor/*0.2*/, tLoIndex, tHiIndex, tLoReal); } catch (const std::out_of_range& e) { rtLoHi=0.0; throw e; } tHiReal=tLoReal+rtLoHi; rtLoHi/=GetSR(); //Begin Half Duration calculation //------------------------------- //t50LeftReal=0.0; // 2008-04-27: changed limits to start from the beginning of the trace // and to stop at the end of the trace halfDuration = stfnum::t_half(cursec().get(), reference, ampl, (double)0 /*(double)baseBeg*/, (double)cursec().size()-1 /*(double)peakEnd*/,maxT, t50LeftIndex, t50RightIndex, t50LeftReal); t50RightReal=t50LeftReal+halfDuration; halfDuration/=GetSR(); t50Y=0.5*ampl + reference; //Calculate the beginning of the event by linear extrapolation: if (latencyEndMode==stf::footMode) { t0Real=tLoReal-(tHiReal-tLoReal)/3.0; // using 20-80% rise time (f/(1-2f) = 0.2/(1-0.4) = 1/3.0) } else { t0Real=t50LeftReal; } //Begin Ratio of slopes rise/decay calculation //-------------------------------------------- double left_rise = peakBeg; maxRise=stfnum::maxRise(cursec().get(),left_rise,maxT,maxRiseT,maxRiseY,windowLength); double t_half_3=t50RightIndex+2.0*(t50RightIndex-t50LeftIndex); double right_decay=peakEnd<=t_half_3 ? peakEnd : t_half_3+1; maxDecay=stfnum::maxDecay(cursec().get(),maxT,right_decay,maxDecayT,maxDecayY,windowLength); //Slope ratio if (maxDecay !=0) slopeRatio=maxRise/maxDecay; else slopeRatio=0.0; maxRise *= GetSR(); maxDecay *= GetSR(); if (size()>1) { //Calculate the absolute peak of the (AP) Ch2 inbetween the peak boundaries //A direction dependent evaluation of the peak as in Ch1 does NOT exist!! // endResting is set to 100 points arbitrarily in the pascal version // (see measlib.pas) assuming that the resting potential is stable // during the first 100 sampling points. // const int endResting=100; const int searchRange=100; double APBase=0.0, APVar=0.0; try { // in 2012-11-02: use baseline cursors and not arbitrarily 100 points //APBase=stfnum::base(APVar,secsec().get(),0,endResting); APBase=stfnum::base(baselineMethod,APVar,secsec().get(), baseBeg, baseEnd ); // use baseline cursors //APPeak=stfnum::peak(secsec().get(),APBase,peakBeg,peakEnd,pM,stfnum::up,APMaxT); APPeak=stfnum::peak( secsec().get(),APBase ,peakBeg ,peakEnd ,pM,direction ,APMaxT ); } catch (const std::out_of_range& e) { APBase=0.0; APPeak=0.0; throw e; } //------------------------------- //Maximal slope in the rise before the peak //---------------------------- APMaxRiseT=0.0; APMaxRiseY=0.0; double left_APRise = peakBeg; //if (GetLatencyWindowMode() == stf::defaultMode ) { left_APRise= APMaxT-searchRange>2.0 ? APMaxT-searchRange : 2.0; try { stfnum::maxRise(secsec().get(),left_APRise,APMaxT,APMaxRiseT,APMaxRiseY,windowLength); } catch (const std::out_of_range&) { APMaxRiseT=0.0; APMaxRiseY=0.0; left_APRise = peakBeg; } //End determination of the region of maximal slope in the second channel //---------------------------- //------------------------------- //Half-maximal amplitude //---------------------------- //APt50LeftReal=0.0; //std::size_t APt50LeftIndex,APt50RightIndex; stfnum::t_half(secsec().get(), APBase, APPeak-APBase, left_APRise, (double)secsec().get().size(), APMaxT, APt50LeftIndex, APt50RightIndex, APt50LeftReal); //End determination of the region of maximal slope in the second channel //---------------------------- // Get onset in 2nd channel APrtLoHi=stfnum::risetime(secsec().get(), APBase, APPeak-APBase, (double)0, APMaxT, 0.2, APtLoIndex, APtHiIndex, APtLoReal); APtHiReal = APtLoReal + APrtLoHi; APt0Real = APtLoReal-(APtHiReal-APtLoReal)/3.0; // using 20-80% rise time (f/(1-2f) = 0.2/(1-0.4) = 1/3.0) } // get and set start of latency measurement: double latStart=0.0; switch (latencyStartMode) { // Interestingly, latencyCursor is an int in pascal, although // the maxTs aren't. That's why there are double type casts // here. case stf::peakMode: //Latency cursor is set to the peak latStart=APMaxT; break; case stf::riseMode: latStart=APMaxRiseT; break; case stf::halfMode: latStart=APt50LeftReal; break; case stf::manualMode: default: latStart=GetLatencyBeg(); break; } SetLatencyBeg(latStart); APt0Real = tLoReal-(tHiReal-tLoReal)/3.0; // using 20-80% rise time (f/(1-2f) = 0.2/(1-0.4) = 1/3.0) // get and set end of latency measurement: double latEnd=0.0; switch (latencyEndMode) { // Interestingly, latencyCursor is an int in pascal, although // the maxTs aren't. That's why there are double type casts // here. case stf::footMode: latEnd=tLoReal-(tHiReal-tLoReal)/3.0; // using 20-80% rise time (f/(1-2f) = 0.2/(1-0.4) = 1/3.0) break; case stf::riseMode: latEnd=maxRiseT; break; case stf::halfMode: latEnd=t50LeftReal; break; case stf::peakMode: latEnd=maxT; break; case stf::manualMode: default: latEnd=GetLatencyEnd(); break; } SetLatencyEnd(latEnd); SetLatency(GetLatencyEnd()-GetLatencyBeg()); #ifdef WITH_PSLOPE //------------------------------------- // Begin PSlope calculation (PSP Slope) //------------------------------------- // int PSlopeBegVal; switch (pslopeBegMode) { case stf::psBeg_footMode: // Left PSlope to commencement PSlopeBegVal = (int)(tLoReal-(tHiReal-tLoReal)/3.0); break; case stf::psBeg_thrMode: // Left PSlope to threshold PSlopeBegVal = (int)thrT; break; case stf::psBeg_t50Mode: // Left PSlope to the t50 PSlopeBegVal = (int)t50LeftReal; break; case stf::psBeg_manualMode: // Left PSlope cursor manual default: PSlopeBegVal = PSlopeBeg; } SetPSlopeBeg(PSlopeBegVal); int PSlopeEndVal; switch (pslopeEndMode) { case stf::psEnd_t50Mode: // Right PSlope to t50rigth PSlopeEndVal = (int)t50LeftReal; break; case stf::psEnd_peakMode: // Right PSlope to peak PSlopeEndVal = (int)maxT; break; case stf::psEnd_DeltaTMode: // Right PSlope to DeltaT time from first peak PSlopeEndVal = (int)(PSlopeBeg + DeltaT); break; case stf::psEnd_manualMode: default: PSlopeEndVal = PSlopeEnd; } SetPSlopeEnd(PSlopeEndVal); try { PSlope = (stfnum::pslope(cursec().get(), PSlopeBeg, PSlopeEnd))*GetSR(); } catch (const std::out_of_range& e) { PSlope = 0.0; throw e; } //----------------------------------- // End PSlope calculation (PSP Slope) //----------------------------------- #endif // WITH_PSLOPE //-------------------------- } //End of Measure(,,,,,) void wxStfDoc::CopyCursors(const wxStfDoc& c_Recording) { measCursor=c_Recording.measCursor; correctRangeR(measCursor); baseBeg=c_Recording.baseBeg; correctRangeR(baseBeg); baseEnd=c_Recording.baseEnd; correctRangeR(baseEnd); peakBeg=c_Recording.peakBeg; correctRangeR(peakBeg); peakEnd=c_Recording.peakEnd; correctRangeR(peakEnd); fitBeg=c_Recording.fitBeg; correctRangeR(fitBeg); fitEnd=c_Recording.fitEnd; correctRangeR(fitEnd); #ifdef WITH_PSLOPE PSlopeBeg = c_Recording.PSlopeBeg; // PSlope left cursor correctRangeR(PSlopeBeg); PSlopeEnd = c_Recording.PSlopeEnd; // PSlope right cursor correctRangeR(PSlopeEnd); DeltaT=c_Recording.DeltaT; //distance (number of points) from first cursor #endif pM=c_Recording.pM; //peakMean, number of points used for averaging } void wxStfDoc::SetLatencyStartMode(int value) { switch (value) { case 1: latencyStartMode=stf::peakMode; break; case 2: latencyStartMode=stf::riseMode; break; case 3: latencyStartMode=stf::halfMode; break; case 4: latencyStartMode=stf::footMode; break; case 0: default: latencyStartMode=stf::manualMode; } } void wxStfDoc::SetLatencyEndMode(int value) { switch (value) { case 1: latencyEndMode=stf::peakMode; break; case 2: latencyEndMode=stf::riseMode; break; case 3: latencyEndMode=stf::halfMode; break; case 4: latencyEndMode=stf::footMode; break; case 0: default: latencyEndMode=stf::manualMode; } } void wxStfDoc::SetLatencyWindowMode(int value) { if ( value == 1 ) { latencyWindowMode = stf::windowMode; } else { latencyWindowMode = stf::defaultMode; } } void wxStfDoc::correctRangeR(int& value) { if (value<0) { value=0; return; } if (value>=(int)cursec().size()) { value=(int)cursec().size()-1; return; } } void wxStfDoc::correctRangeR(std::size_t& value) { if (value>=cursec().size()) { value=cursec().size()-1; return; } } void wxStfDoc::SetMeasCursor(int value) { correctRangeR(value); measCursor=value; } double wxStfDoc::GetMeasValue() { if (measCursor>=curch().size()) { correctRangeR(measCursor); } return cursec().at(measCursor); } void wxStfDoc::SetBaseBeg(int value) { correctRangeR(value); baseBeg=value; } void wxStfDoc::SetBaseEnd(int value) { correctRangeR(value); baseEnd=value; } void wxStfDoc::SetPeakBeg(int value) { correctRangeR(value); peakBeg=value; } void wxStfDoc::SetPeakEnd(int value) { correctRangeR(value); peakEnd=value; } void wxStfDoc::SetFitBeg(int value) { correctRangeR(value); fitBeg=value; } void wxStfDoc::SetFitEnd(int value) { correctRangeR(value); fitEnd=value; } void wxStfDoc::SetLatencyBeg(double value) { if (value<0.0) { value=0.0; } if (value>=(double)cursec().size()) { value=cursec().size()-1.0; } latencyStartCursor=value; } void wxStfDoc::SetLatencyEnd(double value) { if (value<0.0) { value=0.0; } if (value>=(double)cursec().size()) { value=cursec().size()-1.0; } latencyEndCursor=value; } void wxStfDoc::SetRTFactor(int value) { if (value < 0){ value = 5; } else if (value > 50) { value = 45; } RTFactor = value; } #ifdef WITH_PSLOPE void wxStfDoc::SetPSlopeBeg(int value) { correctRangeR(value); PSlopeBeg = value; } void wxStfDoc::SetPSlopeEnd(int value) { correctRangeR(value); PSlopeEnd = value; } #endif stfnum::Table wxStfDoc::CurAsTable() const { stfnum::Table table(cursec().size(),size()); try { for (std::size_t nRow=0;nRow= 0) { table.at(0,nCol) = GetPeak()-GetThreshold(); } else { table.at(0,nCol) = 0; } if (viewCursors) { table.at(1,nCol)=GetPeakBeg()*GetXScale(); table.at(2,nCol)=GetPeakEnd()*GetXScale(); } nCol++; } // RT (Lo-Hi%) if (viewRTLoHi) {table.at(0,nCol)=GetRTLoHi(); if (viewCursors) { table.at(1,nCol)=GetTLoReal()*GetXScale(); table.at(2,nCol)=GetTHiReal()*GetXScale(); } nCol++; } if (viewInnerRiseTime) { table.at(0,nCol)=GetInnerRiseTime(); if (viewCursors) { table.at(1,nCol)=GetInnerLoRT(); table.at(2,nCol)=GetInnerHiRT(); } nCol++; } if (viewOuterRiseTime) { table.at(0,nCol)=GetOuterRiseTime(); if (viewCursors) { table.at(1,nCol)=GetOuterLoRT(); table.at(2,nCol)=GetOuterHiRT(); } nCol++; } // Half duration if (viewT50) {table.at(0,nCol)=GetHalfDuration(); if (viewCursors) { table.at(1,nCol)=GetT50LeftReal()*GetXScale(); table.at(2,nCol)=GetT50RightReal()*GetXScale(); } nCol++; } // Rise/decay if (viewRD) {table.at(0,nCol)=GetSlopeRatio(); if (viewCursors) { table.at(1,nCol)=GetMaxRiseT()*GetXScale(); table.at(2,nCol)=GetMaxDecayT()*GetXScale(); } nCol++; } // Max rise if (viewSloperise) {table.at(0,nCol)=GetMaxRise(); if (viewCursors) { table.at(1,nCol)=GetMaxRiseT()*GetXScale(); table.SetEmpty(2,nCol,true); } nCol++; } // Max decay if (viewSlopedecay) {table.at(0,nCol)=GetMaxDecay(); if (viewCursors) { table.at(1,nCol)=GetMaxDecayT()*GetXScale(); table.SetEmpty(2,nCol,true); } nCol++; } // Latency if (viewLatency) {table.at(0,nCol)=GetLatency()*GetXScale(); if (viewCursors) { table.at(1,nCol)=GetLatencyBeg()*GetXScale(); table.at(2,nCol)=GetLatencyEnd()*GetXScale(); } nCol++; } #ifdef WITH_PSLOPE // PSlope if (viewPSlope) {table.at(0,nCol)=GetPSlope(); if (viewCursors) { table.at(1,nCol)=GetPSlopeBeg()*GetXScale(); table.at(2,nCol)=GetPSlopeEnd()*GetXScale(); } nCol++; } #endif // WITH_PSLOPE return table; } void wxStfDoc::resize(std::size_t c_n_channels) { Recording::resize(c_n_channels); yzoom.resize(size()); sec_attr.resize(size()); for (std::size_t nchannel = 0; nchannel < size(); ++nchannel) { sec_attr[nchannel].resize(at(nchannel).size()); } } void wxStfDoc::InsertChannel(Channel& c_Channel, std::size_t pos) { Recording::InsertChannel(c_Channel, pos); yzoom.resize(size()); sec_attr.resize(size()); for (std::size_t nchannel = 0; nchannel < size(); ++nchannel) { sec_attr[nchannel].resize(at(nchannel).size()); } } void wxStfDoc::SetIsFitted( std::size_t nchannel, std::size_t nsection, const Vector_double& bestFitP_, stfnum::storedFunc* fitFunc_, double chisqr, std::size_t fitBeg, std::size_t fitEnd ) { if (nchannel >= sec_attr.size() || nsection >= sec_attr[nchannel].size()) { throw std::out_of_range("Index out of range in wxStfDoc::SetIsFitted"); } if ( !fitFunc_ ) { throw std::runtime_error("Function pointer is zero in wxStfDoc::SetIsFitted"); } if ( fitFunc_->pInfo.size() != bestFitP_.size() ) { throw std::runtime_error("Number of best-fit parameters doesn't match number\n \ of function parameters in wxStfDoc::SetIsFitted"); } sec_attr[nchannel][nsection].fitFunc = fitFunc_; if ( sec_attr[nchannel][nsection].bestFitP.size() != bestFitP_.size() ) sec_attr[nchannel][nsection].bestFitP.resize(bestFitP_.size()); sec_attr[nchannel][nsection].bestFitP = bestFitP_; sec_attr[nchannel][nsection].bestFit = sec_attr[nchannel][nsection].fitFunc->output(sec_attr[nchannel][nsection].bestFitP, sec_attr[nchannel][nsection].fitFunc->pInfo, chisqr ); sec_attr[nchannel][nsection].storeFitBeg = fitBeg; sec_attr[nchannel][nsection].storeFitEnd = fitEnd; sec_attr[nchannel][nsection].isFitted = true; } void wxStfDoc::DeleteFit(std::size_t nchannel, std::size_t nsection) { if (nchannel >= sec_attr.size() || nsection >= sec_attr[nchannel].size()) { throw std::out_of_range("Index out of range in wxStfDoc::DeleteFit"); } sec_attr[nchannel][nsection].fitFunc = NULL; sec_attr[nchannel][nsection].bestFitP.resize( 0 ); sec_attr[nchannel][nsection].bestFit = stfnum::Table( 0, 0 ); sec_attr[nchannel][nsection].isFitted = false; } void wxStfDoc::SetIsIntegrated(std::size_t nchannel, std::size_t nsection, bool value, std::size_t begin, std::size_t end, const Vector_double& quad_p_) { if (nchannel >= sec_attr.size() || nsection >= sec_attr[nchannel].size()) { throw std::out_of_range("Index out of range in wxStfDoc::SetIsIntegrated"); } if (value==false) { sec_attr[nchannel][nsection].isIntegrated=value; return; } if (end<=begin) { throw std::out_of_range("integration limits out of range in Section::SetIsIntegrated"); } int n_intervals=std::div((int)end-(int)begin,2).quot; if ((int)quad_p_.size() != n_intervals*3) { throw std::out_of_range("Wrong number of parameters for quadratic equations in Section::SetIsIntegrated"); } sec_attr[nchannel][nsection].quad_p = quad_p_; sec_attr[nchannel][nsection].isIntegrated=value; sec_attr[nchannel][nsection].storeIntBeg=begin; sec_attr[nchannel][nsection].storeIntEnd=end; } void wxStfDoc::ClearEvents(std::size_t nchannel, std::size_t nsection) { wxStfView* pView=(wxStfView*)GetFirstView(); if (pView!=NULL) { wxStfGraph* pGraph = pView->GetGraph(); if (pGraph != NULL) { pGraph->ClearEvents(); } } try { sec_attr.at(nchannel).at(nsection).eventList.clear(); } catch(const std::out_of_range& e) { throw e; } } const stf::SectionAttributes& wxStfDoc::GetSectionAttributes(std::size_t nchannel, std::size_t nsection) const { try { return sec_attr.at(nchannel).at(nsection); } catch(const std::out_of_range& e) { throw e; } } const stf::SectionAttributes& wxStfDoc::GetCurrentSectionAttributes() const { try { return sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()); } catch(const std::out_of_range& e) { throw e; } } stf::SectionAttributes& wxStfDoc::GetCurrentSectionAttributesW() { try { return sec_attr.at(GetCurChIndex()).at(GetCurSecIndex()); } catch(const std::out_of_range& e) { throw e; } } #if 0 void wxStfDoc::Userdef(std::size_t id) { wxBusyCursor wc; int fselect=(int)id; Recording newR; Vector_double init(0); // get user input if necessary: if (!wxGetApp().GetPluginLib().at(fselect).input.labels.empty()) { wxStfUsrDlg myDlg( GetDocumentWindow(), wxGetApp().GetPluginLib().at(fselect).input ); if (myDlg.ShowModal()!=wxID_OK) { return; } init=myDlg.readInput(); } // Apply function to current valarray std::map< wxString, double > resultsMap; try { newR=wxGetApp().GetPluginLib().at(fselect).pluginFunc( *this, init, resultsMap ); } catch (const std::out_of_range& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return; } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return; } catch (const std::exception& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); return; } if (newR.size()==0) { return; } wxString newTitle(GetTitle()); newTitle += wxT(", "); newTitle += wxGetApp().GetPluginLib().at(fselect).menuEntry; wxStfDoc* pDoc = wxGetApp().NewChild(newR,this,newTitle); ((wxStfChildFrame*)pDoc->GetDocumentWindow())->ShowTable( stfnum::Table(resultsMap), wxGetApp().GetPluginLib().at(fselect).menuEntry ); } #endif stimfit-0.16.7/src/stimfit/gui/parentframe.h0000775000175000017500000002140514750344764014501 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file parentframe.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfParentFrame. */ #ifndef _PARENTFRAME_H #define _PARENTFRAME_H /*! \addtogroup wxstf * @{ */ #include #include #include #include "./../stf.h" class wxStfGraph; class wxStfTable; class wxStfGrid; class wxStfFileDrop; class wxProgressDialog; typedef wxAuiToolBar wxStfToolBar; #ifdef WITH_PYTHON struct new_wxwindow { new_wxwindow(wxWindow* cppW=NULL, PyObject* pyW=NULL) : cppWindow(cppW), pyWindow(pyW) {} wxWindow* cppWindow; PyObject* pyWindow; }; #else struct new_wxwindow { new_wxwindow(wxWindow* cppW=NULL, void* pyW=NULL) : cppWindow(cppW), pyWindow(pyW) {} wxWindow* cppWindow; void* pyWindow; }; #endif //! Provides the top-level frame. /*! It is part of the of the document/view framework implemented in wxWidgets. * This class can only be used for MDI parent frames. */ class StfDll wxStfParentFrame : public wxStfParentType { DECLARE_CLASS(wxStfParentFrame) public: //! Constructor /*! \param manager Pointer to the document manager. * \param frame Pointer to the parent frame (should be NULL, because this is * the top-level frame * \param title Title of this frame. * \param pos Initial position of this frame. * \param size Initial size of this frame. * \param style Window style. */ wxStfParentFrame(wxDocManager *manager, wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, long style); //! Destructor ~wxStfParentFrame(); //! Shows the "About" dialog. /*! \param event The menu event that made the call. */ void OnAbout(wxCommandEvent& event); //! Creates a new graph. /*! Called from view.cpp when a new drawing view is created. * \param view Pointer to the attached view. * \param parent Pointer to the child frame that will serve as a parent for the new graph. * \return A pointer to the newly created graph. */ wxStfGraph *CreateGraph(wxView *view, wxStfChildFrame *parent); //! Retrieve the current mouse mode. /*! \return The current mouse cursor mode. */ stf::cursor_type GetMouseQual() const; //! Sets the current mouse cursor mode. /*! \param value The new mouse cursor mode. */ void SetMouseQual(stf::cursor_type value); //! Sets status of the toolbar's selection button. /*! \param selected The desired toggle status of the selection button. */ void SetSelectedButton(bool selected); //! Retrieve which channels will be affected by scaling operations /*! \return The channels affected by scaling operations. */ stf::zoom_channels GetZoomQual() const; //! Set the channels that will be affected by scaling operations /*! \param value The channels affected by scaling operations. */ void SetZoomQual(stf::zoom_channels value); //! Set the zoom buttons to single- or multi-channel mode. /*! \param value Set to true for single- or false for multi-channel mode. */ void SetSingleChannel(bool value); //! Retrieves the print data /*! \return Pointer to the stored print data. */ wxPrintData* GetPrintData() { return m_printData.get(); } //! Retrieves the page setup /*! \return Pointer to the page setup data. */ wxPageSetupDialogData* GetPageSetup() { return m_pageSetupData.get(); } //! Retrieve the wxAuiManager. /*! \return A reference to the wxAuiManager. */ wxAuiManager& GetMgr() { return m_mgr; } //! Checks for updates. /*! \param progDlg An optional progress dialog */ void CheckUpdate( wxProgressDialog* progDlg=NULL ) const; new_wxwindow MakePythonWindow(const std::string& windowFunc, const std::string& mgr_name="pythonShell", const std::string& caption="Python Shell", bool show=true, bool full=false, bool isfloat=true, int width=-1, int height=-1, double mpl_width=8.0, double mpl_height=6.0); int GetMplFigNo() {return mpl_figno++;} private: wxAuiManager m_mgr; wxStfToolBar *m_cursorToolBar, *m_scaleToolBar; wxStfFileDrop* m_drop; #ifdef WITH_PYTHON wxString python_code2; // python import code void RedirectStdio(); #endif #if (__cplusplus < 201103) // print data, to remember settings during the session boost::shared_ptr m_printData; // page setup data boost::shared_ptr m_pageSetupData; #else // print data, to remember settings during the session std::shared_ptr m_printData; // page setup data std::shared_ptr m_pageSetupData; #endif bool firstResize; int mpl_figno; wxStfToolBar* CreateStdTb(); wxStfToolBar* CreateScaleTb(); wxStfToolBar* CreateEditTb(); wxStfToolBar* CreateCursorTb(); void OnHelp(wxCommandEvent& event); void OnCheckUpdate(wxCommandEvent& event); void OnToggleSelect(wxCommandEvent& event); void OnToolFirst(wxCommandEvent& event); void OnToolNext(wxCommandEvent& event); void OnToolPrevious(wxCommandEvent& event); void OnToolLast(wxCommandEvent& event); void OnToolXenl(wxCommandEvent& event); void OnToolXshrink(wxCommandEvent& event); void OnToolYenl(wxCommandEvent& event); void OnToolYshrink(wxCommandEvent& event); void OnToolUp(wxCommandEvent& event); void OnToolDown(wxCommandEvent& event); void OnToolFit(wxCommandEvent& event); void OnToolLeft(wxCommandEvent& event); void OnToolRight(wxCommandEvent& event); void OnToolCh1(wxCommandEvent& event); void OnToolCh2(wxCommandEvent& event); void OnToolSnapshotwmf(wxCommandEvent& event); void OnToolMeasure(wxCommandEvent& event); void OnToolPeak(wxCommandEvent& event); void OnToolBase(wxCommandEvent& event); void OnToolDecay(wxCommandEvent& event); void OnToolLatency(wxCommandEvent& event); void OnToolZoom(wxCommandEvent& event); void OnToolEvent(wxCommandEvent& event); void OnToolFitdecay(wxCommandEvent& event); #ifdef WITH_PSLOPE void OnToolPSlope(wxCommandEvent& event); #endif // void OnSwapChannels(wxCommandEvent& event); void OnCh2base(wxCommandEvent& event); void OnCh2pos(wxCommandEvent& event); void OnCh2zoom(wxCommandEvent& event); void OnCh2basezoom(wxCommandEvent& event); void OnAverage(wxCommandEvent& event); void OnAlignedAverage(wxCommandEvent& event); void OnExportfile(wxCommandEvent& event); void OnExportatf(wxCommandEvent& event); void OnExportigor(wxCommandEvent& event); void OnExporthdf5(wxCommandEvent& event); void OnConvert(wxCommandEvent& event); void OnPrint(wxCommandEvent& event); void OnScale(wxCommandEvent& event); void OnMpl(wxCommandEvent& event); void OnMplSpectrum(wxCommandEvent& event); void OnPageSetup(wxCommandEvent& event); void OnViewResults(wxCommandEvent& event); void OnSaveperspective(wxCommandEvent& event); void OnLoadperspective(wxCommandEvent& event); void OnRestoreperspective(wxCommandEvent& event); #ifdef WITH_PYTHON void OnViewshell(wxCommandEvent& event); void OnUserdef(wxCommandEvent& event); #endif void OnLStartMaxslope(wxCommandEvent& event); void OnLStartHalfrise(wxCommandEvent& event); void OnLStartPeak(wxCommandEvent& event); void OnLStartManual(wxCommandEvent& event); void OnLEndFoot(wxCommandEvent& event); void OnLEndMaxslope(wxCommandEvent& event); void OnLEndHalfrise(wxCommandEvent& event); void OnLEndPeak(wxCommandEvent& event); void OnLEndManual(wxCommandEvent& event); void OnLWindow(wxCommandEvent& event); DECLARE_EVENT_TABLE() }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/app.cpp0000775000175000017500000015435514752207205013311 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // app.cpp // The application, derived from wxApp // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg #include // For compilers that support precompilation, includes "wx/wx.h". #include #include #include #include #include #include #include #include #include #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #if !wxUSE_DOC_VIEW_ARCHITECTURE #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h! #endif #if !wxUSE_MDI_ARCHITECTURE #error You must set wxUSE_MDI_ARCHITECTURE to 1 in setup.h! #endif #include "stfconf.h" #include "./app.h" #include "./doc.h" #include "./view.h" #include "./parentframe.h" #include "./childframe.h" #include "./graph.h" #include "./dlgs/cursorsdlg.h" #include "./dlgs/smalldlgs.h" #include "./../../libstfnum/funclib.h" #include "./../../libstfnum/fit.h" #if defined(__WXGTK__) || defined(__WXMAC__) #if !defined(__MINGW32__) #include "./../../libstfio/abf/axon/Common/axodefn.h" #include "./../../libstfio/abf/axon/AxAbfFio32/abffiles.h" #endif #endif extern wxStfApp& wxGetApp(); wxStfApp& wxGetApp() { return *static_cast(wxApp::GetInstance()); } BEGIN_EVENT_TABLE( wxStfApp, wxApp ) EVT_KEY_DOWN( wxStfApp::OnKeyDown ) EVT_MENU( ID_CURSORS, wxStfApp::OnCursorSettings ) EVT_MENU( ID_NEWFROMSELECTED, wxStfApp::OnNewfromselected ) EVT_MENU( ID_NEWFROMALL, wxStfApp::OnNewfromall ) EVT_MENU( ID_APPLYTOALL, wxStfApp::OnApplytoall ) #ifdef WITH_PYTHON EVT_MENU( ID_IMPORTPYTHON, wxStfApp::OnPythonImport ) EVT_MENU_RANGE(ID_USERDEF, ID_USERDEF+32, wxStfApp::OnUserdef) #endif END_EVENT_TABLE() wxStfApp::wxStfApp(void) : directTxtImport(false), isBars(true), txtImport(), funcLib(), #ifdef WITH_PYTHON extensionLib(), #endif CursorsDialog(NULL), storedLinFunc( stfnum::initLinFunc() ), /*m_file_menu(0),*/ m_fileToLoad(wxEmptyString), mrActiveDoc(0) {} void wxStfApp::OnInitCmdLine(wxCmdLineParser& parser) { wxApp::OnInitCmdLine(parser); parser.AddOption(wxT("d"), wxT("dir"), wxT("Working directory to change to"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL ); parser.AddParam(wxT("File to open"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL ); } bool wxStfApp::OnCmdLineParsed(wxCmdLineParser& parser) { // Check if we should change the working directory: wxString new_cwd( wxT("\0") ); if ( parser.Found( wxT("dir"), &new_cwd ) ) { // Check whether the directory exists: if ( !wxDirExists( new_cwd ) ) { wxString msg; msg << wxT("New working directory ") << new_cwd << wxT(" doesn't exist."); ErrorMsg( msg ); return false; } // Change to the new wd: if ( !wxSetWorkingDirectory( new_cwd ) ) { wxString msg; msg << wxT("Couldn't change working directory to ") << new_cwd; ErrorMsg( msg ); return false; } } // Get file to load if ( parser.GetParamCount() > 0 ) { m_fileToLoad = parser.GetParam(); } return wxApp::OnCmdLineParsed(parser); } bool wxStfApp::OnInit(void) { #ifndef _STFDEBUG wxLog::SetLogLevel(wxLOG_FatalError); #endif if (!wxApp::OnInit()) { std::cerr << "Could not start application" << std::endl; return false; } #ifdef WITH_PYTHON if ( !Init_wxPython() ) { // don't start the app if we can't initialize wxPython. wxString msg; msg << wxT("Could not start wxPython"); ErrorMsg( msg ); return false; } // Load Python extensions before creation of wxMenuBar ( see later CreateUnifiedMenuBar() ) #if PY_MAJOR_VERSION < 3 extensionLib = LoadExtensions(); #ifdef _STFDEBUG std::cout << (int) GetExtensionLib().size() << " Python extension/s loaded"<< std::endl; #endif #endif #endif //WITH_PTYHON // Config: config.reset(new wxFileConfig(wxT("Stimfit"))); //// Create a document manager wxDocManager* docManager = new wxDocManager; //// Create a template relating drawing documents to their views #if defined(WITH_BIOSIG) m_biosigTemplate=new wxDocTemplate( docManager, wxT("All files"), wxT("*.*"), wxT(""), wxT(""), wxT("Biosig Document"), wxT("Biosig View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); #endif #if defined(WITH_BIOSIG) m_biosigTemplate=new wxDocTemplate( docManager, wxT("Biosig files"), wxT("*.dat;*.cfs;*.gdf;*.ibw;*.wcp"), wxT(""), wxT(""), wxT("Biosig Document"), wxT("Biosig View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); #endif m_cfsTemplate=new wxDocTemplate( docManager, wxT("CED filing system"), wxT("*.dat;*.cfs"), wxT(""), wxT("dat;cfs"), wxT("CFS Document"), wxT("CFS View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); m_hdf5Template=new wxDocTemplate( docManager, wxT("hdf5 file"), wxT("*.h5"), wxT(""), wxT("h5"), wxT("HDF5 Document"), wxT("HDF5 View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); m_abfTemplate=new wxDocTemplate( docManager, wxT("Axon binary file"), wxT("*.abf"), wxT(""), wxT("abf"), wxT("ABF Document"), wxT("ABF View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); #if defined(__WXGTK__) || defined(__WXMAC__) ABF_Initialize(); #endif m_atfTemplate=new wxDocTemplate( docManager, wxT("Axon text file"), wxT("*.atf"), wxT(""), wxT("atf"), wxT("ATF Document"), wxT("ATF View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); m_axgTemplate=new wxDocTemplate( docManager, wxT("Axograph binary file"), wxT("*.axgd;*.axgx"), wxT(""), wxT("axgd;axgx"), wxT("AXG Document"), wxT("AXG View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); m_hekaTemplate=new wxDocTemplate( docManager, wxT("HEKA file"), wxT("*.dat"), wxT(""), wxT("dat"), wxT("HEKA Document"), wxT("HEKA View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); m_intanTemplate=new wxDocTemplate( docManager, wxT("Intan CLAMP file"), wxT("*.clp"), wxT(""), wxT("clp"), wxT("Intan CLAMP Document"), wxT("Intan View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); m_tdmsTemplate=new wxDocTemplate( docManager, wxT("Mantis TDMS file"), wxT("*.tdms"), wxT(""), wxT("tdms"), wxT("Mantis TDMS Document"), wxT("TDMS View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); #if 0 m_sonTemplate=new wxDocTemplate( docManager, wxT("CED Spike 2 (SON) file"), wxT("*.smr"), wxT(""), wxT(""), wxT("SON Document"), wxT("SON View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); #endif m_txtTemplate=new wxDocTemplate( docManager, wxT("General text file import"), wxT("*.*"), wxT(""), wxT(""), wxT("Text Document"), wxT("Text View"), CLASSINFO(wxStfDoc), CLASSINFO(wxStfView) ); // read last directory from config: wxString lastDir = wxGetProfileString( wxT("Settings"), wxT("Last directory"), wxT("") ); if (lastDir == wxT("") || !wxFileName::DirExists( lastDir )) { lastDir = wxFileName::GetCwd(); } docManager->SetLastDirectory( lastDir ); //// Create the main frame window wxStfParentFrame* frame = new wxStfParentFrame(docManager, nullptr, wxT("Stimfit"), wxDefaultPosition, #ifndef __WXMAC__ wxSize(1024, 768), #else wxSize(640, 480), #endif wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE | wxMAXIMIZE); #if 0 frame->SetIcon( wxICON(sample) ); #endif // frame->SetIcon(wxIcon(wxT("doc.xbm"))); #ifndef __WXGTK__ //// Make a menubar wxMenu* m_file_menu = new wxMenu; // wxMenu *edit_menu = (wxMenu *) NULL; m_file_menu->Append(wxID_OPEN); m_file_menu->AppendSeparator(); m_file_menu->Append(ID_CONVERT, wxT("Convert file series...")); #ifdef WITH_PYTHON m_file_menu->AppendSeparator(); m_file_menu->Append( ID_IMPORTPYTHON, wxT("&Import Python module...\tCtrl+I"), wxT("Import or reload user-defined Python modules") ); #endif // WITH_PYTHON m_file_menu->AppendSeparator(); m_file_menu->Append(wxID_EXIT); // A nice touch: a history of files visited. Use this menu. GetDocManager()->FileHistoryLoad( *config ); GetDocManager()->FileHistoryUseMenu(m_file_menu); #if (wxCHECK_VERSION(2, 9, 0)) GetDocManager()->FileHistoryAddFilesToMenu(m_file_menu); #else GetDocManager()->FileHistoryAddFilesToMenu(); #endif wxMenu *help_menu = new wxMenu; help_menu->Append(wxID_HELP); help_menu->Append(ID_UPDATE, wxT("&Check for updates")); help_menu->Append(wxID_ABOUT); wxMenu *m_view_menu = new wxMenu; #ifdef WITH_PYTHON m_file_menu->AppendSeparator(); m_view_menu->Append(ID_VIEW_SHELL, wxT("&Toggle Python shell"), wxT("Shows or hides the Python shell")); #endif // WITH_PYTHON wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(m_file_menu, wxT("&File")); /* if (edit_menu) menu_bar->Append(edit_menu, wxT("&Edit")); */ menu_bar->Append(m_view_menu, wxT("&View")); menu_bar->Append(help_menu, wxT("&Help")); #ifdef __WXMAC__ // wxApp::SetExitOnFrameDelete(false); wxMenuBar::MacSetCommonMenuBar(menu_bar); #endif #else // __WXGTK__ wxMenuBar* menu_bar = CreateUnifiedMenuBar(); #endif //__WXGTK__ frame->SetMenuBar(menu_bar); frame->Centre(wxBOTH); /* pStatusBar = new wxStatusBar(frame); frame->SetStatusBar(pStatusBar); */ #if 1 //ndef __WXMAC__ frame->Show(true); #endif //ndef __WXMAC__ // check for updates in background: #ifndef __WXMAC__ frame->CheckUpdate(NULL); #endif // load user-defined plugins: // pluginLib = stf::GetPluginLib(); //#ifdef WITH_PYTHON // extensionLib = LoadExtensions(); // std::cout << "DEBUG: wxStfApp extensionLib size is " << GetExtensionLib().size() << std::endl; //#endif // load fit function library: funcLib = stfnum::GetFuncLib(); SetTopWindow(frame); if (!m_fileToLoad.empty()) { wxDocTemplate* templ=GetDocManager()->FindTemplateForPath(m_fileToLoad); wxStfDoc* NewDoc=(wxStfDoc*)templ->CreateDocument(m_fileToLoad,wxDOC_NEW); NewDoc->SetDocumentTemplate(templ); if (!NewDoc->OnOpenDocument(m_fileToLoad)) { ErrorMsg(wxT("Couldn't open file, aborting file import")); GetDocManager()->CloseDocument(NewDoc); return false; } } return true; } int wxStfApp::OnExit() { #if wxUSE_CONFIG GetDocManager()->FileHistorySave(*config); #endif // wxUSE_CONFIG delete GetDocManager(); #ifdef WITH_PYTHON Exit_wxPython(); #endif return wxApp::OnExit(); } // "Fake" registry void wxStfApp::wxWriteProfileInt(const wxString& main, const wxString& sub, int value) const { // create a wxConfig-compatible path: wxString path=wxT("/")+main+wxT("/")+sub; if (!config->Write(path,(long)value)) { ErrorMsg(wxT("Couldn't write application settings")); return; } config->Flush(); } int wxStfApp::wxGetProfileInt(const wxString& main,const wxString& sub, int default_) const { wxString path=wxT("/")+main+wxT("/")+sub; return config->Read(path,default_); } void wxStfApp::wxWriteProfileString( const wxString& main, const wxString& sub, const wxString& value ) const { // create a wxConfig-compatible path: wxString path=wxT("/")+main+wxT("/")+sub; if (!config->Write(path,value)) { ErrorMsg(wxT("Couldn't write application settings")); return; } config->Flush(); } wxString wxStfApp::wxGetProfileString( const wxString& main, const wxString& sub, const wxString& default_) const { wxString path=wxT("/")+main+wxT("/")+sub; return config->Read(path,default_); } void wxStfApp::OnPeakcalcexecMsg(wxStfDoc* actDoc) { if (actDoc==0) { actDoc = GetActiveDoc(); if (!actDoc) return; } if (!actDoc->IsInitialized()) { ErrorMsg(wxT("Uninitialized file in wxStfApp::OnPeakcalcexecMsg()")); return; } #ifdef __WXMAC__ wxStfView* actView = (wxStfView*)actDoc->GetFirstView(); #else wxStfView* actView = GetActiveView(); #endif if (actView!=NULL) { wxStfGraph* pGraph = actView->GetGraph(); if (pGraph != NULL) pGraph->Refresh(); else return; } if (CursorsDialog != NULL && CursorsDialog->IsShown() && actView!=NULL && actDoc!=NULL && actDoc->IsInitialized()) { CursorsDialog->SetActiveDoc(actDoc); switch (CursorsDialog->CurrentCursor()) { case stf::measure_cursor: actDoc->SetMeasCursor(CursorsDialog->GetCursorM());// * GetDocument()->GetSR())); wxWriteProfileInt(wxT("Settings"), wxT("MeasureCursor"), CursorsDialog->GetCursorM() ); actDoc->SetMeasRuler( CursorsDialog->GetRuler() ); wxWriteProfileInt(wxT("Settings"), wxT("ShowRuler"), CursorsDialog->GetRuler() ); break; //Get limits for peak calculation from the dialog box: case stf::peak_cursor: actDoc->SetPeakBeg(CursorsDialog->GetCursor1P());// * GetDocument()->GetSR())); actDoc->SetPeakEnd(CursorsDialog->GetCursor2P());// * GetDocument()->GetSR())); actDoc->CheckBoundaries(); break; case stf::base_cursor: wxWriteProfileInt(wxT("Settings"), wxT("BaselineMethod"), CursorsDialog->GetBaselineMethod()); actDoc->SetBaseBeg(CursorsDialog->GetCursor1B()); actDoc->SetBaseEnd(CursorsDialog->GetCursor2B()); actDoc->SetBaselineMethod(CursorsDialog->GetBaselineMethod()); break; case stf::decay_cursor: actDoc->SetFitBeg(CursorsDialog->GetCursor1D()); actDoc->SetFitEnd(CursorsDialog->GetCursor2D()); break; case stf::latency_cursor: // Use peak cursors for latency? // actDoc->SetLatencyWindowMode(CursorsDialog->UsePeak4Latency() ); // wxWriteProfileInt(wxT("Settings"), wxT("LatencyWindowMode"), CursorsDialog->UsePeak4Latency() ); // Latency start mode actDoc->SetLatencyBeg(CursorsDialog->GetCursor1L()); // set latency mode in wxStfDoc actDoc->SetLatencyStartMode(CursorsDialog->GetLatencyStartMode() ); // write latency start mode in Stimfit Profile wxWriteProfileInt(wxT("Settings"), wxT("LatencyStartMode"), CursorsDialog->GetLatencyStartMode() ); if (CursorsDialog->GetLatencyStartMode() == stf::manualMode) wxWriteProfileInt(wxT("Settings"), wxT("LatencyStartCursor"), CursorsDialog->GetCursor1L() ); // Latency end mode actDoc->SetLatencyEnd(CursorsDialog->GetCursor2L()); actDoc->SetLatencyEndMode(CursorsDialog->GetLatencyEndMode() ); wxWriteProfileInt(wxT("Settings"), wxT("LatencyEndMode"), CursorsDialog->GetLatencyEndMode() ); if (CursorsDialog->GetLatencyEndMode() == stf::manualMode) wxWriteProfileInt(wxT("Settings"), wxT("LatencyEndCursor"), CursorsDialog->GetCursor2L() ); break; #ifdef WITH_PSLOPE case stf::pslope_cursor: // first PSlope cursor actDoc->SetPSlopeBegMode( CursorsDialog->GetPSlopeBegMode() ); wxWriteProfileInt(wxT("Settings"), wxT("PSlopeStartMode"), CursorsDialog->GetPSlopeBegMode() ); if (actDoc->GetPSlopeBegMode() == stf::psBeg_manualMode) actDoc->SetPSlopeBeg( CursorsDialog->GetCursor1PS() ); //wxWriteProfileInt(wxT("Settings"), wxT("PSlopeStartCursor"), CursorsDialog->GetCursor1PS() ); // second PSlope cursor actDoc->SetPSlopeEndMode( CursorsDialog->GetPSlopeEndMode() ); if (actDoc->GetPSlopeEndMode() == stf::psEnd_manualMode) actDoc->SetPSlopeEnd( CursorsDialog->GetCursor2PS() ); // we take data from CursorsDialog only if we need the DeltaT //else if (actDoc->GetPSlopeEndMode() == stf::psEnd_DeltaTMode){ actDoc->SetDeltaT(CursorsDialog->GetDeltaT()); break; #endif case stf::undefined_cursor: ErrorMsg(wxT("Undefined cursor in wxStfApp::OnPeakcalcexecMsg()")); return; default: break; } wxWriteProfileInt(wxT("Settings"), wxT("PeakAtEnd"), CursorsDialog->GetPeakAtEnd() ); //Update edit peak limits in the peak calculation dialog box if (CursorsDialog->GetPeakAtEnd()) { //If 'Upper limit at end of trace' is selected in the dialog box //Set upper limit to end of trace actDoc->SetPeakEnd((int)actDoc->cursec().size()-1); try { CursorsDialog->UpdateCursors(); } catch (const std::runtime_error& e) { ExceptMsg(wxString(e.what(), wxConvLocal)); return; } actDoc->SetPeakAtEnd(true); } else { actDoc->SetPeakAtEnd(false); } // Get number of peak points from the dialog box... actDoc->SetPM(CursorsDialog->GetPeakPoints()); wxWriteProfileInt(wxT("Settings"),wxT("PeakMean"),(int)actDoc->GetPM()); // Get direction from the dialog box actDoc->SetDirection(CursorsDialog->GetDirection()); wxWriteProfileInt(wxT("Settings"),wxT("Direction"), CursorsDialog->GetDirection()); // Get reference for AP kinetics from the dialog box actDoc->SetFromBase(CursorsDialog->GetFromBase()); wxWriteProfileInt(wxT("Settings"),wxT("FromBase"), CursorsDialog->GetFromBase()); // Get factor for rise time calculation actDoc->SetRTFactor(CursorsDialog->GetRTFactor()); wxWriteProfileInt(wxT("Settings"),wxT("RTFactor"), CursorsDialog->GetRTFactor()); // Get slope for threshold: actDoc->SetSlopeForThreshold( CursorsDialog->GetSlope() ); wxString wxsSlope; wxsSlope << CursorsDialog->GetSlope(); wxWriteProfileString(wxT("Settings"), wxT("Slope"), wxsSlope); wxWriteProfileInt(wxT("Settings"), wxT("StartFitAtPeak"), CursorsDialog->GetStartFitAtPeak() ); //Update start fit at peak if ( CursorsDialog->GetStartFitAtPeak() ) { actDoc->SetFitBeg( actDoc->GetMaxT() ); actDoc->SetStartFitAtPeak(true); try { CursorsDialog->UpdateCursors(); } catch (const std::runtime_error& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); return; } } else { actDoc->SetStartFitAtPeak(false); } } // Calculate peak, base, Lo/Hi rise time, half duration, // ratio of rise/slope, maximum slope and geometrical slope (PSlope). try { if (actDoc != NULL) { actDoc->Measure( ); } } catch (const std::out_of_range& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); } /* // Set fit start cursor to new peak if necessary. //std::cout << CursorsDialog->GetPeakAtEnd() << std::endl; //wxWriteProfileInt(wxT("Settings"), wxT("StartFitAtPeak"), CursorsDialog->GetStartFitAtPeak() ); if (actDoc != NULL && CursorsDialog != NULL && CursorsDialog->GetStartFitAtPeak()) //if ( CursorsDialog->GetStartFitAtPeak() ) { //actDoc->SetFitBeg(actDoc->GetMaxT()); actDoc->SetStartFitAtPeak( true ); //try { // CursorsDialog->UpdateCursors(); //} //catch (const std::runtime_error& e) { // ExceptMsg(wxString( e.what(), wxConvLocal )); // return; //} } else { actDoc->SetStartFitAtPeak( true ); } */ // Updates strings in the result box if (actView != NULL) { wxStfChildFrame* pChild=(wxStfChildFrame*)actView->GetFrame(); if (pChild != NULL) pChild->UpdateResults(); wxStfGraph* pGraph = actView->GetGraph(); if (pGraph != NULL) pGraph->SetFocus(); } } wxMenuBar *wxStfApp::CreateUnifiedMenuBar(wxStfDoc* doc) { //// Make a menubar wxMenu *file_menu = new wxMenu; file_menu->Append(wxID_OPEN); file_menu->Append(wxID_CLOSE); // file_menu->Append(wxID_SAVE, wxT("&Save")); file_menu->Append(wxID_SAVEAS); //#ifdef _WINDOWS file_menu->AppendSeparator(); file_menu->Append(ID_CONVERT, wxT("&Convert file series...")); //#endif file_menu->AppendSeparator(); file_menu->Append(ID_FILEINFO, wxT("File information...")); file_menu->AppendSeparator(); file_menu->Append(ID_MPL, wxT("Create &figure...")); file_menu->Append(ID_PRINT_PRINT, wxT("&Print...")); file_menu->Append(ID_PRINT_PAGE_SETUP, wxT("Print &Setup...")); #ifdef WITH_PYTHON file_menu->AppendSeparator(); file_menu->Append( ID_IMPORTPYTHON, wxT("&Import Python module...\tCtrl+I"), wxT("Import or reload user-defined Python modules") ); #endif // WITH_PYTHON file_menu->AppendSeparator(); file_menu->Append(wxID_EXIT); #if !defined __WXGTK__ && (wxCHECK_VERSION(2, 9, 0)) ((wxStfDoc*)doc)->SetFileMenu( file_menu ); #else GetDocManager()->FileHistoryLoad( *config ); #endif GetDocManager()->FileHistoryUseMenu(file_menu); #if (wxCHECK_VERSION(2, 9, 0)) GetDocManager()->FileHistoryAddFilesToMenu(file_menu); #else GetDocManager()->FileHistoryAddFilesToMenu(); #endif wxMenu* m_edit_menu=new wxMenu; m_edit_menu->Append( ID_CURSORS, wxT("&Cursor settings...\tCtrl+R"), wxT("Set cursor position, direction, etc.") ); m_edit_menu->AppendSeparator(); m_edit_menu->Append( ID_MYSELECTALL, wxT("&Select all traces\tCtrl+A"), wxT("Select all traces in this file") ); m_edit_menu->Append( ID_SELECTSOME, wxT("S&elect some traces..."), wxT("Select every n-th trace in this file") ); m_edit_menu->Append( ID_SELECT_AND_ADD, wxT("Se&lect and add traces of type ..."), wxT("Traces of a certain type are added to the select") ); m_edit_menu->Append( ID_UNSELECTALL, wxT("&Unselect all traces\tCtrl+U"), wxT("Unselect all traces in this file") ); m_edit_menu->Append( ID_UNSELECTSOME, wxT("U&nselect some traces"), wxT("Unselect some traces in this file") ); m_edit_menu->Append( ID_SELECT_AND_REMOVE, wxT("Unse&lect traces of type ..."), wxT("Traces of a certain type are removed from the selection") ); wxMenu *editSub=new wxMenu; editSub->Append( ID_NEWFROMSELECTEDTHIS, wxT("&selected traces from this file"), wxT("Create a new window showing all selected traces from this file") ); editSub->Append( ID_NEWFROMSELECTED, wxT("&selected traces from all files"), wxT("Create a new window showing all selected traces from all files") ); editSub->Append(ID_NEWFROMALL, wxT("&all traces from all files"), wxT("Create a new window showing all traces from all files") ); m_edit_menu->AppendSeparator(); m_edit_menu->AppendSubMenu(editSub,wxT("New window with...")); m_edit_menu->Append( ID_CONCATENATE_MULTICHANNEL, wxT("&Concatenate selected sweeps (multiple channels)"), wxT("Create one large sweep by merging selected sweeps in this file") ); wxMenu* m_view_menu = new wxMenu; m_view_menu->Append( ID_VIEW_RESULTS, wxT("&Results..."), wxT("Select analysis results to be shown in the results table") ); m_view_menu->Append( ID_APPLYTOALL, wxT("&Apply scaling to all windows"), wxT("Apply this trace's scaling to all other windows") ); m_view_menu->AppendCheckItem( ID_SCALE, wxT("&View scale bars"), wxT("If checked, use scale bars rather than coordinates") ); m_view_menu->AppendSeparator(); m_view_menu->Append(ID_SAVEPERSPECTIVE,wxT("&Save window positions")); m_view_menu->Append(ID_LOADPERSPECTIVE,wxT("&Load window positions")); m_view_menu->Append(ID_RESTOREPERSPECTIVE,wxT("&Restore default window positions")); #ifdef WITH_PYTHON m_view_menu->AppendSeparator(); m_view_menu->Append(ID_VIEW_SHELL, wxT("&Toggle Python shell"), wxT("Shows or hides the Python shell")); #endif // WITH_PYTHON wxMenu* ch2Sub=new wxMenu; ch2Sub->Append(ID_CH2BASE, wxT("Match &baseline")); ch2Sub->Append(ID_CH2POS, wxT("Match &abs. position")); ch2Sub->Append(ID_CH2ZOOM, wxT("Match &y-scale")); ch2Sub->Append(ID_CH2BASEZOOM, wxT("Match baseline a&nd y-scale")); m_view_menu->AppendSeparator(); m_view_menu->AppendSubMenu(ch2Sub, wxT("&Channel 2 scaling")); m_view_menu->Append(ID_SWAPCHANNELS, wxT("&Swap channels")); wxMenu *analysis_menu = new wxMenu; wxMenu *fitSub = new wxMenu; fitSub->Append( ID_FIT, wxT("&Nonlinear regression...\tCtrl+N"), wxT("Fit a function to this trace between fit cursors") ); fitSub->Append( ID_LFIT, wxT("&Linear fit..."), wxT("Fit a linear function to this trace between fit cursors") ); analysis_menu->AppendSubMenu(fitSub, wxT("&Fit")); wxMenu *transformSub = new wxMenu; transformSub->Append( ID_LOG, wxT("&Logarithmic (base e)..."), wxT("Transform selected traces logarithmically") ); analysis_menu->AppendSubMenu(transformSub, wxT("&Transform")); analysis_menu->Append( ID_MULTIPLY, wxT("&Multiply..."), wxT("Multiply selected traces") ); analysis_menu->Append( ID_INTEGRATE, wxT("&Integrate"), wxT("Integrate this trace between fit cursors") ); analysis_menu->Append( ID_DIFFERENTIATE, wxT("&Differentiate"), wxT("Differentiate selected traces") ); analysis_menu->Append( ID_SUBTRACTBASE, wxT("&Subtract baseline"), wxT("Subtract baseline from selected traces") ); analysis_menu->Append( ID_FILTER, wxT("Fi<er..."), wxT("Filter selected traces") ); analysis_menu->Append( ID_MPL_SPECTRUM, wxT("&Power spectrum..."), wxT("Compute an estimate of the power spectrum of the selected traces") ); analysis_menu->Append( ID_POVERN, wxT("P over &N correction..."), wxT("Apply P over N correction to all traces of this file") ); wxMenu* eventPlotSub = new wxMenu; eventPlotSub->Append(ID_PLOTCRITERION, wxT("&Detection criterion...")); eventPlotSub->Append(ID_PLOTCORRELATION, wxT("&Correlation coefficient...")); eventPlotSub->Append(ID_PLOTDECONVOLUTION, wxT("&Deconvolution...")); wxMenu* eventSub = new wxMenu; eventSub->AppendSubMenu(eventPlotSub,wxT("Plot")); eventSub->Append(ID_EXTRACT,wxT("&Template matching...")); eventSub->Append(ID_THRESHOLD,wxT("Threshold &crossing...")); analysis_menu->AppendSubMenu(eventSub,wxT("Event detection")); analysis_menu->Append( ID_BATCH, wxT("&Batch analysis..."), wxT("Analyze selected traces and show results in a table") ); #if 0 wxMenu* userdefSub=new wxMenu; for (std::size_t n=0;nAppend( ID_USERDEF1+(int)n, GetPluginLib()[n].menuEntry ); } analysis_menu->AppendSubMenu(userdefSub,wxT("User-defined functions")); #endif #ifdef WITH_PYTHON wxMenu *extensions_menu = new wxMenu; for (std::size_t n=0;nAppend(ID_USERDEF+(int)n, stf::std2wx(GetExtensionLib()[n].menuEntry)); } #endif wxMenu *help_menu = new wxMenu; help_menu->Append(wxID_HELP, wxT("Online &help\tF1")); help_menu->Append(wxID_ABOUT, wxT("&About")); help_menu->Append(ID_UPDATE, wxT("&Check for updates")); wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, wxT("&File")); menu_bar->Append(m_edit_menu, wxT("&Edit")); menu_bar->Append(m_view_menu, wxT("&View")); menu_bar->Append(analysis_menu, wxT("&Analysis")); #ifdef WITH_PYTHON menu_bar->Append(extensions_menu, wxT("E&xtensions")); #endif menu_bar->Append(help_menu, wxT("&Help")); return menu_bar; } /* * Centralised code for creating a document frame. * Called from view.cpp when a view is created. */ wxStfChildFrame *wxStfApp::CreateChildFrame(wxDocument *doc, wxView *view) { //// Make a child frame wxStfChildFrame *subframe = new wxStfChildFrame( doc, view, wxStaticCast(GetTopWindow(), wxStfParentFrame), wxID_ANY, doc->GetTitle(), #ifdef __WXMAC__ wxDefaultPosition, wxDefaultSize, #else wxDefaultPosition, wxDefaultSize, #endif wxDEFAULT_FRAME_STYLE | // wxNO_FULL_REPAINT_ON_RESIZE | wxWANTS_CHARS | wxMAXIMIZE ); #ifdef __WXMSW__ subframe->SetIcon(wxString(wxT("chart"))); #endif #ifdef __X__ // subframe->SetIcon(wxIcon(wxT("doc.xbm"))); #endif #ifndef __WXGTK__ wxMenuBar* menu_bar = CreateUnifiedMenuBar((wxStfDoc*)doc); //// Associate the menu bar with the frame subframe->SetMenuBar(menu_bar); #endif // __WXGTK__ return subframe; } wxStfDoc* wxStfApp::NewChild(const Recording& NewData, const wxStfDoc* Sender, const wxString& title) { wxStfDoc* NewDoc=(wxStfDoc*)m_cfsTemplate->CreateDocument(title,wxDOC_NEW); NewDoc->SetDocumentName(title); NewDoc->SetTitle(title); NewDoc->SetDocumentTemplate(m_cfsTemplate); if (!NewDoc->OnNewDocument()) return NULL; try { NewDoc->SetData(NewData, Sender, title); } catch (const std::out_of_range& e) { wxString msg; msg << wxT("Error while creating new document:\n") << stf::std2wx(e.what()); ExceptMsg(msg); // Close file: NewDoc->OnCloseDocument(); return NULL; } catch (const std::runtime_error& e) { wxString msg; msg << wxT("Runtime error while creating new document:\n") << wxString( e.what(), wxConvLocal ); ExceptMsg( msg ); // Close file: if (!NewDoc->OnCloseDocument()) ErrorMsg(wxT("Could not close file; please close manually")); return NULL; } return NewDoc; } wxStfView* wxStfApp::GetActiveView() const { if ( GetDocManager() == 0) { ErrorMsg( wxT("Couldn't access the document manager")); return NULL; } wxStfView* pView = (wxStfView*)GetDocManager()->GetCurrentView(); if (pView == NULL) { if (mrActiveDoc != NULL) { return (wxStfView*)mrActiveDoc->GetFirstView(); } } return pView; } wxStfDoc* wxStfApp::GetActiveDoc() const { if ( GetDocManager() == 0) { ErrorMsg( wxT("Couldn't access the document manager")); return NULL; } if (GetDocManager()->GetDocuments().empty()) return NULL; wxStfDoc* pDoc = (wxStfDoc*)GetDocManager()->GetCurrentDocument(); if (pDoc == NULL) { return mrActiveDoc; } return pDoc; } void wxStfApp::OnKeyDown( wxKeyEvent& event ) { event.Skip(); wxStfDoc* actDoc = GetActiveDoc(); if (!actDoc) return; // wxStfView* actView = (wxStfView*)actDoc->GetFirstView(); wxStfView* actView = GetActiveView(); if (actView) { wxStfGraph* pGraph = actView->GetGraph(); wxStfChildFrame* pChild=(wxStfChildFrame*)actView->GetFrame(); if (pGraph && pChild && pChild->IsActive()) pGraph->OnKeyDown(event); } } void wxStfApp::OnCursorSettings( wxCommandEvent& WXUNUSED(event) ) { wxStfDoc* actDoc=GetActiveDoc(); if (CursorsDialog==NULL && actDoc!=NULL) { CursorsDialog=new wxStfCursorsDlg((wxStfParentFrame*)GetTopWindow(), actDoc); CursorsDialog->Show(); CursorsDialog->SetActiveDoc(actDoc); //set CEdit controls to given values try { CursorsDialog->UpdateCursors(); } catch (const std::runtime_error& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); return; } //set CButton to given direction CursorsDialog->SetDirection(actDoc->GetDirection()); CursorsDialog->SetPeakPoints((int)actDoc->GetPM()); CursorsDialog->SetFromBase(actDoc->GetFromBase()); CursorsDialog->SetSlope( actDoc->GetSlopeForThreshold() ); return; } if(CursorsDialog!=NULL && !CursorsDialog->IsShown() && actDoc!=NULL) { CursorsDialog->Show(); CursorsDialog->SetActiveDoc(actDoc); //set CEdit controls to given values try { CursorsDialog->UpdateCursors(); } catch (const std::runtime_error& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); return; } //set CButton to given direction CursorsDialog->SetDirection(actDoc->GetDirection()); CursorsDialog->SetPeakPoints((int)actDoc->GetPM()); CursorsDialog->SetFromBase(actDoc->GetFromBase()); CursorsDialog->SetSlope( actDoc->GetSlopeForThreshold() ); } } void wxStfApp::OnNewfromselected( wxCommandEvent& WXUNUSED(event) ) { // number of selected traces across all open documents: std::size_t nwxT=0; // Search the document's template list for open documents: wxList docList=GetDocManager()->GetDocuments(); if (docList.IsEmpty()) { ErrorMsg(wxT("No traces were found")); return; } // Since random access is expensive, go through the list node by node: // Get first node: wxObjectList::compatibility_iterator curNode=docList.GetFirst(); std::size_t n_channels=((wxStfDoc*)curNode->GetData())->size(); while (curNode) { wxStfDoc* pDoc=(wxStfDoc*)curNode->GetData(); if (pDoc->size()!=n_channels) { ErrorMsg(wxT("Can't combine files: different numbers of channels")); return; } try { nwxT+=pDoc->GetSelectedSections().size(); } catch (const std::out_of_range& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); return; } curNode=curNode->GetNext(); } if (nwxT==0) { ErrorMsg(wxT("No selected traces were found")); return; } Recording Selected(n_channels,nwxT); // Do the same iteration once again filling the channel with data: curNode=docList.GetFirst(); wxStfDoc* pDoc=NULL; nwxT=0; std::vector > channel_names(n_channels); while (curNode) { pDoc=(wxStfDoc*)curNode->GetData(); if (pDoc->GetSelectedSections().size() > 0) { for (std::size_t n_c=0;n_csize();++n_c) { channel_names[n_c].push_back(pDoc->get()[n_c].GetChannelName()); for (std::size_t n=0; nGetSelectedSections().size(); ++n) { try { Selected[n_c].InsertSection( pDoc->get()[n_c][pDoc->GetSelectedSections()[n]], n+nwxT ); } catch (const std::out_of_range& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); return; } } } } nwxT+=pDoc->GetSelectedSections().size(); curNode=curNode->GetNext(); } // Set channel names: for (std::size_t n_c=0;n_c=0 && !used;--n_used) { // can't use size_t here because // n_used might be negative when checking loop condition used = ( channel_names[n_c][n_n].compare( channel_names[n_c][n_used] ) == 0 ); } if (!used) { channel_name << wxT(", ") << channel_names[n_c][n_n]; } } Selected.get()[n_c].SetChannelName(channel_name.str()); } // Copy some variables from the last document's recording // to the new recording: Selected.CopyAttributes(*pDoc); // Create a new document in a new child window, using the settings // of the last open document: NewChild(Selected,pDoc,wxT("New from selected traces")); } void wxStfApp::OnNewfromall( wxCommandEvent& WXUNUSED(event) ) { // number of traces in all open documents: std::size_t nwxT=0; // minimal number of channels: // Search the document's template list for open documents: wxList docList=GetDocManager()->GetDocuments(); if (docList.IsEmpty()) { ErrorMsg(wxT("No traces were found")); return; } // Since random access is expensive, go through the list node by node: // Get first node: wxObjectList::compatibility_iterator curNode=docList.GetFirst(); std::size_t n_channels=((wxStfDoc*)curNode->GetData())->size(); while (curNode) { wxStfDoc* pDoc=(wxStfDoc*)curNode->GetData(); if (pDoc->size()!=n_channels) { ErrorMsg(wxT("Can't combine files: different numbers of channels")); return; } try { nwxT+=pDoc->get().at(pDoc->GetCurChIndex()).size(); } catch (const std::out_of_range& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); return; } curNode=curNode->GetNext(); } Recording Selected(n_channels,nwxT); //Do the same iteration once again filling the channel with data: curNode=docList.GetFirst(); nwxT=0; wxStfDoc* pDoc=NULL; std::vector > channel_names(n_channels); while (curNode) { pDoc=(wxStfDoc*)curNode->GetData(); if (pDoc->get()[pDoc->GetCurChIndex()].size() > 0) { for (std::size_t n_c=0;n_cget()[n_c].GetChannelName()); for (std::size_t n=0; nget()[n_c].size(); ++n) { try { Selected[n_c].InsertSection(pDoc->get()[n_c][n],n+nwxT); } catch (const std::out_of_range& e) { ExceptMsg(wxString( e.what(), wxConvLocal )); return; } } } } nwxT+=pDoc->get()[pDoc->GetCurChIndex()].size(); curNode=curNode->GetNext(); } // Set channel names: for (std::size_t n_c=0;n_c=0 && !used;--n_used) { // can't use size_t here because // n_used might be negative when checking loop condition used = ( channel_names[n_c][n_n].compare( channel_names[n_c][n_used] ) == 0 ); } if (!used) { channel_name << wxT(", ") << channel_names[n_c][n_n]; } } Selected.get()[n_c].SetChannelName(channel_name.str()); } // Copy some variables from the last document's recording // to the new recording: Selected.CopyAttributes(*pDoc); // Create a new document in a new child window, using the settings // of the last open document: NewChild(Selected,pDoc,wxT("New from all traces")); } void wxStfApp::OnApplytoall( wxCommandEvent& WXUNUSED(event) ) { // toggle through open documents to find out // which one is active: // Search the document's template list for open documents: wxList docList=GetDocManager()->GetDocuments(); if (docList.IsEmpty()) { ErrorMsg(wxT("No traces were found")); return; } wxStfDoc* pDoc=GetActiveDoc(); wxStfView* pView=GetActiveView(); if (pDoc==NULL || pView==NULL) { ErrorMsg(wxT("Couldn't find an active window")); return; } std::size_t llbToApply=pDoc->GetBaseBeg(); std::size_t ulbToApply=pDoc->GetBaseEnd(); std::size_t llpToApply=pDoc->GetPeakBeg(); std::size_t ulpToApply=pDoc->GetPeakEnd(); std::size_t lldToApply=pDoc->GetFitBeg(); std::size_t uldToApply=pDoc->GetFitEnd(); double latencyStartCursorToApply=pDoc->GetLatencyBeg(); double latencyEndCursorToApply=pDoc->GetLatencyEnd(); // Since random access is expensive, go through the list node by node: // Get first node: wxObjectList::compatibility_iterator curNode=docList.GetFirst(); while (curNode) { wxStfDoc* OpenDoc=(wxStfDoc*)curNode->GetData(); if (OpenDoc==NULL) return; wxStfView* curView = (wxStfView*)OpenDoc->GetFirstView(); //(GetActiveView()); if (curView!=pView && curView!=NULL) { OpenDoc->GetXZoomW() = pDoc->GetXZoom(); for ( std::size_t n_c=0; n_c < OpenDoc->size(); ++n_c ) { if ( n_c < pDoc->size() ) { OpenDoc->GetYZoomW(n_c) = pDoc->GetYZoom(n_c); } } OpenDoc->SetBaseBeg((int)llbToApply); OpenDoc->SetBaseEnd((int)ulbToApply); OpenDoc->SetPeakBeg((int)llpToApply); OpenDoc->SetPeakEnd((int)ulpToApply); OpenDoc->SetFitBeg((int)lldToApply); OpenDoc->SetFitEnd((int)uldToApply); OpenDoc->SetLatencyBeg(latencyStartCursorToApply); OpenDoc->SetLatencyEnd(latencyEndCursorToApply); wxStfChildFrame* pChild=(wxStfChildFrame*)curView->GetFrame(); pChild->UpdateResults(); if (curView->GetGraph() != NULL) curView->GetGraph()->Refresh(); } curNode=curNode->GetNext(); } } bool wxStfApp::OpenFileSeries(const wxArrayString& fNameArray) { int nFiles=(int)fNameArray.GetCount(); if (nFiles==0) return false; bool singleWindow=false; if (nFiles!=1) { // Ask whether to put files into a single window: singleWindow=(wxMessageDialog( (wxStfParentFrame*)GetTopWindow(), wxT("Put files into a single window?"), wxT("File series import"), wxYES_NO ).ShowModal() == wxID_YES); } wxProgressDialog progDlg( wxT("Importing file series"), wxT("Starting file import"), 100, (wxStfParentFrame*)GetTopWindow(), wxPD_SMOOTH | wxPD_AUTO_HIDE ); int n_opened=0; Recording seriesRec; while (n_opened!=nFiles) { wxString progStr; progStr << wxT("Reading file #") << n_opened + 1 << wxT(" of ") << nFiles; progDlg.Update( (int)((double)n_opened/(double)nFiles*100.0), progStr ); if (!singleWindow) { wxDocTemplate* templ=GetDocManager()->FindTemplateForPath(fNameArray[n_opened]); wxStfDoc* NewDoc=(wxStfDoc*)templ->CreateDocument(fNameArray[n_opened],wxDOC_NEW); NewDoc->SetDocumentTemplate(templ); if (!NewDoc->OnOpenDocument(fNameArray[n_opened++])) { ErrorMsg(wxT("Couldn't open file, aborting file import")); GetDocManager()->CloseDocument(NewDoc); return false; } } else { // Add to recording first: #ifndef TEST_MINIMAL // Find a template: wxDocTemplate* templ=GetDocManager()->FindTemplateForPath(fNameArray[n_opened]); // Use this template only for type recognition: wxString filter(templ->GetFileFilter()); stfio::filetype type = stfio::findType(stf::wx2std(templ->GetFileFilter())); #else stfio::filetype type = stfio::none; #endif #if 0 // TODO: re-implement ascii if (type==stfio::ascii) { if (!get_directTxtImport()) { wxStfTextImportDlg ImportDlg(NULL, stf::CreatePreview(fNameArray[n_opened]), 1, true); if (ImportDlg.ShowModal()!=wxID_OK) { return false; } // store settings in application: set_txtImportSettings(ImportDlg.GetTxtImport()); set_directTxtImport(ImportDlg.ApplyToAll()); } } #endif // add this file to the series recording: Recording singleRec; try { stf::wxProgressInfo progDlg("Reading file", "Opening file", 100); stfio::importFile(stf::wx2std(fNameArray[n_opened++]),type,singleRec,txtImport, progDlg); if (n_opened==1) { seriesRec.resize(singleRec.size()); // reserve memory to avoid allocations: for (std::size_t n_c=0;n_cFindTemplateForPath( filename ); if ( templ == NULL ) { ErrorMsg(wxT("Couldn't open file, aborting file import")); return false; } wxStfDoc* NewDoc = (wxStfDoc*)templ->CreateDocument( filename, wxDOC_NEW ); if ( NewDoc == NULL ) { ErrorMsg(wxT("Couldn't open file, aborting file import")); return false; } NewDoc->SetDocumentTemplate(templ); if (!NewDoc->OnOpenPyDocument(filename)) { ErrorMsg(wxT("Couldn't open file, aborting file import")); GetDocManager()->CloseDocument(NewDoc); return false; } return true; } #endif //WITH_PYTHON void wxStfApp::CleanupDocument(wxStfDoc* pDoc) { // count open docs: if (GetDocManager() && GetDocManager()->GetDocuments().GetCount()==1) { // Clean up if this was the last document: if (CursorsDialog!=NULL) { CursorsDialog->Destroy(); CursorsDialog=NULL; } } // Update active document: /* activeDoc.remove(pDoc); */ // Remove menu from file history menu list: // GetDocManager()->FileHistoryUseMenu(m_file_menu); // GetDocManager()->FileHistoryAddFilesToMenu(); } std::vector wxStfApp::GetSectionsWithFits() const { // Search the document's template list for open documents: wxList docList=GetDocManager()->GetDocuments(); if (docList.IsEmpty()) { return std::vector(0); } std::vector sectionList; // Since random access is expensive, go through the list node by node: // Get first node: wxObjectList::compatibility_iterator curNode=docList.GetFirst(); while (curNode) { wxStfDoc* pDoc=(wxStfDoc*)curNode->GetData(); try { for (std::size_t n_sec=0; n_sec < pDoc->get().at(pDoc->GetCurChIndex()).size(); ++n_sec) { stf::SectionAttributes sec_attr = pDoc->GetSectionAttributes(pDoc->GetCurChIndex(), n_sec); if (sec_attr.isFitted) { sectionList.push_back(stf::SectionPointer(&pDoc->get()[pDoc->GetCurChIndex()][n_sec], sec_attr) ); } } } catch (const std::out_of_range& e) { ExceptMsg( wxString( e.what(), wxConvLocal ) ); return std::vector(0); } curNode=curNode->GetNext(); } return sectionList; } wxString wxStfApp::GetVersionString() const { wxString verString; verString << wxT("Stimfit ") << wxString(PACKAGE_VERSION, wxConvLocal) #ifdef _STFDEBUG << wxT(", debug build, "); #else << wxT(", release build, "); #endif verString << wxT(__DATE__) << wxT(", ") << wxT(__TIME__); return verString; } // LocalWords: wxStfView #ifdef WITH_PYTHON void wxStfApp::OnPythonImport(wxCommandEvent& WXUNUSED(event)) { // show a file selection dialog menu. wxString pyFilter; // file filter only show *.py pyFilter = wxT("Python file (*.py)|*.py"); wxFileDialog LoadModuleDialog ((wxStfParentFrame*)GetTopWindow(), wxT("Import/reload Python module"), wxT(""), wxT(""), pyFilter, wxFD_OPEN | wxFD_PREVIEW ); if (LoadModuleDialog.ShowModal() == wxID_OK) { wxString modulelocation = LoadModuleDialog.GetPath(); ImportPython(modulelocation); // see in /src/app/unopt.cpp L196 } else { return; } } #endif // WITH_PYTHON stimfit-0.16.7/src/stimfit/gui/app.h0000775000175000017500000004266414750344764012767 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file app.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfApp. */ #ifndef _APP_H #define _APP_H /*! \defgroup wxstf Stimfit classes and functions derived from wxWidgets * @{ */ //! Event ids enum { ID_TOOL_FIRST, // = wxID_HIGHEST+1, resulted in wrong events being fired ID_TOOL_NEXT, ID_TOOL_PREVIOUS, ID_TOOL_LAST, ID_TOOL_XENL, ID_TOOL_XSHRINK, ID_TOOL_YENL, ID_TOOL_YSHRINK, ID_TOOL_UP, ID_TOOL_DOWN, ID_TOOL_FIT, ID_TOOL_LEFT, ID_TOOL_RIGHT, ID_TOOL_SELECT, ID_TOOL_REMOVE, ID_TOOL_MEASURE, ID_TOOL_PEAK, ID_TOOL_BASE, ID_TOOL_DECAY, ID_TOOL_LATENCY, #ifdef WITH_PSLOPE ID_TOOL_PSLOPE, #endif ID_TOOL_ZOOM, ID_TOOL_EVENT, ID_TOOL_CH1, ID_TOOL_CH2, ID_TOOL_SNAPSHOT, ID_TOOL_SNAPSHOT_WMF, ID_TOOL_FITDECAY, #ifdef WITH_PYTHON ID_IMPORTPYTHON, #endif ID_VIEW_RESULTS, ID_VIEW_MEASURE, ID_VIEW_BASELINE, ID_VIEW_BASESD, ID_VIEW_THRESHOLD, ID_VIEW_PEAKZERO, ID_VIEW_PEAKBASE, ID_VIEW_PEAKTHRESHOLD, ID_VIEW_RTLOHI, ID_VIEW_INNERRISETIME, ID_VIEW_OUTERRISETIME, ID_VIEW_T50, ID_VIEW_RD, ID_VIEW_SLOPERISE, ID_VIEW_SLOPEDECAY, ID_VIEW_LATENCY, #ifdef WITH_PSLOPE ID_VIEW_PSLOPE, #endif ID_VIEW_CURSORS, ID_VIEW_SHELL, ID_FILEINFO, ID_EXPORTIMAGE, ID_EXPORTPS, ID_EXPORTLATEX, ID_EXPORTSVG, ID_TRACES, ID_PLOTSELECTED, ID_SHOWSECOND, ID_CURSORS, ID_AVERAGE, ID_ALIGNEDAVERAGE, ID_FIT, ID_LFIT, ID_LOG, ID_VIEWTABLE, ID_BATCH, ID_INTEGRATE, ID_DIFFERENTIATE, ID_CH2BASE, ID_CH2POS, ID_CH2ZOOM, ID_CH2BASEZOOM, ID_SWAPCHANNELS, ID_SCALE, ID_ZOOMHV, ID_ZOOMH, ID_ZOOMV, ID_EVENTADD, ID_EVENTEXTRACT, ID_APPLYTOALL, ID_UPDATE, ID_CONVERT, #if 0 ID_LATENCYSTART_MAXSLOPE, ID_LATENCYSTART_HALFRISE, ID_LATENCYSTART_PEAK, ID_LATENCYSTART_MANUAL, ID_LATENCYEND_FOOT, ID_LATENCYEND_MAXSLOPE, ID_LATENCYEND_HALFRISE, ID_LATENCYEND_PEAK, ID_LATENCYEND_MANUAL, ID_LATENCYWINDOW, #endif ID_PRINT_PRINT, ID_MPL, ID_MPL_SPECTRUM, ID_PRINT_PAGE_SETUP, ID_PRINT_PREVIEW, ID_COPYINTABLE, ID_MULTIPLY, ID_SELECTSOME, ID_UNSELECTSOME, ID_MYSELECTALL, ID_UNSELECTALL, ID_SELECT_AND_ADD, ID_SELECT_AND_REMOVE, ID_NEWFROMSELECTED, ID_NEWFROMSELECTEDTHIS, ID_NEWFROMALL, ID_CONCATENATE_MULTICHANNEL, ID_SUBTRACTBASE, ID_FILTER, ID_POVERN, ID_PLOTCRITERION, ID_PLOTCORRELATION, ID_PLOTDECONVOLUTION, ID_EXTRACT, ID_THRESHOLD, ID_LOADPERSPECTIVE, ID_SAVEPERSPECTIVE, ID_RESTOREPERSPECTIVE, ID_STFCHECKBOX, ID_EVENT_ADDEVENT, ID_EVENT_EXTRACT, ID_EVENT_ERASE, ID_COMBOTRACES, ID_SPINCTRLTRACES, ID_ZERO_INDEX, ID_COMBOACTCHANNEL, ID_COMBOINACTCHANNEL, #ifdef WITH_PYTHON ID_USERDEF, // this should be the last ID event #endif }; #include #include #include #include #include #include #include "./../stf.h" #include "./../../libstfnum/stfnum.h" #ifdef WITH_PYTHON #ifdef _POSIX_C_SOURCE #define _POSIX_C_SOURCE_WAS_DEF #undef _POSIX_C_SOURCE #endif #ifdef _XOPEN_SOURCE #define _XOPEN_SOURCE_WAS_DEF #undef _XOPEN_SOURCE #endif #include #ifdef _POSIX_C_SOURCE_WAS_DEF #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE #endif #endif #ifdef _XOPEN_SOURCE_WAS_DEF #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #endif #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic ignored "-Wwrite-strings" #endif #ifdef WITH_PYTHON #if PY_MAJOR_VERSION >= 3 #include #include #else #include #endif #endif // revert to previous behaviour #if defined(__WXMAC__) || defined(__WXGTK__) #pragma GCC diagnostic warning "-Wwrite-strings" #endif #endif // WITH_PYTHON #if (__cplusplus < 201103) #include #endif class wxDocManager; class wxStfDoc; class wxStfView; class wxStfCursorsDlg; class wxStfParentFrame; class wxStfChildFrame; class Section; //! The application, derived from wxApp /*! This class is used to set and get application-wide properties, * implement the windowing system message or event loop, * initiate application processing via OnInit, and * allow default processing of events not handled by other objects in the application. */ class StfDll wxStfApp: public wxApp { public: //! Constructor wxStfApp(); //! Initialise the application /*! Initialises the document manager and the file-independent menu items, * loads the user-defined extension library and the least-squares function library, * parses the command line and attempts to open a file if one was given * at program startup by either double-clicking it or as a command-line * argument. * \return true upon successful initialisation, false otherwise. */ virtual bool OnInit(); //! Exit the application /*! Does nothing but calling the base class's wxApp::OnExit(). * \return The return value of wxApp::OnExit(). */ virtual int OnExit(); //! Creates a new child frame /*! This is called from view.cpp whenever a child frame is created. If you * want to pop up a new frame showing a new document, use NewChild() instead; this * function will then be called by the newly created view. * \param doc A pointer to the document that the new child frame should contain. * \param view A pointer to the view corresponding to the document. * \return A pointer to the newly created child frame. */ wxStfChildFrame *CreateChildFrame(wxDocument *doc, wxView *view); //! Retrieves the currently active document. /*! \return A pointer to the currently active document. */ wxStfDoc* GetActiveDoc() const; //! Retrieves the currently active view. /*! \return A pointer to the currently active view. */ wxStfView* GetActiveView() const; //! Displays a message box when an error has occured. /*! You can use this function from almost anywhere using * wxGetApp().ErrorMsg( wxT( "Error abc: xyz" ) ); * \param msg The message string to be shown. */ void ErrorMsg(const wxString& msg) const { wxMessageBox(msg,wxT("An error has occured"),wxOK | wxICON_EXCLAMATION,NULL); } //! Displays a message box when an exception has occured. /*! You can use this function from almost anywhere using * wxGetApp().ExceptMsg( wxT( "Exception description xyz" ) ); * \param msg The message string to be shown. */ void ExceptMsg(const wxString& msg) const { wxMessageBox(msg,wxT("An exception was caught"),wxOK | wxICON_HAND,NULL); } //! Displays a message box with information. /*! You can use this function from almost anywhere using * wxGetApp().InfoMsg( wxT( "Info xyz" ) ); * \param msg The message string to be shown. */ void InfoMsg(const wxString& msg) const { wxMessageBox(msg,wxT("Information"), wxOK | wxICON_INFORMATION, NULL); } //! Indicates whether text files should be imported directly without showing an import settings dialog. /*! \return true if text files should be imported directly, false otherwise. */ bool get_directTxtImport() const { return directTxtImport; } //! Determines whether text files should be imported directly without showing an import filter settings dialog. /*! \param directTxtImport_ Set to true if text files should be imported directly, false otherwise. */ void set_directTxtImport(bool directTxtImport_) { directTxtImport=directTxtImport_; } //! Retrieves the text import filter settings. /*! \return A struct with the current text import filter settings. */ const stfio::txtImportSettings& GetTxtImport() const { return txtImport; } //! Sets the text import filter settings. /*! \param txtImport_ A struct with the new text import filter settings. */ void set_txtImportSettings(const stfio::txtImportSettings& txtImport_) { txtImport=txtImport_; } //! Retrieves the functions that are available for least-squares minimisation. /*! \return A vector containing the available functions. */ const std::vector& GetFuncLib() const { return funcLib; } //! Retrieves a pointer to a function for least-squares minimisation. /*! \return A vector containing the available functions. */ stfnum::storedFunc* GetFuncLibPtr(std::size_t at) { return &funcLib.at(at); } //! Retrieves a pointer to a function for least-squares minimisation. /*! \return A vector containing the available functions. */ stfnum::storedFunc* GetLinFuncPtr( ) { return &storedLinFunc; } #ifdef WITH_PYTHON //! Retrieves the user-defined extension functions. /*! \return A vector containing the user-defined functions. */ const std::vector< stf::Extension >& GetExtensionLib() const { return extensionLib; } #endif //! Retrieves the cursor settings dialog. /*! \return A pointer to the cursor settings dialog. */ wxStfCursorsDlg* GetCursorsDialog() const { return CursorsDialog; } //! Retrieves all sections with fits /*! \return A vector containing pointers to all sections in which fits have been performed */ std::vector GetSectionsWithFits() const; //! Writes an integer value to the configuration. /*! \param main The main path within the configuration. * \param sub The sub-path within the configuration. * \param value The integer to write to the configuration. */ void wxWriteProfileInt(const wxString& main,const wxString& sub, int value) const; //! Retrieves an integer value from the configuration. /*! \param main The main path within the configuration. * \param sub The sub-path within the configuration. * \param default_ The default integer to return if the configuration entry can't be read. * \return The integer that is stored in /main/sub, or default_ if the entry couldn't * be read. */ int wxGetProfileInt(const wxString& main,const wxString& sub, int default_) const; //! Writes a string to the configuration. /*! \param main The main path within the configuration. * \param sub The sub-path within the configuration. * \param value The string to write to the configuration. */ void wxWriteProfileString( const wxString& main, const wxString& sub, const wxString& value ) const; //! Retrieves a string from the configuration. /*! \param main The main path within the configuration. * \param sub The sub-path within the configuration. * \param default_ The default string to return if the configuration entry can't be read. * \return The string that is stored in /main/sub, or default_ if the entry couldn't * be read. */ wxString wxGetProfileString( const wxString& main, const wxString& sub, const wxString& default_ ) const; //! Creates a new child window showing a new document. /*! \param NewData The new data to be shown in the new window. * \param Sender The document that was at the origin of this new window. * \param title A title for the new document. * \return A pointer to the newly created document. */ wxStfDoc* NewChild( const Recording& NewData, const wxStfDoc* Sender, const wxString& title = wxT("\0") ); //! Execute all pending calculations. /*! Whenever settings that have an effect on measurements, such as * cursor positions or trace selections, are modified, this function * needs to be called to update the results table. */ void OnPeakcalcexecMsg(wxStfDoc* actDoc = 0); //! Sets the currently active document. /*! \param pDoc A pointer to the currently active document. */ void SetMRActiveDoc(wxStfDoc* pDoc) {mrActiveDoc = pDoc;} //! Destroys the last cursor settings dialog when the last document is closed /*! Do not use this function directly. It only needs to be called from wxStfDoc::OnCloseDocument(). * \param pDoc Pointer to the document that is being closed. */ void CleanupDocument(wxStfDoc* pDoc); //! Closes all documents bool CloseAll() { return GetDocManager()->CloseDocuments(); } //! Opens a series of files. Optionally, files can be put into a single window. /*! \param fNameArray An array of file names to be opened. * \return true upon successful opening of all files, false otherwise. */ bool OpenFileSeries(const wxArrayString& fNameArray); //! Returns the number of currently opened documents. /*! \return The number of currently opened documents. */ int GetDocCount() { return (int)GetDocManager()->GetDocuments().GetCount(); } //! Determine whether scale bars or coordinates should be shown. /*! \param value Set to true for scale bars, false for coordinates. */ void set_isBars(bool value) { isBars=value; } //! Indicates whether scale bars or coordinates are shown. /*! \return true for scale bars, false for coordinates. */ bool get_isBars() const { return isBars; } //! Get a formatted version string. /*! \return A version string (stimfit x.y.z, release/debug build, date). */ wxString GetVersionString() const; //! Open a new window showing all selected traces from all open files /*! \param event The associated menu event */ void OnNewfromselected( wxCommandEvent& event ); //! Access the document manager /*! \return A pointer to the document manager. */ wxDocManager* GetDocManager() const { return wxDocManager::GetDocumentManager(); } wxStfParentFrame* GetMainFrame() {return (wxStfParentFrame*)GetTopWindow();} virtual void OnInitCmdLine(wxCmdLineParser& parser); virtual bool OnCmdLineParsed(wxCmdLineParser& parser); #ifdef WITH_PYTHON //! Opens a file in a new window, to be called from Python. /*! \param fNameArray An array of file names to be opened. * \return true upon successful opening, false otherwise. */ bool OpenFilePy(const wxString& fNameArray); //! Opens a dialog to import a Python module /*! \param event The associated menu event */ void OnPythonImport( wxCommandEvent& event ); #endif protected: private: void OnCursorSettings( wxCommandEvent& event ); void OnNewfromall( wxCommandEvent& event ); void OnApplytoall( wxCommandEvent& event ); void OnProcessCustom( wxCommandEvent& event ); void OnKeyDown( wxKeyEvent& event ); #ifdef WITH_PYTHON void ImportPython(const wxString& modulelocation); void OnUserdef(wxCommandEvent& event); bool Init_wxPython(); bool Exit_wxPython(); std::vector LoadExtensions(); #endif // WITH_PYTHON wxMenuBar* CreateUnifiedMenuBar(wxStfDoc* doc=NULL); #ifdef _WINDOWS #pragma optimize( "", off ) #endif #ifdef _WINDOWS #pragma optimize( "", on ) #endif bool directTxtImport,isBars; stfio::txtImportSettings txtImport; // Registry: #if (__cplusplus < 201103) boost::shared_ptr config; #else std::shared_ptr config; #endif std::vector funcLib; #ifdef WITH_PYTHON std::vector< stf::Extension > extensionLib; #endif // Pointer to the cursors settings dialog box wxStfCursorsDlg* CursorsDialog; wxDocTemplate* m_cfsTemplate, *m_hdf5Template, *m_txtTemplate,*m_abfTemplate, *m_atfTemplate,*m_axgTemplate,*m_sonTemplate, *m_hekaTemplate, *m_intanTemplate, *m_tdmsTemplate, *m_biosigTemplate; stfnum::storedFunc storedLinFunc; // wxMenu* m_file_menu; wxString m_fileToLoad; /*std::list activeDoc;*/ wxStfDoc* mrActiveDoc; #ifdef WITH_PYTHON PyThreadState* m_mainTState; #endif DECLARE_EVENT_TABLE() }; #ifdef _WINDOWS //! Returns a reference to the application. extern StfDll wxStfApp& wxGetApp(); #else DECLARE_APP(wxStfApp) #endif #ifndef _STFDEBUG wxDISABLE_DEBUG_SUPPORT(); #endif //! true if in single-window mode extern bool singleWindowMode; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/main.cpp0000775000175000017500000000064714750344764013461 // For compilers that support precompilation, includes "wx/wx.h". #include #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "./app.h" wxAppConsole *wxCreateApp() { wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "your program"); return new wxStfApp; } wxAppInitializer wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp); IMPLEMENT_WXWIN_MAIN IMPLEMENT_WX_THEME_SUPPORT stimfit-0.16.7/src/stimfit/gui/doc.h0000775000175000017500000012536414750344764012753 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file doc.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfDoc. */ #ifndef _DOC_H #define _DOC_H /*! \addtogroup wxstf * @{ */ #include "./../stf.h" //! The document class, derived from both wxDocument and Recording. /*! The document class can be used to model an application’s file-based data. * It is part of the document/view framework supported by wxWidgets. */ class StfDll wxStfDoc: public wxDocument, public Recording { #ifndef FROM_PYTHON DECLARE_DYNAMIC_CLASS(wxStfDoc) #endif private: bool peakAtEnd, startFitAtPeak, initialized, progress; Recording Average; int InitCursors(); void PostInit(); bool ChannelSelDlg(); void WriteToReg(); bool outOfRange(std::size_t check) { return (check >= cursec().size()); } void Focus(); void OnNewfromselectedThisMenu( wxCommandEvent& event ) { OnNewfromselectedThis( ); } void Selectsome(wxCommandEvent& event); void Unselectsome(wxCommandEvent& event); void SelectTracesOfType(wxCommandEvent& event); void UnselectTracesOfType(wxCommandEvent& event); void ConcatenateMultiChannel(wxCommandEvent& event); void OnAnalysisBatch( wxCommandEvent& event ); void OnAnalysisIntegrate( wxCommandEvent& event ); void OnAnalysisDifferentiate( wxCommandEvent& event ); //void OnSwapChannels( wxCommandEvent& event ); void Multiply(wxCommandEvent& event); void SubtractBaseMenu( wxCommandEvent& event ) { SubtractBase( ); } void LFit(wxCommandEvent& event); void LnTransform(wxCommandEvent& event); void Filter(wxCommandEvent& event); void P_over_N(wxCommandEvent& event); void Plotextraction(stf::extraction_mode mode); void Plotcriterion(wxCommandEvent& event); void Plotcorrelation(wxCommandEvent& event); void Plotdeconvolution(wxCommandEvent& event); void MarkEvents(wxCommandEvent& event); void Threshold(wxCommandEvent& event); void Viewtable(wxCommandEvent& event); void Fileinfo(wxCommandEvent& event); Recording ReorderChannels(); wxMenu* doc_file_menu; stf::latency_mode latencyStartMode, latencyEndMode; stf::latency_window_mode latencyWindowMode; stfnum::direction direction; //of peak detection: UP, DOWN or BOTH #ifdef WITH_PSLOPE stf::pslope_mode_beg pslopeBegMode; // for left mode PSlope cursor stf::pslope_mode_end pslopeEndMode; // for right mode PSlope cursor #endif std::size_t baseBeg, baseEnd, peakBeg, peakEnd, fitBeg, fitEnd; stfnum::baseline_method baselineMethod; // method for calculating baseline #ifdef WITH_PSLOPE std::size_t PSlopeBeg, PSlopeEnd; int DeltaT; // distance (number of points) from the first cursor bool viewPSlope; #endif std::size_t measCursor; bool ShowRuler; // show a ruler throught the measurement cursor? double latencyStartCursor, latencyEndCursor, latency, //time from latency cursor to beginning of event base, APBase, baseSD, threshold, slopeForThreshold, peak, APPeak, tLoReal, tHiReal, t50LeftReal, t50RightReal, maxT, thrT, maxRiseY, maxRiseT, maxDecayY, maxDecayT, maxRise, maxDecay, t50Y, APMaxT, APMaxRiseY, APMaxRiseT, APt50LeftReal, APrtLoHi, APtLoReal, APtHiReal, APt0Real, #ifdef WITH_PSLOPE PSlope, #endif rtLoHi, InnerLoRT, InnerHiRT, OuterLoRT, OuterHiRT, halfDuration, slopeRatio, t0Real; // cursor windows: int pM; //peakMean, number of points used for averaging int RTFactor; // Lower point for the rise-time calculation std::size_t tLoIndex, tHiIndex, t50LeftIndex, t50RightIndex, APt50LeftIndex, APt50RightIndex, APtLoIndex, APtHiIndex; bool fromBase, viewCrosshair,viewBaseline,viewBaseSD,viewThreshold, viewPeakzero,viewPeakbase,viewPeakthreshold, viewRTLoHi, viewInnerRiseTime, viewOuterRiseTime, viewT50,viewRD,viewSloperise,viewSlopedecay,viewLatency, viewCursors; XZoom xzoom; std::vector yzoom; std::vector< std::vector > sec_attr; public: //! Constructor. /*! Does nothing but initialising the member list. */ wxStfDoc(); //! Destructor. ~wxStfDoc(); //! Swaps active and inactive channel /*! \param event The menu event that made the call. */ void OnSwapChannels( wxCommandEvent& event ); //! Override default file opening. /*! Attempts to identify the file type from the filter extension (such as "*.dat") * \param filename Full path of the file. * \return true if successfully opened, false otherwise. */ virtual bool OnOpenDocument(const wxString& filename); //! Open document without progress dialog. /*! Attempts to identify the file type from the filter extension (such as "*.dat") * \param filename Full path of the file. * \return true if successfully opened, false otherwise. */ virtual bool OnOpenPyDocument(const wxString& filename); //! Override default file saving. /*! \return true if successfully saved, false otherwise. */ virtual bool SaveAs(); #ifndef TEST_MINIMAL //! Override default file saving. /*! \param filename Full path of the file. * \return true if successfully saved, false otherwise. */ virtual bool DoSaveDocument(const wxString& filename); #endif //! Override default file closing. /*! Writes settings to the config file or registry before closing. * \return true if successfully closed, false otherwise. */ virtual bool OnCloseDocument(); //! Override default file creation. /*! \return true if successfully closed, false otherwise. */ virtual bool OnNewDocument(); //! Sets the content of a newly created file. /*! \param c_Data The data that is used for the new file. * \param Sender Pointer to the document that generated this file. * \param title Title of the new document. */ void SetData( const Recording& c_Data, const wxStfDoc* Sender, const wxString& title ); //! Indicates whether an average has been created. /*! \return true if an average has been created, false otherwise. */ bool GetIsAverage() const { return !Average.get().empty(); } //! Indicates whether the left decay cursor should always be at the peak of the trace. /*! \return true if the left decay cursor should be at the end of the trace, false otherwise. */ bool GetStartFitAtPeak() const { return startFitAtPeak; } //! Indicates whether the right peak cursor should always be at the end of a trace. /*! \return true if the right peak cursor should be at the end, false otherwise. */ bool GetPeakAtEnd() const { return peakAtEnd; } //! Indicates whether the the document is fully initialised. /*! The document has to be fully initialized before other parts of the * program start accessing it; for example, the graph might start reading out values * before they exist. * \return true if the document is fully initialised, false otherwise. */ bool IsInitialized() const { return initialized; } //! Sets the right peak cursor to the end of a trace. /*! \param value determines whether the peak cursor should be at the end of a trace. */ void SetPeakAtEnd(bool value) { peakAtEnd=value; } //! Sets the left decay cursor to the peak of the trace. /*! \param value determines whether the left decay cursor should be at the peak of the trace. */ void SetStartFitAtPeak(bool value) { startFitAtPeak=value; } //! Retrieves the average trace(s). /*! \return The average trace as a Recording object. */ const Recording& GetAverage() const { return Average; } //! Checks whether any cursor is reversed or out of range and corrects it if required. void CheckBoundaries(); //! Sets the current section to the specified value /*! Checks for out-of-range errors * \param section The 0-based index of the new section */ bool SetSection(std::size_t section); //! Creates a new window containing the selected sections of this file. /*! \return true upon success, false otherwise. */ bool OnNewfromselectedThis( ); //! Selects all sections /*! \param event The menu event that made the call. */ void Selectall(wxCommandEvent& event); //! Unselects all sections /*! \param event The menu event that made the call. */ void Deleteselected(wxCommandEvent& event); //! Updates the status of the selection button void UpdateSelectedButton(); //! Creates an average trace from the selected sections /*! \param calcSD Set to true if the standard deviation should be calculated as well, false otherwise * \param align Set to true if traces should be aligned to the point of steepest rise of the reference channel, * false otherwise. */ void CreateAverage( bool calcSD, bool align ); #if 0 //! Applies a user-defined function to the current data set /*! \param id The id of the user-defined function */ void Userdef(std::size_t id); #endif //! Toggles the selection status of the current section void ToggleSelect( ); //! Selects the current section if previously unselected void Select(); //! Unselects the current section if previously selected void Remove(); //! Creates a new document from the checked events /*! \param event The menu event that made the call. */ void Extract(wxCommandEvent& event); //! Erases all events, independent of whether they are checked or not /*! \param event The menu event that made the call. */ void InteractiveEraseEvents(wxCommandEvent& event); //! Adds an event at the current eventPos /*! \param event The menu event that made the call. */ void AddEvent( wxCommandEvent& event ); //! Subtracts the baseline of all selected traces. /*! \return true upon success, false otherwise. */ bool SubtractBase( ); //! Fit a function to the data. /*! \param event The menu event that made the call. */ void FitDecay(wxCommandEvent& event); //! Sets a pointer to the file menu attached to this document. /*! \param menu The menu to be attached. */ void SetFileMenu( wxMenu* menu ) { doc_file_menu = menu; } //! Measure everything using functions defined in measlib.h /*! This will measure the baseline, peak values, Lo to Hi% rise time, * half duration, maximal slopes during rise and decay, the ratio of these slopes * and the latency. */ void Measure(); //! Put the current measurement results into a text table. stfnum::Table CurResultsTable(); //! Retrieves the position of the measurement cursor (crosshair). /*! \return The index of the measurement cursor within the current section. */ std::size_t GetMeasCursor() const { return measCursor; } //! Retrieves the computation mode for baseline. /*! \return The current mode for computing the baseline. */ stfnum::baseline_method GetBaselineMethod() const { return baselineMethod; } //! Retrieves the position of the left baseline cursor. /*! \return The index of the left baseline cursor within the current section. */ std::size_t GetBaseBeg() const { return baseBeg; } //! Retrieves the position of the right baseline cursor /*! \return The index of the left baseline cursor within the current section. */ std::size_t GetBaseEnd() const { return baseEnd; } //! Retrieves the position of the left peak cursor. /*! \return The index of the left peak cursor within the current section. */ std::size_t GetPeakBeg() const { return peakBeg; } //! Retrieves the position of the right peak cursor. /*! \return The index of the right peak cursor within the current section. */ std::size_t GetPeakEnd() const { return peakEnd; } //! Retrieves the position of the left fitting cursor. /*! \return The index of the left fitting cursor within the current section. */ std::size_t GetFitBeg() const { return fitBeg; } //! Retrieves the position of the right fitting cursor. /*! \return The index of the right fitting cursor within the current section. */ std::size_t GetFitEnd() const { return fitEnd; } #ifdef WITH_PSLOPE //! Retrieves the position of the left PSlope cursor. /*! \return The index of the left PSlope cursor within the current section. */ std::size_t GetPSlopeBeg() const { return PSlopeBeg; } //! Retrieves the position of the right PSlope cursor. /*! \return The index of the right PSlope cursor within the current section. */ std::size_t GetPSlopeEnd() const { return PSlopeEnd; } #endif // WITH_PSLOPE //! Retrieves the number of points used for averaging during peak calculation. /*! \return The number of points to be used. */ int GetPM() const { return pM; } #ifdef WITH_PSLOPE //! Retrieves the number of points used for distance from the first cursor. /*! \return The number of points to be used. */ int GetDeltaT() const { return DeltaT; } #endif //! Retrieves the position of the left latency cursor. /*! \return The index of the left latency cursor within the current section. Note that by contrast * to the other cursors, this is a double because the latency cursor may be set to an interpolated * position between two data points. */ double GetLatencyBeg() const { return latencyStartCursor; } //! Retrieves the position of the right latency cursor. /*! \return The interpolated index of the right latency cursor within the current section. Note that * by contrast to the other cursors, this is a double because the latency cursor may be set to an * interpolated position between two data points. */ double GetLatencyEnd() const { return latencyEndCursor; } //! Retrieves the latency. /*! \return The latency, expressed in units of data points. */ double GetLatency() const { return latency; } //! Retrieves the time point at which Lo% of the maximal amplitude have been reached. /*! \return The time point at which Lo% of the maximal amplitude have been reached, expressed in * units of data points. */ double GetTLoReal() const { return tLoReal; } //! Retrieves the time point at which Hi% of the maximal amplitude have been reached. /*! \return The time point at which Hi% of the maximal amplitude have been reached, expressed in * units of data points. */ double GetTHiReal() const { return tHiReal; } //! Retrieves the time point at which Lo% of the maximal amplitude have been reached. /*! \return The time point at which Lo% of the maximal amplitude have been reached, expressed in * units of data points. */ double GetInnerLoRT() const { return InnerLoRT; } //! Retrieves the time point at which Hi% of the maximal amplitude have been reached. /*! \return The time point at which Hi% of the maximal amplitude have been reached, expressed in * units of data points. */ double GetInnerHiRT() const { return InnerHiRT; } //! Retrieves the time point at which Lo% of the maximal amplitude have been reached. /*! \return The time point at which Lo% of the maximal amplitude have been reached, expressed in * units of data points. */ double GetOuterLoRT() const { return OuterLoRT; } //! Retrieves the time point at which Hi% of the maximal amplitude have been reached. /*! \return The time point at which Hi% of the maximal amplitude have been reached, expressed in * units of data points. */ double GetOuterHiRT() const { return OuterHiRT; } //! Retrieves the extrapolated onset time point of an event in the active channel. /*! \return The onset time point of an event, extrapolated from the crossing of a line through * 20 and 80% of the event amplitude with the baseline. Expressed in units of data points. */ double GetT0Real() const { return t0Real; } //! Retrieves the time point at which 50% of the maximal amplitude have been reached from the left of the peak. /*! \return The time point at which 50% of the maximal amplitude have been reached from the left of the peak, * expressed in units of data points. */ double GetT50LeftReal() const { return t50LeftReal; } //! Retrieves the time point at which 50% of the maximal amplitude have been reached from the right of the peak. /*! \return The time point at which 50% of the maximal amplitude have been reached from the right of the peak, * expressed in units of data points. */ double GetT50RightReal() const { return t50RightReal; } //! Retrieves the y value at 50% of the maximal amplitude. /*! \return The y value at 50% of the maximal amplitude. */ double GetT50Y() const { return t50Y; } //! Retrieves the maximal slope of the rising phase. /*! \return The maximal slope during the rising phase. */ double GetMaxRise() const { return maxRise; } //! Retrieves the maximal slope of the decaying phase. /*! \return The maximal slope of rise. */ double GetMaxDecay() const { return maxDecay; } //! Retrieves the time point of the maximal slope of the rising phase in the second channel. /*! This time point is needed as a reference for the latency calculation and for aligned averages. * \return The time point at which the maximal slope of the rising phase is reached in the second channel, * expressed in units of data points.. */ double GetAPMaxRiseT() const { return APMaxRiseT; } //! Retrieves the time point of the peak in the second channel. /*! \return The time point at which the peak is found in the second channel, * expressed in units of data points. */ double GetAPMaxT() const { return APMaxT; } //! Retrieves the time point at which 50% of the max. amplitude have been reached from the left of the peak in the reference channel. /*! \return The time point at which 50% of the maximal amplitude have been reached from the left of the peak * in the reference channel, expressed in units of data points. */ double GetAPT50LeftReal() const { return APt50LeftReal; } //! Retrieves the extrapolated onset time point of an event in the reference channel. /*! \return The onset time point of an event, extrapolated from the crossing of a line through * 20 and 80% of the event amplitude with the baseline. Expressed in units of data points. */ double GetAPT0Real() const { return APt0Real; } //! Retrieves the time point of the maximal slope during the rising phase. /*! \return The time point of the maximal slope during the rising phase, expressed in units of data points. */ double GetMaxRiseT() const { return maxRiseT; } //! Retrieves the y-value at the time point of the maximal slope during the rising phase. /*! \return The y-value at the time point of the maximal slope during the rising phase. */ double GetMaxRiseY() const { return maxRiseY; } //! Retrieves the time point of the maximal slope during the decaying phase. /*! \return The time point of the maximal slope during the decaying phase, expressed in units of data points. */ double GetMaxDecayT() const { return maxDecayT; } //! Retrieves the y-value at the time point of the maximal slope during the decaying phase. /*! \return The y-value at the time point of the maximal slope during the decaying phase. */ double GetMaxDecayY() const { return maxDecayY; } //! Retrieves the y-value at the measurement cursor (crosshair). Will update measCursor if out of range. /*! \return The y-value at the measurement cursor. */ double GetMeasValue(); //! Retrieves the peak value. /*! \return The peak value. */ double GetPeak() const { return peak; } //! Retrieves the peak time value. /*! \return The peak time value. */ double GetPeakTime() const { return maxT; } //! Retrieves the baseline. /*! \return The baseline value. */ double GetBase() const { return base; } //! Retrieves the baseline in the second channel. /*! \return The baseline value in the second channel. */ double GetAPBase() const { return APBase; } //! Retrieves the standard deviation of the baseline. /*! \return The standard deviation of the baseline. */ double GetBaseSD() const { return baseSD; } //! Retrieves the value at which the threshold slope is crossed. /*! \return The standard deviation of the baseline. */ double GetThreshold() const { return threshold; } //! Retrieves the time point at which the peak is found. /*! \return The time point at which the peak is found, expressed in units of data points. */ double GetMaxT() const { return maxT; } //! Retrieves the time point at which the threshold slope is crossed. /*! \return The time point at which the threshold slope is crossed, or * a negative value if the threshold is not attained. */ double GetThrT() const { return thrT; } //! Retrieves the Lo to Hi% rise time. /*! \return The difference between GetTHiReal() and GetTLoReal(), expressed in units o data points. */ double GetRTLoHi() const { return rtLoHi; } //! Retrieves the inner rise time. /*! expressed in units o data points. */ double GetInnerRiseTime() const { return (InnerHiRT-InnerLoRT); } //! Retrieves the outer rise time. /*! expressed in units o data points. */ double GetOuterRiseTime() const { return (OuterHiRT-OuterLoRT); } //! Retrieves the full width at half-maximal amplitude ("half duration"). /*! \return The difference between GetT50RightReal() and GetT50LeftReal(), expressed in units of data points. */ double GetHalfDuration() const { return halfDuration; } //! Retrieves ratio of the maximal slopes during the rising and decaying phase. /*! \return The ratio of GetMaxRise() and GetMaxDecay(). */ double GetSlopeRatio() const { return slopeRatio; } //! Retrieves lower factor (e.g 20) for the rise time calculation. /*! \return lower factor value for rise time calculation expressed in percentage (e.g 20). */ int GetRTFactor() const { return RTFactor; } #ifdef WITH_PSLOPE //! Retrieves the value of the Slope /*! \return slope value in y-units/x-units. */ double GetPSlope() const { return PSlope; } #endif //! Retrieves the mode of the latency start cursor. /*! \return The current mode of the latency start cursor. */ stf::latency_mode GetLatencyStartMode() const { return latencyStartMode; } //! Retrieves the mode of the latency end cursor. /*! \return The current mode of the latency end cursor. */ stf::latency_mode GetLatencyEndMode() const { return latencyEndMode; } //! Retrieves the mode of the latency window. /*! \return The current mode of the latency window. */ stf::latency_window_mode GetLatencyWindowMode() const { return latencyWindowMode; } //! Retrieves the direction of peak calculations. /*! \return The current direction of peak calculations. */ stfnum::direction GetDirection() const { return direction; } #ifdef WITH_PSLOPE //! Retrieves the mode of the left PSlope cursor. /*! \return The current mode of the left PSlope cursor. */ stf::pslope_mode_beg GetPSlopeBegMode() const { return pslopeBegMode; } //! Retrieves the mode of the right PSlope cursor. /*! \return The current mode of the right PSlope cursor. */ stf::pslope_mode_end GetPSlopeEndMode() const { return pslopeEndMode; } #endif // WITH_PSLOPE //! Indicates whether to use the baseline as a reference for AP kinetics. /*! \return true if the baseline should be used, false if the threshold should be used. */ bool GetFromBase() const { return fromBase; } //! Indicates whether the measurement cursor (crosshair) value should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewCrosshair() const { return viewCrosshair; } //! Indicates whether the baseline value should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewBaseline() const { return viewBaseline; } //! Indicates whether the baseline's standard deviation should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewBaseSD() const { return viewBaseSD; } //! Indicates whether the threshold should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewThreshold() const { return viewThreshold; } //! Indicates whether the peak value (measured from zero) should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewPeakZero() const { return viewPeakzero; } //! Indicates whether the peak value (measured from baseline) should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewPeakBase() const { return viewPeakbase; } //! Indicates whether the peak value (measured from threshold) should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewPeakThreshold() const { return viewPeakthreshold; } //! Indicates whether the Lo to Hi% rise time should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewRTLoHi() const { return viewRTLoHi; } //! Indicates whether the inner rise time should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewInnerRiseTime() const { return viewInnerRiseTime; } //! Indicates whether the outer rise time should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewOuterRiseTime() const { return viewOuterRiseTime; } //! Indicates whether the half duration should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewT50() const { return viewT50; } //! Indicates whether the ratio of the maximal slopes during rise and decay should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewRD() const { return viewRD; } //! Indicates whether the maximal slope during the rising phase should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewSlopeRise() const { return viewSloperise; } //! Indicates whether the maximal slope during the decaying phase should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewSlopeDecay() const { return viewSlopedecay; } //! Indicates whether the latency should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewLatency() const { return viewLatency; } #ifdef WITH_PSLOPE //! Indicates whether the Slope should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewPSlope() const { return viewPSlope; } #endif //! Indicates whether two additional rows showing the positions of start and end cursors should be shown in the results table. /*! \return true if it should be shown, false otherwise. */ bool GetViewCursors() const { return viewCursors; } //! Returns the slope for threshold detection. /*! \return The slope value for threshold detection. */ double GetSlopeForThreshold() const { return slopeForThreshold; } //! Returns the current zoom settings for this channel (read-only). /*! \return The current zoom settings. */ const XZoom& GetXZoom() { return xzoom; } //! Returns the current zoom settings for this channel (read & write). /*! \return The current zoom settings. */ XZoom& GetXZoomW() { return xzoom; } //! Returns the current zoom settings for this channel (read-only). /*! \return The current zoom settings. */ const YZoom& GetYZoom(int ch) { return yzoom.at(ch); } //! Returns the current zoom settings for this channel (read & write). /*! \return The current zoom settings. */ YZoom& GetYZoomW(int ch) { return yzoom.at(ch); } //! Sets the position of the measurement cursor (crosshair). /*! \param value The index of the measurement cursor within the current section. */ void SetMeasCursor(int value); //! Sets whether the measurement cursor (crosshair) should be visible. /*! \param value is true if the ruler will be visible, false otherwirse.. */ void SetMeasRuler(bool value) { ShowRuler = value; } //! Retrieves whether the measurement cursor (crosshair) is visible. /*! \param true if the ruler is visible, false otherwirse.. */ bool GetMeasRuler() const { return ShowRuler;} //! Sets the method to compute the baseline. /*! \param value The new method to calculate the baseline. */ void SetBaselineMethod(stfnum::baseline_method value) { baselineMethod = value; } //! Sets the position of the left baseline cursor. /*! \param value The index of the left baseline cursor within the current section. */ void SetBaseBeg(int value); //! Sets the position of the right baseline cursor /*! \param value The index of the left baseline cursor within the current section. */ void SetBaseEnd(int value); //! Sets the position of the left peak cursor. /*! \param value The index of the left peak cursor within the current section. */ void SetPeakBeg(int value); //! Sets the position of the right peak cursor. /*! \param value The index of the right peak cursor within the current section. */ void SetPeakEnd(int value); //! Sets the position of the left fitting cursor. /*! \param value The index of the left fitting cursor within the current section. */ void SetFitBeg(int value); //! Sets the position of the right fitting cursor. /*! \param value The index of the right fitting cursor within the current section. */ void SetFitEnd(int value); //! Sets the position of the left latency cursor. /*! \param value The index of the left latency cursor within the current section. Note that by contrast * to the other cursors, this is a double because the latency cursor may be set to an interpolated * position between two data points. */ void SetLatencyBeg(double value); //! Sets the position of the right latency cursor. /*! \param value The index of the right latency cursor within the current section. Note that by contrast * to the other cursors, this is a double because the latency cursor may be set to an interpolated * position between two data points. */ void SetLatencyEnd(double value); //! Sets the latency. /*! \param value The latency, expressed in units of data points. */ void SetLatency(double value) { latency=value; } #ifdef WITH_PSLOPE //! Sets the position of the left PSlope cursor. /*! \param value The index of the left PSlope cursor within the current section. */ void SetPSlopeBeg(int value); //! Sets the position of the right PSlope cursor. /*! \param value The index of the right PSlope cursor within the current section. */ void SetPSlopeEnd(int value); //! Sets the PSlope. /*! \param value The slope, expressed in y-units/x-units. */ void SetPSlope(double value) { PSlope=value; } //! Set the position mode of the left PSlope cursor. /*! \param value The new mode of the left PSlope cursor. */ void SetPSlopeBegMode(stf::pslope_mode_beg value) { pslopeBegMode=value; } //! Set the position mode of the right PSlope cursor. /*! \param value The new mode of the right PSlope cursor. */ void SetPSlopeEndMode(stf::pslope_mode_end value) { pslopeEndMode=value; } //! Sets the number of points used for the distance from the first cursor. /*! \param value The number of points to be used. */ void SetDeltaT(int value) { DeltaT=value; } #endif // WITH_PSLOPE //! Sets the number of points used for averaging during peak calculation. /*! \param value The number of points to be used. */ void SetPM(int value) { pM=value; } //! Sets the lower value (e.g 20) to calculate the rise time. /*! \param value The lower percentage (e.g 20) to be used to c calculate the rise time. */ void SetRTFactor(int value); //! Sets the mode of the latency start cursor. /*! \param value The new mode of the latency start cursor. */ void SetLatencyStartMode(stf::latency_mode value) { latencyStartMode=value; } //! Sets the mode of the latency end cursor. /*! \param value The new mode of the latency end cursor. */ void SetLatencyEndMode(stf::latency_mode value) { latencyEndMode=value; } //! Sets the mode of the latency end cursor. /*! \param value The new mode of the latency end cursor.. */ void SetLatencyWindowMode(stf::latency_window_mode value) { latencyWindowMode=value; } //! Sets the mode of the latency start cursor. /*! \param value The new mode of the latency start cursor.. */ void SetLatencyStartMode(int value); //! Sets the mode of the latency end cursor. /*! \param value The new mode of the latency end cursor.. */ void SetLatencyEndMode(int value); //! Sets the mode of the latency end cursor. /*! \param value The new mode of the latency end cursor.. */ void SetLatencyWindowMode(int value); //! Sets the direction of peak calculations. /*! \param value The new direction of peak calculations. */ void SetDirection(stfnum::direction value) { direction=value; } //! Sets the reference for AP kinetics measurements. /*! \param frombase true if the baseline should be used, false if the threshold should be used. */ void SetFromBase(bool frombase) { fromBase = frombase; } //! Determines whether the measurement cursor (crosshair) value should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewCrosshair(bool value) { viewCrosshair=value; } //! Determines whether the baseline value should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewBaseline(bool value) { viewBaseline=value; } //! Determines whether the baseline's standard deviation should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewBaseSD(bool value) { viewBaseSD=value; } //! Determines whether the threshold should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewThreshold(bool value) { viewThreshold=value; } //! Determines whether the peak value (measured from zero) should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewPeakZero(bool value) { viewPeakzero=value; } //! Determines whether the peak value (measured from baseline) should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewPeakBase(bool value) { viewPeakbase=value; } //! Determines whether the peak value (measured from threshold) should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewPeakThreshold(bool value) { viewPeakthreshold=value; } //! Determines whether the Lo to Hi% rise time should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewRTLoHi(bool value) { viewRTLoHi=value; } //! Determines whether the inner rise time should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewInnerRiseTime(bool value) { viewInnerRiseTime=value; } //! Determines whether the outer rise time should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewOuterRiseTime(bool value) { viewOuterRiseTime=value; } //! Determines whether the half duration should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewT50(bool value) { viewT50=value; } //! Determines whether the ratio of the maximal slopes during rise and decay should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewRD(bool value) { viewRD=value; } //! Determines whether the maximal slope during the rising phase should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewSlopeRise(bool value) { viewSloperise=value; } //! Determines whether the maximal slope during the decaying phase should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewSlopeDecay(bool value) { viewSlopedecay=value; } //! Determines whether the latency should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewLatency(bool value) { viewLatency=value; } #ifdef WITH_PSLOPE //! Determines whether the slope should be shown in the results table. /*! \param value Set to true if it should be shown, false otherwise. */ void SetViewPSlope(bool value) { viewPSlope=value; } #endif //! Determines whether two additional rows showing the positions of start and end cursors should be shown in the results table. /*! \param value Set to true if they should be shown, false otherwise. */ void SetViewCursors(bool value) { viewCursors=value; } //! Sets the slope where the baseline should be set. /*! \param value The slope value where the baseline shoudl be set. */ void SetSlopeForThreshold(double value) { slopeForThreshold=value; } //! Put the current trace into a text table. stfnum::Table CurAsTable() const; //! Copies the cursor positions from another Recording to this Recording. /*! This will copy the crosshair, base, peak and fit cursors positions as * well as the number of points for peak averaging from another Recording * and correct the new values if they are out of range. The latency cursors * will not be copied. * \param c_Recording The Recording from which to copy the cursor positions. */ void CopyCursors(const wxStfDoc& c_Recording); //! Resize the Recording to a new number of channels. /*! Resizes both the channel and the global y units arrays. * \param c_n_channels The new number of channels. */ virtual void resize(std::size_t c_n_channels); //! Insert a Channel at a given position. /*! Will throw std::out_of_range if range check fails. * \param c_Channel The Channel to be inserted. * \param pos The position at which to insert the channel (0-based). */ virtual void InsertChannel(Channel& c_Channel, std::size_t pos); const stf::SectionAttributes& GetSectionAttributes(std::size_t nchannel, std::size_t nsection) const; const stf::SectionAttributes& GetCurrentSectionAttributes() const; stf::SectionAttributes& GetCurrentSectionAttributesW(); //! Deletes the current fit, sets isFitted to false; void DeleteFit(std::size_t nchannel, std::size_t nsection); //! Sets the best-fit parameters when a fit has been performed on this section. /*! \param bestFitP_ The best-fit parameters \param fitFunc_ The function used for fitting \param chisqr The sum of squared errors \param fitBeg Sampling point index where the fit starts \param fitEnd Sampling point index where the fit ends */ void SetIsFitted( std::size_t nchannel, std::size_t nsection, const Vector_double& bestFitP_, stfnum::storedFunc* fitFunc_, double chisqr, std::size_t fitBeg, std::size_t fitEnd ); //! Determines whether an integral has been calculated in this section. /*! \return true if an integral has been calculated, false otherwise. */ void SetIsIntegrated(std::size_t nchannel, std::size_t nsection, bool value, std::size_t begin, std::size_t end, const Vector_double& quad_p_); //! Erases all events. void ClearEvents(std::size_t nchannel, std::size_t nsection); void correctRangeR(int& value); void correctRangeR(std::size_t& value); bool LoadTDMS(const std::string& filename, Recording& ReturnData); DECLARE_EVENT_TABLE() }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/printout.h0000775000175000017500000000512714750344764014064 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file printout.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares wxStfPrintout. Derived from wxPrintout to handle printing of traces. */ #ifndef _PRINTOUT_H #define _PRINTOUT_H /*! \addtogroup wxstf * @{ */ //! Handles printing of traces. class wxStfPrintout : public wxPrintout { public: //! Constructor /*! \param title Printout title */ wxStfPrintout(const wxChar *title = _T("Printout")); //! Called by the framework when a page should be printed. /*! \param page The page number to be printed * \return false will cancel the print job. */ bool OnPrintPage(int page); //! Checks whether a page exists. /*! \param page The page number to be checked. * \return True if \e page exists. */ bool HasPage(int page); //! Called by the framework at the start of document printing. /*! \param startPage Page from which to start printing. * \param endPage Page at which to end printing. * \return false cancels the print job. */ bool OnBeginDocument(int startPage, int endPage); //! Retrieve information about the pages that will be printed. /*! \param minPage On return, a pointer to the minimal page number allowed. * \param maxPage On return, a pointer to the maximal page number allowed. * \param selPageFrom On return, a pointer to the minimal selected page number allowed. * \param selPageTo On return, a pointer to the maximal selected page number allowed. */ void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo); //! Prints the first (and only) page. void DrawPageOne(); private: void PrintHeader(wxDC* pDC,double scale); bool store_noGimmicks; wxStfDoc* Doc() const {return wxGetApp().GetActiveDoc();} }; /*@}*/ #endif stimfit-0.16.7/src/stimfit/gui/childframe.cpp0000775000175000017500000005400214750344764014625 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // frame.cpp // These are the top-level and child windows of the application. // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg #ifdef _STFDEBUG #include #endif // For compilers that support precompilation, includes "wx/wx.h". #include #include #include #include #include #include #include #include #include #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #if !wxUSE_DOC_VIEW_ARCHITECTURE #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h! #endif #if !wxUSE_MDI_ARCHITECTURE #error You must set wxUSE_MDI_ARCHITECTURE to 1 in setup.h! #endif #include "./app.h" #include "./doc.h" #include "./view.h" #include "./graph.h" #include "./table.h" #include "./printout.h" #include "./dlgs/smalldlgs.h" #include "./copygrid.h" #include "./parentframe.h" #ifdef _WINDOWS #include "./../../libstfio/atf/atflib.h" #include "./../../libstfio/igor/igorlib.h" #endif #include "./childframe.h" IMPLEMENT_CLASS(wxStfChildFrame, wxStfChildType) BEGIN_EVENT_TABLE(wxStfChildFrame, wxStfChildType) EVT_SPINCTRL( ID_SPINCTRLTRACES, wxStfChildFrame::OnSpinCtrlTraces ) EVT_COMBOBOX( ID_COMBOACTCHANNEL, wxStfChildFrame::OnComboActChannel ) EVT_COMBOBOX( ID_COMBOINACTCHANNEL, wxStfChildFrame::OnComboInactChannel ) EVT_CHECKBOX( ID_ZERO_INDEX, wxStfChildFrame::OnZeroIndex) EVT_CHECKBOX( ID_PLOTSELECTED, wxStfChildFrame::OnShowselected ) // workaround for status bar: EVT_MENU_HIGHLIGHT_ALL( wxStfChildFrame::OnMenuHighlight ) END_EVENT_TABLE() wxStfChildFrame::wxStfChildFrame(wxDocument* doc, wxView* view, wxStfParentType* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name) : wxStfChildType(doc,view,parent,id,title,pos,size,style,name), m_parent(parent), m_notebook(NULL) { m_mgr.SetManagedWindow(this); #ifndef __WXMAC__ m_mgr.SetFlags( wxAUI_MGR_ALLOW_FLOATING | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_VENETIAN_BLINDS_HINT | wxAUI_MGR_ALLOW_ACTIVE_PANE ); #else m_mgr.SetFlags( wxAUI_MGR_DEFAULT ); #endif } wxStfChildFrame::~wxStfChildFrame() { // deinitialize the frame manager m_mgr.UnInit(); } wxStfGrid* wxStfChildFrame::CreateTable() { // create the notebook off-window to avoid flicker //wxSize client_size = GetClientSize(); wxStfGrid* ctrl = new wxStfGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL | wxHSCROLL ); #ifndef __APPLE__ wxFont font( 10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL ); ctrl->SetDefaultCellFont(font); #endif ctrl->SetDefaultColSize(108); ctrl->SetColLabelSize(20); ctrl->SetDefaultCellAlignment(wxALIGN_RIGHT,wxALIGN_CENTRE); ctrl->CreateGrid(3,10); ctrl->EnableEditing(false); return ctrl; } wxAuiNotebook* wxStfChildFrame::CreateNotebook() { // create the notebook off-window to avoid flicker wxSize client_size = GetClientSize(); m_notebook_style = wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_CLOSE_ON_ACTIVE_TAB |/*wxAUI_NB_DEFAULT_STYLE | */ wxNO_BORDER; wxAuiNotebook* ctrl = new wxAuiNotebook( this, wxID_ANY, wxPoint(client_size.x, client_size.y), wxSize(200,200), m_notebook_style ); return ctrl; } wxPanel* wxStfChildFrame::CreateTraceCounter() { //wxSize client_size = GetClientSize(); wxPanel* ctrl = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize );// , wxSize(165,88) ); return ctrl; } wxPanel* wxStfChildFrame::CreateChannelCounter() { wxPanel* ctrl = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize ); //, wxSize(256,88) ); return ctrl; } void wxStfChildFrame::CreateMenuTraces(const std::size_t value) { sizemax = value; m_traceCounter = CreateTraceCounter(); // this is wxPanel wxBoxSizer* pTracesBoxSizer; // top-level Sizer pTracesBoxSizer = new wxBoxSizer(wxVERTICAL); wxGridSizer* TracesGridSizer; // top-level GridSizer TracesGridSizer = new wxGridSizer(3,1,0,0); // Grid for spin control wxFlexGridSizer* pSpinCtrlTraceSizer; pSpinCtrlTraceSizer = new wxFlexGridSizer(1,3,0,0); // 1 row, 3 columns for the SpinCtrl + text // 1) the wxSpinCtrl object trace_spinctrl = new wxSpinCtrl( m_traceCounter, ID_SPINCTRLTRACES, wxEmptyString, wxDefaultPosition, wxSize(64, wxDefaultCoord), wxSP_WRAP); // the "of n", where n is the number of traces // n is zero-based in zero-based check box is selected wxStaticText* pIndexText; pIndexText = new wxStaticText(m_traceCounter, wxID_ANY, wxT("Index: ")); pSize=new wxStaticText( m_traceCounter, wxID_ANY, wxEmptyString); wxString sizeStr; pSpinCtrlTraceSizer->Add( pIndexText, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1) ; pSpinCtrlTraceSizer->Add( trace_spinctrl, 0, wxALIGN_LEFT, 1) ; pSpinCtrlTraceSizer->Add( pSize, 0, wxALIGN_LEFT | wxALIGN_CENTER, 1) ; // 2) Show zero-based index? Read from Stimfit registry pZeroIndex = new wxCheckBox( m_traceCounter, ID_ZERO_INDEX, wxT("Zero-based index ") ); pZeroIndex->SetValue(wxGetApp().wxGetProfileInt(wxT("Settings"), wxT("Zeroindex"), 0)); // If true set the starting value to zero if (pZeroIndex->GetValue()){ sizemax--; trace_spinctrl->SetValue(0); trace_spinctrl->SetRange(0, (int)sizemax); } else { trace_spinctrl->SetValue(1); trace_spinctrl->SetRange(1, (int)sizemax); } // value argument is the number of traces sizeStr << wxT("(") << value << wxT(")"); // gives asserts on OS X: wxString::Format(wxT("%3d"), value); pSize->SetLabel(sizeStr); // Show selected pShowSelected = new wxCheckBox( m_traceCounter, ID_PLOTSELECTED, wxT("Show selected")); pShowSelected->SetValue(false); // Add everything to top-level GridSizer TracesGridSizer->Add(pSpinCtrlTraceSizer, 0, wxALIGN_LEFT | wxALIGN_TOP | wxALL, 3); TracesGridSizer->Add(pZeroIndex, 0, wxALIGN_LEFT | wxALIGN_BOTTOM | wxALL, 3); TracesGridSizer->Add(pShowSelected, 0, wxALIGN_LEFT | wxALIGN_BOTTOM | wxALL, 3); pTracesBoxSizer->Add(TracesGridSizer, 0, wxALIGN_CENTER | wxALL, 1); pTracesBoxSizer->SetSizeHints(m_traceCounter); m_traceCounter->SetSizer( TracesGridSizer ); m_traceCounter->Layout(); wxSize size = m_traceCounter->GetSize(); wxStfDoc* pDoc=(wxStfDoc*)GetDocument(); m_mgr.AddPane( m_traceCounter, wxAuiPaneInfo().Caption(wxT("Trace selection")).Fixed().BestSize(size.x, size.y). Position(pDoc->size()-1).CloseButton(false).Floatable().Dock().Top().Name(wxT("SelectionT")) ); m_table=CreateTable(); m_mgr.AddPane( m_table, wxAuiPaneInfo().Caption(wxT("Results")).Position(pDoc->size()). CloseButton(false).Floatable().Dock().Top().Name(wxT("Results")) ); m_mgr.Update(); Refresh(); } // Channel Selection childframe void wxStfChildFrame::CreateComboChannels(const wxArrayString& channelStrings) { m_channelCounter = CreateChannelCounter(); wxBoxSizer* pChannelsBoxSizer; // top-level Sizer pChannelsBoxSizer = new wxBoxSizer(wxVERTICAL); // Grid for ChannelCombo wxFlexGridSizer* ChannelCombos; ChannelCombos = new wxFlexGridSizer(2,2,4,0); // Active channel Combo wxStaticText* pActIndex = new wxStaticText( m_channelCounter, wxID_ANY, wxT("Active channel: ") ); pActChannel = new wxComboBox( m_channelCounter, ID_COMBOACTCHANNEL, wxT("0"), wxDefaultPosition, wxSize(120, wxDefaultCoord), channelStrings, wxCB_DROPDOWN | wxCB_READONLY ); // Inactive channel Combo wxStaticText* pInactIndex = new wxStaticText( m_channelCounter, wxID_ANY, wxT("Reference channel: ") ); pInactIndex->SetForegroundColour( *wxRED ); pInactChannel = new wxComboBox( m_channelCounter, ID_COMBOINACTCHANNEL, wxT("1"), wxDefaultPosition, wxSize(120,wxDefaultCoord), channelStrings, wxCB_DROPDOWN | wxCB_READONLY ); ChannelCombos->Add( pActIndex, 1, wxALIGN_CENTER_VERTICAL, 1); ChannelCombos->Add( pActChannel, 1); ChannelCombos->Add( pInactIndex,1, wxALIGN_CENTER_VERTICAL, 1); ChannelCombos->Add( pInactChannel, 1); wxBoxSizer *pShowChannelSizer; pShowChannelSizer = new wxBoxSizer(wxHORIZONTAL); // Show reference channel? Read from Stimfit registry pShowSecond = new wxCheckBox( m_channelCounter, ID_PLOTSELECTED, wxT("Show reference") ); pShowSecond->SetValue(wxGetApp().wxGetProfileInt(wxT("Settings"), wxT("ShowReference"),0)); pShowSecond->SetForegroundColour( *wxRED ); pShowAll = new wxCheckBox( m_channelCounter, ID_PLOTSELECTED, wxT("Show all ") ); pShowAll->SetValue(false); pShowChannelSizer->Add( pShowAll ); pShowChannelSizer->Add( pShowSecond ); pChannelsBoxSizer->Add(ChannelCombos, 0, wxALIGN_CENTER | wxALL, 3); pChannelsBoxSizer->Add(pShowChannelSizer, 0, wxALIGN_LEFT | wxALL, 3); pChannelsBoxSizer->SetSizeHints(m_channelCounter); m_channelCounter->SetSizer( pChannelsBoxSizer ); m_channelCounter->Layout(); wxSize size = m_channelCounter->GetSize(); m_mgr.AddPane( m_channelCounter, wxAuiPaneInfo().Caption(wxT("Channel selection")).Fixed().BestSize(size.x, size.y). Position(0).CloseButton(false).Floatable().Dock().Top().Name(wxT("SelectionC")) ); m_mgr.Update(); Refresh(); } // Trace selection childframe void wxStfChildFrame::SetSelected(std::size_t value) { wxString selStr; selStr << wxT("Show ") << wxString::Format(wxT("%3d"),(int)value) << wxT(" selected"); pShowSelected->SetLabel(selStr); } void wxStfChildFrame::SetChannels( std::size_t act, std::size_t inact ) { pActChannel->SetSelection( act ); pInactChannel->SetSelection( inact ); } std::size_t wxStfChildFrame::GetCurTrace() const { // if zero-based is True if ( pZeroIndex->GetValue() ) return trace_spinctrl->GetValue(); else return trace_spinctrl->GetValue()-1; } void wxStfChildFrame::SetCurTrace(std::size_t n) { // if zero-based is True if ( pZeroIndex->GetValue() ) trace_spinctrl->SetValue((int)n); else trace_spinctrl->SetValue((int)n+1); } void wxStfChildFrame::OnSpinCtrlTraces( wxSpinEvent& event ){ event.Skip(); wxStfView* pView=(wxStfView*)GetView(); wxStfDoc* pDoc=(wxStfDoc*)GetDocument(); if (pDoc == NULL || pView == NULL) { wxGetApp().ErrorMsg(wxT("Null pointer in wxStfChildFrame::OnSpinCtrlTraces()")); return; } if (pView->GetGraph() != NULL) { pView->GetGraph()->ChangeTrace(GetCurTrace()); pView->GetGraph()->Enable(); pView->GetGraph()->SetFocus(); } } void wxStfChildFrame::OnActivate(wxActivateEvent &event) { wxStfView* pView=(wxStfView*)GetView(); if (pView) pView->Activate(true); } void wxStfChildFrame::OnComboActChannel(wxCommandEvent& WXUNUSED(event)) { if ( pActChannel->GetCurrentSelection() == pInactChannel->GetCurrentSelection()) { // correct selection: for (int n_c=0;n_c<(int)pActChannel->GetCount();++n_c) { if (n_c!=pActChannel->GetCurrentSelection()) { pInactChannel->SetSelection(n_c); break; } } } UpdateChannels(); } void wxStfChildFrame::OnComboInactChannel(wxCommandEvent& WXUNUSED(event)) { if (pInactChannel->GetCurrentSelection()==pActChannel->GetCurrentSelection()) { // correct selection: for (int n_c=0;n_c<(int)pInactChannel->GetCount();++n_c) { if (n_c!=pInactChannel->GetCurrentSelection()) { pActChannel->SetSelection(n_c); break; } } } UpdateChannels(); } void wxStfChildFrame::UpdateChannels( ) { wxStfDoc* pDoc=(wxStfDoc*)GetDocument(); if ( pDoc != NULL && pDoc->size() > 1) { try { if (pActChannel->GetCurrentSelection() >= 0 || pActChannel->GetCurrentSelection() < (int)pDoc->size()) { pDoc->SetCurChIndex( pActChannel->GetCurrentSelection() ); if (pInactChannel->GetCurrentSelection() >= 0 || pInactChannel->GetCurrentSelection() < (int)pDoc->size()) { pDoc->SetSecChIndex( pInactChannel->GetCurrentSelection() ); } else { pDoc->SetCurChIndex(0); pDoc->SetSecChIndex(1); } } else { pDoc->SetCurChIndex(0); pDoc->SetSecChIndex(1); } } catch (const std::out_of_range& e) { wxString msg(wxT("Error while changing channels\nPlease close file\n")); msg += wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(msg); return; } // Update measurements: wxGetApp().OnPeakcalcexecMsg(); UpdateResults(); wxStfView* pView=(wxStfView*)GetView(); if ( pView == NULL ) { wxGetApp().ErrorMsg( wxT("View is zero in wxStfDoc::SwapChannels")); return; } if (pView->GetGraph() != NULL) { pView->GetGraph()->Refresh(); pView->GetGraph()->Enable(); pView->GetGraph()->SetFocus(); } } } void wxStfChildFrame::OnZeroIndex( wxCommandEvent& event) { event.Skip(); wxSpinCtrl* pTraceCtrl = (wxSpinCtrl*)FindWindow(ID_SPINCTRLTRACES); wxCheckBox* pZeroIndex = (wxCheckBox*)FindWindow(ID_ZERO_INDEX); if (pZeroIndex == NULL || pTraceCtrl == NULL){ wxGetApp().ErrorMsg(wxT("Null pointer in wxStfChildFrame::OnZeroIndex")); return; } // If Zero-index is ON (selected) if (pZeroIndex->GetValue()){ wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("Zeroindex"), 1); // write config if (pTraceCtrl->GetValue()==1){ sizemax--; pTraceCtrl->SetRange(0, sizemax); // first set new range pTraceCtrl->SetValue(pTraceCtrl->GetValue()-1); // now you can move one less } else if (pTraceCtrl->GetValue()==(int)sizemax){ sizemax--; pTraceCtrl->SetValue(pTraceCtrl->GetValue()-1); // move one less pTraceCtrl->SetRange(0, sizemax); // next set new range } else { sizemax--; pTraceCtrl->SetRange(0, sizemax); // first set new range pTraceCtrl->SetValue(pTraceCtrl->GetValue()-1); // now you can move one less } } // If Zero-index is OFF (unselected) else { wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("Zeroindex"), 0); if (pTraceCtrl->GetValue()==0){ sizemax++; pTraceCtrl->SetValue(pTraceCtrl->GetValue()+1); pTraceCtrl->SetRange(1, (int)sizemax); } else if (pTraceCtrl->GetValue()==(int)sizemax){ sizemax++; pTraceCtrl->SetRange(1, (int)sizemax); // first set new range pTraceCtrl->SetValue(pTraceCtrl->GetValue()+1); // now you can move one more } else { // now the order does not matter sizemax++; pTraceCtrl->SetRange(1, (int)sizemax); // first set new range pTraceCtrl->SetValue(pTraceCtrl->GetValue()+1); // now you can move one more } } //wxString sizeStr; //sizeStr << wxT("of ") << wxString::Format(wxT("%3d"),(int)sizemax); //pSize->SetLabel(sizeStr); } void wxStfChildFrame::OnShowselected(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=(wxStfView*)GetView(); if (pView != NULL && pView->GetGraph()!= NULL) { pView->GetGraph()->Refresh(); pView->GetGraph()->Enable(); pView->GetGraph()->SetFocus(); } } bool wxStfChildFrame::ShowSecond() { wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("ShowReference"), pShowSecond->IsChecked()); // write config return pShowSecond->IsChecked(); } void wxStfChildFrame::ActivateGraph() { wxStfView* pView=(wxStfView*)GetView(); // Set the focus somewhere else: if (m_traceCounter != NULL) m_traceCounter->SetFocus(); if (pView != NULL && pView->GetGraph()!= NULL) { pView->GetGraph()->Enable(); pView->GetGraph()->SetFocus(); } } void wxStfChildFrame::ShowTable(const stfnum::Table &table,const wxString& caption) { // Create and show notebook if necessary: if (m_notebook==NULL && !m_mgr.GetPane(m_notebook).IsOk()) { m_notebook=CreateNotebook(); m_mgr.AddPane( m_notebook, wxAuiPaneInfo().Caption(wxT("Analysis results")). Floatable().Dock().Left().Name( wxT("Notebook") ) ); } else { // Re-open notebook if it has been closed: if (!m_mgr.GetPane(m_notebook).IsShown()) { m_mgr.GetPane(m_notebook).Show(); } } wxStfGrid* pGrid = new wxStfGrid( m_notebook, wxID_ANY, wxPoint(0,20), wxDefaultSize ); wxStfTable* pTable(new wxStfTable(table)); pGrid->SetTable(pTable,true); // the grid will take care of the deletion pGrid->EnableEditing(false); pGrid->SetDefaultCellAlignment(wxALIGN_RIGHT,wxALIGN_CENTRE); for (std::size_t n_row=0; n_row<=table.nRows()+1; ++n_row) { pGrid->SetCellAlignment((int)n_row, 0, wxALIGN_LEFT, wxALIGN_CENTRE); } m_notebook->AddPage( pGrid, caption, true ); // "commit" all changes made to wxAuiManager m_mgr.Update(); wxStfView* pView=(wxStfView*)GetView(); if (pView != NULL && pView->GetGraph()!= NULL) { pView->GetGraph()->Enable(); pView->GetGraph()->SetFocus(); } } void wxStfChildFrame::UpdateResults() { wxStfDoc* pDoc=(wxStfDoc*)GetDocument(); stfnum::Table table(pDoc->CurResultsTable()); // Delete or append columns: if (m_table->GetNumberCols()<(int)table.nCols()) { m_table->AppendCols((int)table.nCols()-(int)m_table->GetNumberCols()); } else { if (m_table->GetNumberCols()>(int)table.nCols()) { m_table->DeleteCols(0,(int)m_table->GetNumberCols()-(int)table.nCols()); } } // Delete or append row: if (m_table->GetNumberRows()<(int)table.nRows()) { m_table->AppendRows((int)table.nRows()-(int)m_table->GetNumberRows()); } else { if (m_table->GetNumberRows()>(int)table.nRows()) { m_table->DeleteRows(0,(int)m_table->GetNumberRows()-(int)table.nRows()); } } for (std::size_t nRow=0;nRowSetRowLabelValue((int)nRow, stf::std2wx(table.GetRowLabel(nRow))); for (std::size_t nCol=0;nColSetColLabelValue((int)nCol, stf::std2wx(table.GetColLabel(nCol))); if (!table.IsEmpty(nRow,nCol)) { wxString entry; entry << table.at(nRow,nCol); m_table->SetCellValue((int)nRow,(int)nCol,entry); } else { m_table->SetCellValue((int)nRow,(int)nCol,wxT("n.a.")); } } } } void wxStfChildFrame::Saveperspective() { wxString perspective = m_mgr.SavePerspective(); // Save to wxConfig: wxGetApp().wxWriteProfileString(wxT("Settings"),wxT("Windows"),perspective); #ifdef _STFDEBUG wxFile persp(wxT("perspective.txt"), wxFile::write); persp.Write(perspective); persp.Close(); #endif } void wxStfChildFrame::Loadperspective() { wxString perspective = wxGetApp().wxGetProfileString(wxT("Settings"),wxT("Windows"),wxT("")); if (perspective!=wxT("")) { m_mgr.LoadPerspective(perspective); } else { wxGetApp().ErrorMsg(wxT("Couldn't find saved windows settings")); } } void wxStfChildFrame::Restoreperspective() { m_mgr.LoadPerspective(defaultPersp); m_mgr.Update(); } void wxStfChildFrame::OnMenuHighlight(wxMenuEvent& event) { if (this->GetMenuBar()) { wxMenuItem *item = this->GetMenuBar()->FindItem(event.GetId()); if(item) { wxLogStatus(item->GetHelp()); } } event.Skip(); } wxMenuBar* wxStfChildFrame::GetMenuBar() const { if (wxStfChildType::GetMenuBar()) { return wxStfChildType::GetMenuBar(); } else { return m_parent->GetMenuBar(); } } #if wxUSE_DRAG_AND_DROP bool wxStfFileDrop::OnDropFiles(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxArrayString& filenames) { int nFiles=(int)filenames.GetCount(); if (nFiles>0) { return wxGetApp().OpenFileSeries(filenames); } else { return false; } } #endif stimfit-0.16.7/src/stimfit/gui/view.cpp0000775000175000017500000001103214750344764013475 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // view.cpp // Derived from wxView to satisfy the doc/view architecture. // Doesn't do a lot in stimfit. // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/filename.h" #if !wxUSE_DOC_VIEW_ARCHITECTURE #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h! #endif #include "./app.h" #include "./doc.h" #include "./view.h" #include "./parentframe.h" #include "./childframe.h" #include "./graph.h" #include "./dlgs/cursorsdlg.h" IMPLEMENT_DYNAMIC_CLASS(wxStfView, wxView) BEGIN_EVENT_TABLE(wxStfView, wxView) END_EVENT_TABLE() wxStfView::wxStfView() : graph((wxStfGraph *) NULL), childFrame((wxStfChildFrame *) NULL) { } // What to do when a view is created. Creates actual // windows for displaying the view. bool wxStfView::OnCreate(wxDocument *doc, long WXUNUSED(flags) ) { childFrame = wxGetApp().CreateChildFrame(doc, this); if (childFrame==NULL) { return false; } // extract file name: wxFileName fn(doc->GetFilename()); childFrame->SetTitle(fn.GetName()); graph = wxGetApp().GetMainFrame()->CreateGraph(this, childFrame); if (graph==NULL) { return false; } childFrame->GetMgr()->AddPane( graph, wxAuiPaneInfo().Caption(wxT("Traces")).Name(wxT("Traces")).CaptionVisible(true). CloseButton(false).Centre().PaneBorder(true) ); childFrame->GetMgr()->Update(); // childFrame->ActivateGraph(); #if defined(__X__) || defined(__WXMAC__) // X seems to require a forced resize // childFrame->SetClientSize(800,600); #endif //#ifndef __WXMAC__ childFrame->Show(true); //#endif Activate(true); return true; } wxStfDoc* wxStfView::Doc() { return (wxStfDoc*)GetDocument(); } wxStfDoc* wxStfView::DocC() const { return (wxStfDoc*)GetDocument(); } // Sneakily gets used for default print/preview // as well as drawing on the screen. void wxStfView::OnDraw(wxDC *WXUNUSED(pDC)) { } void wxStfView::OnUpdate(wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint)) { if (graph) { graph->Refresh(); } } // Clean up windows used for displaying the view. bool wxStfView::OnClose(bool deleteWindow) { if ( !GetDocument()->Close() ) return false; Activate(false); if ( deleteWindow ) wxDELETE(childFrame); SetFrame(NULL); return true; } void wxStfView::OnActivateView(bool activate, wxView *activeView, wxView *deactiveView) { //this function will be called whenever the view is activated if (activeView!=NULL) { wxStfDoc *pDoc = ((wxStfView*)activeView)->Doc(); if (pDoc) { // Update menu checks: // pDoc->UpdateMenuCheckmarks(); if (wxGetApp().GetMainFrame()!=NULL) wxGetApp().GetMainFrame()->SetSingleChannel(pDoc->size()<2); pDoc->UpdateSelectedButton(); if (wxGetApp().GetCursorsDialog()!=NULL && wxGetApp().GetCursorsDialog()->IsShown()) { wxGetApp().GetCursorsDialog()->SetActiveDoc(Doc()); try { wxGetApp().GetCursorsDialog()->UpdateCursors(); } catch (const std::runtime_error& e) { wxGetApp().ExceptMsg(wxString( e.what(), wxConvLocal )); } } } #ifdef __WXGTK__ wxStfGraph *pGraph = ((wxStfView*)activeView)->GetGraph(); if (pGraph) pGraph->SetFocus(); #endif } #ifdef __WXMAC__ wxGetApp().SetMRActiveDoc(Doc()); #endif wxView::OnActivateView(activate,activeView,deactiveView); } stimfit-0.16.7/src/stimfit/gui/parentframe.cpp0000775000175000017500000015040614752207205015026 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // parentframe.cpp // These are the top-level and child windows of the application. // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg #ifdef _STFDEBUG #include #endif // For compilers that support precompilation, includes "wx/wx.h". #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #if !wxUSE_DOC_VIEW_ARCHITECTURE #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h! #endif #if !wxUSE_MDI_ARCHITECTURE #error You must set wxUSE_MDI_ARCHITECTURE to 1 in setup.h! #endif #include "stfconf.h" #include "./app.h" #include "./doc.h" #include "./view.h" #include "./graph.h" #include "./table.h" #include "./printout.h" #include "./dlgs/convertdlg.h" #include "./dlgs/smalldlgs.h" #include "./copygrid.h" #include "./../../libstfio/atf/atflib.h" #if defined(WITH_BIOSIG) #include "./../../libstfio/biosig/biosiglib.h" #endif #include "./../../libstfio/igor/igorlib.h" #include "./childframe.h" #include "./parentframe.h" #include "./../../libstfnum/levmar/levmar.h" #include "./../res/16-em-down.xpm" #include "./../res/16-em-open.xpm" #include "./../res/accept.xpm" #include "./../res/arrow_down.xpm" #include "./../res/arrow_left.xpm" #include "./../res/arrow_out.xpm" #include "./../res/arrow_right.xpm" #include "./../res/arrow_up.xpm" #include "./../res/camera.xpm" #include "./../res/camera_ps.xpm" #include "./../res/ch1.xpm" #include "./../res/ch2.xpm" #include "./../res/cursor.xpm" #include "./../res/event.xpm" #include "./../res/fit.xpm" #include "./../res/fit_lim.xpm" #include "./../res/latency_lim.xpm" #include "./../res/resultset_first.xpm" #include "./../res/resultset_last.xpm" #include "./../res/resultset_next.xpm" #include "./../res/resultset_previous.xpm" #include "./../res/sum_new.xpm" #include "./../res/sum_new_aligned.xpm" #include "./../res/table.xpm" #include "./../res/zoom.xpm" #include "./../res/zoom_in.xpm" #include "./../res/zoom_out.xpm" #ifdef WITH_PSLOPE #include "./../res/slope.xpm" #endif #ifndef wxS_DIR_DEFAULT #define wxS_DIR_DEFAULT 0777 #endif IMPLEMENT_CLASS(wxStfParentFrame, wxStfParentType) BEGIN_EVENT_TABLE(wxStfParentFrame, wxStfParentType) EVT_MENU(wxID_HELP, wxStfParentFrame::OnHelp) EVT_MENU(ID_UPDATE, wxStfParentFrame::OnCheckUpdate) EVT_MENU(wxID_ABOUT, wxStfParentFrame::OnAbout) EVT_TOOL(ID_TOOL_SELECT,wxStfParentFrame::OnToggleSelect) EVT_TOOL(ID_TOOL_FIRST, wxStfParentFrame::OnToolFirst) EVT_TOOL(ID_TOOL_NEXT, wxStfParentFrame::OnToolNext) EVT_TOOL(ID_TOOL_PREVIOUS, wxStfParentFrame::OnToolPrevious) EVT_TOOL(ID_TOOL_LAST, wxStfParentFrame::OnToolLast) EVT_TOOL(ID_TOOL_XENL, wxStfParentFrame::OnToolXenl) EVT_TOOL(ID_TOOL_XSHRINK, wxStfParentFrame::OnToolXshrink) EVT_TOOL(ID_TOOL_YENL, wxStfParentFrame::OnToolYenl) EVT_TOOL(ID_TOOL_YSHRINK, wxStfParentFrame::OnToolYshrink) EVT_TOOL(ID_TOOL_UP, wxStfParentFrame::OnToolUp) EVT_TOOL(ID_TOOL_DOWN, wxStfParentFrame::OnToolDown) EVT_TOOL(ID_TOOL_FIT, wxStfParentFrame::OnToolFit) EVT_TOOL(ID_TOOL_LEFT, wxStfParentFrame::OnToolLeft) EVT_TOOL(ID_TOOL_RIGHT, wxStfParentFrame::OnToolRight) EVT_TOOL(ID_TOOL_SNAPSHOT_WMF, wxStfParentFrame::OnToolSnapshotwmf) EVT_TOOL(ID_TOOL_CH1, wxStfParentFrame::OnToolCh1) EVT_TOOL(ID_TOOL_CH2, wxStfParentFrame::OnToolCh2) EVT_TOOL(ID_TOOL_MEASURE, wxStfParentFrame::OnToolMeasure) EVT_TOOL(ID_TOOL_PEAK,wxStfParentFrame::OnToolPeak) EVT_TOOL(ID_TOOL_BASE,wxStfParentFrame::OnToolBase) EVT_TOOL(ID_TOOL_DECAY,wxStfParentFrame::OnToolDecay) #ifdef WITH_PSLOPE EVT_TOOL(ID_TOOL_PSLOPE,wxStfParentFrame::OnToolPSlope) #endif EVT_TOOL(ID_TOOL_LATENCY,wxStfParentFrame::OnToolLatency) EVT_TOOL(ID_TOOL_ZOOM,wxStfParentFrame::OnToolZoom) EVT_TOOL(ID_TOOL_EVENT,wxStfParentFrame::OnToolEvent) EVT_TOOL(ID_TOOL_FITDECAY, wxStfParentFrame::OnToolFitdecay) EVT_MENU(ID_CONVERT, wxStfParentFrame::OnConvert) EVT_MENU(ID_AVERAGE, wxStfParentFrame::OnAverage) EVT_MENU(ID_ALIGNEDAVERAGE, wxStfParentFrame::OnAlignedAverage) EVT_MENU( ID_VIEW_RESULTS, wxStfParentFrame::OnViewResults) EVT_MENU( ID_CH2BASE, wxStfParentFrame::OnCh2base ) EVT_MENU( ID_CH2POS, wxStfParentFrame::OnCh2pos ) EVT_MENU( ID_CH2ZOOM, wxStfParentFrame::OnCh2zoom ) EVT_MENU( ID_CH2BASEZOOM, wxStfParentFrame::OnCh2basezoom ) EVT_MENU( ID_SCALE, wxStfParentFrame::OnScale ) EVT_MENU( ID_PRINT_PRINT, wxStfParentFrame::OnPrint) EVT_MENU( ID_MPL, wxStfParentFrame::OnMpl) EVT_MENU( ID_MPL_SPECTRUM,wxStfParentFrame::OnMplSpectrum) EVT_MENU( ID_PRINT_PAGE_SETUP, wxStfParentFrame::OnPageSetup) EVT_MENU( ID_SAVEPERSPECTIVE, wxStfParentFrame::OnSaveperspective ) EVT_MENU( ID_LOADPERSPECTIVE, wxStfParentFrame::OnLoadperspective ) EVT_MENU( ID_RESTOREPERSPECTIVE, wxStfParentFrame::OnRestoreperspective ) #ifdef WITH_PYTHON EVT_MENU( ID_VIEW_SHELL, wxStfParentFrame::OnViewshell ) #endif #if 0 EVT_MENU( ID_LATENCYSTART_MAXSLOPE, wxStfParentFrame::OnLStartMaxslope ) EVT_MENU( ID_LATENCYSTART_HALFRISE, wxStfParentFrame::OnLStartHalfrise ) EVT_MENU( ID_LATENCYSTART_PEAK, wxStfParentFrame::OnLStartPeak ) EVT_MENU( ID_LATENCYSTART_MANUAL, wxStfParentFrame::OnLStartManual ) EVT_MENU( ID_LATENCYEND_FOOT, wxStfParentFrame::OnLEndFoot ) EVT_MENU( ID_LATENCYEND_MAXSLOPE, wxStfParentFrame::OnLEndMaxslope ) EVT_MENU( ID_LATENCYEND_PEAK, wxStfParentFrame::OnLEndPeak ) EVT_MENU( ID_LATENCYEND_HALFRISE, wxStfParentFrame::OnLEndHalfrise ) EVT_MENU( ID_LATENCYEND_MANUAL, wxStfParentFrame::OnLEndManual ) EVT_MENU( ID_LATENCYWINDOW, wxStfParentFrame::OnLWindow ) #endif END_EVENT_TABLE() wxStfParentFrame::wxStfParentFrame(wxDocManager *manager, wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size, long type): wxStfParentType(manager, frame, wxID_ANY, title, pos, size, type, _T("myFrame")), mpl_figno(0) { // ::wxInitAllImageHandlers(); m_mgr.SetManagedWindow(this); #ifndef __WXMAC__ m_mgr.SetFlags( wxAUI_MGR_ALLOW_FLOATING | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_VENETIAN_BLINDS_HINT | wxAUI_MGR_ALLOW_ACTIVE_PANE ); #else m_mgr.SetFlags( wxAUI_MGR_DEFAULT ); #endif #if wxUSE_DRAG_AND_DROP m_drop = new wxStfFileDrop; // obviously gets deleted when the frame is destructed SetDropTarget(m_drop); #endif m_printData.reset(new wxPrintData); // initial paper size // m_printData->SetQuality(wxPRINT_QUALITY_HIGH); // int ppi = m_printData->GetQuality(); m_printData->SetPaperId(wxPAPER_A4); // initial orientation m_printData->SetOrientation(wxLANDSCAPE); m_pageSetupData.reset(new wxPageSetupDialogData); // copy over initial paper size from print record m_pageSetupData->SetPrintData(*m_printData); // Set some initial page margins in mm. m_pageSetupData->SetMarginTopLeft(wxPoint(15, 15)); m_pageSetupData->SetMarginBottomRight(wxPoint(15, 15)); // create some toolbars wxStfToolBar* tb1 = CreateStdTb(); tb1->Realize(); m_scaleToolBar=CreateScaleTb(); m_scaleToolBar->Realize(); wxStfToolBar* tb4=CreateEditTb(); tb4->Realize(); m_cursorToolBar=CreateCursorTb(); m_cursorToolBar->Realize(); // add the toolbars to the manager m_mgr.AddPane( tb1, wxAuiPaneInfo().Name(wxT("tb1")).Caption(wxT("Std Toolbar")).ToolbarPane().Resizable(false). Position(0).Top().Gripper().RightDockable(false) ); #ifdef __WXMAC__ int xpos = 64, ypos = 32; #endif m_mgr.AddPane( m_cursorToolBar, wxAuiPaneInfo().Name(wxT("tb2")).Caption(wxT("Edit Toolbar")). ToolbarPane().Resizable(false). #ifndef __WXMAC__ Position(1).Top().Gripper().RightDockable(false) ); #else Dockable(false).Float().FloatingPosition(xpos, ypos) ); xpos += m_cursorToolBar->GetSize().GetWidth()+8; #endif m_mgr.AddPane( tb4, wxAuiPaneInfo().Name(wxT("tb4")).Caption(wxT("Analysis Toolbar")). ToolbarPane().Resizable(false). #ifndef __WXMAC__ Position(2).Top().Gripper().RightDockable(false) ); #else Dockable(false).Float().FloatingPosition(xpos,ypos) ); xpos += tb4->GetSize().GetWidth()+8; #endif m_mgr.AddPane( m_scaleToolBar, wxAuiPaneInfo().Name(wxT("m_scaleToolBar")).Caption(wxT("Navigation Toolbar")). ToolbarPane().Resizable(false). #ifndef __WXMAC__ Position(3).Top().Gripper().RightDockable(false) ); #else Dockable(false).Float().FloatingPosition(xpos,ypos) ); #endif SetMouseQual( stf::measure_cursor ); #ifdef WITH_PYTHON python_code2 << wxT("import sys\n") << wxT("sys.path.append('.')\n") << wxT("sys.path.append('/usr/local/lib/stimfit')\n") #ifdef IPYTHON << wxT("import embedded_ipython\n") #else << wxT("import embedded_stf\n") #endif << wxT("\n") << wxT("def makeWindow(parent, figsize=(8,6)):\n") #ifdef IPYTHON << wxT(" win = embedded_ipython.MyPanel(parent)\n") #else << wxT(" win = embedded_stf.MyPanel(parent)\n") #endif << wxT(" return win\n") << wxT("\n") #if PY_MAJOR_VERSION < 3 << wxT("import embedded_mpl\n") << wxT("def plotWindowMpl(parent, figsize=(8,6)):\n") << wxT(" win = embedded_mpl.MplPanel(parent, figsize)\n") << wxT(" win.plot_screen()\n") << wxT(" return win\n") << wxT("\n") << wxT("def spectrumWindowMpl(parent, figsize=(8,6)):\n") << wxT(" win = embedded_mpl.MplPanel(parent, figsize)\n") << wxT(" win.plot_spectrum()\n") << wxT(" return win\n") << wxT("\n") << wxT("def makeWindowMpl(parent, figsize=(8,6)):\n") << wxT(" win = embedded_mpl.MplPanel(parent, figsize)\n") << wxT(" return win\n") #endif ; /* The window remains open after the main application has been closed; deactivated for the time being. * RedirectStdio(); */ bool show = wxGetApp().wxGetProfileInt(wxT("Settings"),wxT("ViewShell"), 1); wxWindow* pPython = MakePythonWindow("makeWindow", "pythonShell", "Python Shell", show, #ifdef __WXMAC__ true #else false, false, GetClientSize().GetWidth(), GetClientSize().GetHeight()/5 #endif ).cppWindow; if ( pPython == 0 ) { wxGetApp().ErrorMsg(wxT("Can't create a window for the python shell\nPointer is zero")); } #ifdef _STFDEBUG #ifdef _WINDOWS wxGetApp().InfoMsg( python_code2 ); #else std::cout << "python startup script:\n" << std::string( python_code2.char_str() ); #endif // _WINDOWS #endif // _STFDEBUG #else // WITH_PYTHON m_mgr.Update(); #endif // WITH_PYTHON wxStatusBar* pStatusBar = new wxStatusBar(this, wxID_ANY, wxST_SIZEGRIP); SetStatusBar(pStatusBar); //int widths[] = { 60, 60, -1 }; //pStatusBar->SetFieldWidths(WXSIZEOF(widths), widths); //pStatusBar->SetStatusText(wxT("Test"), 0); } wxStfParentFrame::~wxStfParentFrame() { // deinitialize the frame manager #ifdef WITH_PYTHON // write visibility of the shell to config: bool shell_state = m_mgr.GetPane(wxT("pythonShell")).IsShown(); wxGetApp().wxWriteProfileInt( wxT("Settings"),wxT("ViewShell"), int(shell_state) ); #endif m_mgr.UnInit(); } wxStfToolBar* wxStfParentFrame::CreateStdTb() { wxStfToolBar* tb1=new wxStfToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE ); tb1->SetToolBitmapSize(wxSize(20,20)); tb1->AddTool( wxID_OPEN, wxT("Open"), wxArtProvider::GetBitmap( wxART_FILE_OPEN, wxART_TOOLBAR, wxSize(16,16) ), wxT("Open file"), wxITEM_NORMAL ); tb1->AddTool( wxID_SAVEAS, wxT("Save"), wxArtProvider::GetBitmap( wxART_FILE_SAVE_AS, wxART_TOOLBAR, wxSize(16,16) ), wxT("Save traces"), wxITEM_NORMAL ); tb1->AddTool( ID_PRINT_PRINT, wxT("Print"), wxArtProvider::GetBitmap( wxART_PRINT, wxART_TOOLBAR, wxSize(16,16) ), wxT("Print traces"), wxITEM_NORMAL ); return tb1; } wxStfToolBar* wxStfParentFrame::CreateScaleTb() { wxStfToolBar* scaleToolBar = new wxStfToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE ); scaleToolBar->SetToolBitmapSize(wxSize(20,20)); scaleToolBar->AddTool( ID_TOOL_FIRST, wxT("First"), wxBitmap(resultset_first), wxT("Go to first trace"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_PREVIOUS, wxT("Prev."), wxBitmap(resultset_previous), wxT("Go to previous trace (left cursor)"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_NEXT, wxT("Next"), wxBitmap(resultset_next), wxT("Go to next trace (right cursor)"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_LAST, wxT("Last"), wxBitmap(resultset_last), wxT("Go to last trace"), wxITEM_NORMAL ); scaleToolBar->AddSeparator(); scaleToolBar->AddTool( ID_TOOL_LEFT, wxT("Left"), wxBitmap(arrow_left), wxT("Move traces left (CTRL+left cursor)"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_RIGHT, wxT("Right"), wxBitmap(arrow_right), wxT("Move traces right (CTRL+right cursor)"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_FIT, wxT("Fit"), wxBitmap(arrow_out), wxT("Fit traces to window (\"F\")"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_UP, wxT("Up"), wxBitmap(arrow_up), wxT("Move traces up (up cursor)"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_DOWN, wxT("Down"), wxBitmap(arrow_down), wxT("Move traces down (down cursor)"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_XENL, wxT("Zoom X"), wxBitmap(zoom_in), wxT("Enlarge x-scale (CTRL + \"+\")"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_XSHRINK, wxT("Shrink X"), wxBitmap(zoom_out), wxT("Shrink x-scale (CTRL + \"-\")"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_YENL, wxT("Zoom Y"), wxBitmap(zoom_in), wxT("Enlarge y-scale (\"+\")"), wxITEM_NORMAL ); scaleToolBar->AddTool( ID_TOOL_YSHRINK, wxT("Shrink Y"), wxBitmap(zoom_out), wxT("Shrink y-scale (\"-\")"), wxITEM_NORMAL ); scaleToolBar->AddSeparator(); scaleToolBar->AddTool( ID_TOOL_CH1, wxT("Ch 1"), wxBitmap(ch_), wxT("Scaling applies to active (black) channel (\"1\")"), wxITEM_CHECK ); scaleToolBar->AddTool( ID_TOOL_CH2, wxT("Ch 2"), wxBitmap(ch2_), wxT("Scaling applies to reference (red) channel (\"2\")"), wxITEM_CHECK ); return scaleToolBar; } wxStfToolBar* wxStfParentFrame::CreateEditTb() { wxStfToolBar* tb4= new wxStfToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE ); tb4->SetToolBitmapSize(wxSize(20,20)); tb4->AddTool( ID_AVERAGE, wxT("Mean"), wxBitmap(sum_new), wxT("Average of selected traces"), wxITEM_NORMAL ); tb4->AddTool( ID_ALIGNEDAVERAGE, wxT("Aligned"), wxBitmap(sum_new_aligned), wxT("Aligned average of selected traces"), wxITEM_NORMAL ); tb4->AddTool( ID_TOOL_FITDECAY, wxT("Fit"), wxBitmap(fit),//chart_line), wxT("Fit function to data"), wxITEM_NORMAL ); tb4->AddTool( ID_VIEWTABLE, wxT("Table"), wxBitmap(table), wxT("View current trace as a table"), wxITEM_NORMAL ); return tb4; } wxStfToolBar* wxStfParentFrame::CreateCursorTb() { wxStfToolBar* cursorToolBar = new wxStfToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_DEFAULT_STYLE ); cursorToolBar->SetToolBitmapSize(wxSize(20,20)); cursorToolBar->AddTool( ID_TOOL_SELECT, wxT("Select"), wxBitmap( acceptbmp ), wxT("Select or unselect this trace (\"S\" / \"R\")"), wxITEM_CHECK ); // cursorToolBar->AddTool( ID_TOOL_REMOVE, // wxT("Unselect"), // wxBitmap( bin ), // wxT("Unselect this trace (\"R\")"), // wxITEM_NORMAL ); cursorToolBar->AddSeparator(); cursorToolBar->AddTool( ID_MPL, wxT("Snapshot"), wxBitmap(camera), wxT("Create snapshot with matplotlib"), wxITEM_NORMAL ); cursorToolBar->AddTool( ID_TOOL_SNAPSHOT_WMF, wxT("WMF Snapshot"), wxBitmap(camera_ps), wxT("Copy vectorized image to clipboard"), wxITEM_NORMAL ); cursorToolBar->AddSeparator(); cursorToolBar->AddTool( ID_TOOL_MEASURE, _T("Measure"), wxBitmap(cursor), wxT("Mouse selects measurement (crosshair) cursor (\"M\")"), wxITEM_CHECK ); cursorToolBar->AddTool( ID_TOOL_PEAK, _T("Peak"), wxBitmap(___em_open), wxT("Mouse selects peak cursors (\"P\")"), wxITEM_CHECK ); cursorToolBar->AddTool( ID_TOOL_BASE, _T("Base"), wxBitmap(___em_down), wxT("Mouse selects base cursors (\"B\")"), wxITEM_CHECK ); cursorToolBar->AddTool( ID_TOOL_DECAY, _T("Fit"), wxBitmap(fit_lim),//chart_curve), wxT("Mouse selects fit cursors (\"D\")"), wxITEM_CHECK ); cursorToolBar->AddTool( ID_TOOL_LATENCY, _T("Latency"), wxBitmap(latency_lim),//chart_curve), wxT("Mouse selects latency cursors (\"L\")"), wxITEM_CHECK ); #ifdef WITH_PSLOPE cursorToolBar->AddTool( ID_TOOL_PSLOPE, _T("Slope"), wxBitmap(slope), wxT("Mouse selects slope cursors (\"O\")"), wxITEM_CHECK ); #endif cursorToolBar->AddTool( ID_TOOL_ZOOM, _T("Zoom"), wxBitmap(zoom), wxT("Draw a zoom window with left mouse button (\"Z\")"), wxITEM_CHECK ); cursorToolBar->AddTool( ID_TOOL_EVENT, _T("Events"), wxBitmap(event), wxT( "Add, erase or extract events manually with right mouse button (\"E\")" ), wxITEM_CHECK ); return cursorToolBar; } #if 0 #if defined(WITH_BIOSIG) #define CREDIT_BIOSIG "Biosig import using libbiosig http://biosig.sf.net\n\n" #else #define CREDIT_BIOSIG "" #endif #endif void wxStfParentFrame::OnAbout(wxCommandEvent& WXUNUSED(event) ) { wxAboutDialogInfo info; info.SetName(wxT("Stimfit")); info.SetVersion(wxString(PACKAGE_VERSION, wxConvLocal)); info.SetWebSite(wxT("http://www.stimfit.org")); wxString about = wxString(wxT("Credits:\n\nOriginal idea (Stimfit for DOS):\n\ Peter Jonas, Physiology Department, University of Freiburg\n\n\ Fourier transform:\nFFTW, http://www.fftw.org\n\n\ Levenberg-Marquardt non-linear regression, version ") + wxString(wxT(LM_VERSION)) + wxT("\n\ Manolis Lourakis, http://www.ics.forth.gr/~lourakis/levmar/ \n\n")) + #if defined(WITH_BIOSIG) wxString( wxT("BioSig import using libbiosig\n") ) + //+ wxString( wxT("version ") + wxT(BIOSIG_VERSION ) ) + wxString( wxT("http://biosig.sf.net\n\n") ) + #endif wxString(wxT("Documentation:\n\ Jose Guzman\n\n\ Event detection algorithms:\n\ Jonas, P., Major, G. & Sakmann B. (1993) J Physiol 472:615-63\n\ Clements, J. D. & Bekkers, J. M. (1997) Biophys J 73:220-229\n\ Pernía-Andrade, A.J., et al., (2012) Biophys J 103:1429-39.\n\n\ Thanks to Bill Anderson (www.winltp.com) for helpful suggestions")); info.SetDescription(about); info.SetCopyright(wxT("(C) 2001-2015 Christoph Schmidt-Hieber \n\ Christoph Schmidt-Hieber, University College London\n\ Published under the GNU general public license (http://www.gnu.org/licenses/gpl.html)")); wxAboutBox(info); } void wxStfParentFrame::OnHelp(wxCommandEvent& WXUNUSED(event) ) { wxLaunchDefaultBrowser( wxT("http://www.stimfit.org/doc/sphinx/index.html") ); } std::vector ParseVersionString( const wxString& VersionString ) { std::vector VersionInt(5); const char pt = '.'; // Major version: long major=0; wxString sMajor = VersionString.BeforeFirst(pt); if ( sMajor.length() == VersionString.length() ) { major = 0; } else { sMajor.ToLong( &major ); } VersionInt[0] = major; // Minor version: long minor=0; wxString sMinor1 = VersionString.AfterFirst(pt); if ( sMinor1.empty() ) { minor = 0; } else { wxString sMinor = sMinor1.BeforeFirst(pt); if ( sMinor1.length() == sMinor.length() ) { minor = 0; } else { sMinor.ToLong( &minor ); } } VersionInt[1] = minor; // Build version: long build=0; wxString sBuild = VersionString.AfterLast(pt); if ( sBuild.empty() ) { build = 0; } else { sBuild.ToLong( &build ); } VersionInt[2] = build; return VersionInt; } bool CompVersion( const std::vector& version ) { // Get current version: wxString currentString(PACKAGE_VERSION, wxConvLocal); std::vector current = ParseVersionString(currentString); if (version[0] > current[0]) { return true; } else { if (version[0] == current[0]) { if (version[1] > current[1]) { return true; } else { if (version[1] == current[1]) { if (version[2] > current[2]) { return true; } else { return false; } } else { // version[0] == current[0] && version[1] < current[1] return false; } } } else { // version[0] < current[0] return false; } } } void wxStfParentFrame::CheckUpdate( wxProgressDialog* progDlg ) const { #if defined (__MINGW32__) wxString address(wxT("/latest_mingw")); #elif defined (_WINDOWS) wxString address(wxT("/latest_windows")); #elif defined (__APPLE__) wxString address(wxT("/latest_mac")); #else wxString address(wxT("/latest_linux")); #endif wxHTTP http; http.SetHeader( wxT("Accept") , wxT("text/*") ); http.SetHeader( wxT("User-Agent"), wxT("Mozilla") ); http.SetTimeout( 1 ); // seconds // Note that Connect() wants a host address, not an URL. 80 is the server's port. wxString server( wxT("www.stimfit.org") ); if( http.Connect(server) ) { if(wxInputStream* in_stream = http.GetInputStream (address)) { wxString verS; int c_int = in_stream->GetC(); while ( c_int != wxEOF ) { if (progDlg != NULL) { progDlg->Pulse( wxT("Reading version information...") ); } verS << wxChar(c_int); c_int = in_stream->GetC(); } wxDELETE(in_stream); std::vector version = ParseVersionString( verS ); if ( CompVersion(version) ) { wxString msg; msg << wxT("A newer version of Stimfit (") << verS << wxT(") is available. ") << wxT("Would you like to download it now?"); wxMessageDialog newversion( NULL, msg, wxT("New version available"), wxYES_NO ); if ( newversion.ShowModal() == wxID_YES ) { wxLaunchDefaultBrowser( wxT("http://code.google.com/p/stimfit/downloads/list") ); } } else { if (progDlg != NULL) { wxMessageDialog newversion( NULL, wxT("You already have the newest version"), wxT("No new version available"), wxOK ); newversion.ShowModal(); } } } else { if (progDlg != NULL) { wxGetApp().ErrorMsg( wxT("Couldn't retrieve update information. Are you connected to the internet?") ); } } } else { if (progDlg != NULL) { wxGetApp().ErrorMsg( wxT("Couldn't connect to server. Are you connected to the internet?") ); } } } void wxStfParentFrame::OnCheckUpdate(wxCommandEvent& WXUNUSED(event) ) { wxProgressDialog progDlg( wxT("Checking for updates"), wxT("Connecting to server..."), 100, NULL, wxPD_SMOOTH | wxPD_AUTO_HIDE ); CheckUpdate( &progDlg ); } void wxStfParentFrame::OnConvert(wxCommandEvent& WXUNUSED(event) ) { int nfiles; // files to convert wxString src_ext; // extension of the source file wxString dest_ext; // extesion of the destiny file // "Convert files" Dialog (see wxStfConvertDlg in smalldlgs.cpp) wxStfConvertDlg myDlg(this); if(myDlg.ShowModal() == wxID_OK) { stfio::filetype ift = myDlg.GetSrcFileExt(); stfio::filetype eft = myDlg.GetDestFileExt(); src_ext = myDlg.GetSrcFilter(); // wxProgressDialog wxProgressDialog progDlg( wxT("CFS conversion utility"), wxT("Starting file conversion"), 100, NULL, wxPD_SMOOTH | wxPD_AUTO_HIDE | wxPD_APP_MODAL ); wxArrayString srcFilenames(myDlg.GetSrcFileNames()); nfiles = srcFilenames.size(); // number of files to convert wxString myDestDir = myDlg.GetDestDir(); for (std::size_t nFile=0; nFile ") << destFilename; progDlg.Update( (int)(((double)nFile/(double)srcFilenames.size())*100.0), progStr ); // Open source file and convert: Recording sourceFile; try { stf::wxProgressInfo progDlgIn("Reading file", "Opening file", 100); stfio::importFile(stf::wx2std(srcFilenames[nFile]), ift, sourceFile, wxGetApp().GetTxtImport(), progDlgIn); stf::wxProgressInfo progDlgOut("Writing file", "Opening file", 100); switch ( eft ) { case stfio::atf: stfio::exportATFFile(stf::wx2std(destFilename), sourceFile); dest_ext = wxT("Axon textfile [*.atf]"); break; case stfio::igor: stfio::exportIGORFile(stf::wx2std(destFilename), sourceFile, progDlgOut); dest_ext = wxT("Igor binary file [*.ibw]"); break; #if defined(WITH_BIOSIG) case stfio::biosig: stfio::exportBiosigFile(stf::wx2std(destFilename), sourceFile, progDlgOut); dest_ext = wxT("Biosig/GDF [*.gdf]"); break; #endif default: wxString errorMsg(wxT("Unknown export file type\n")); wxGetApp().ErrorMsg(errorMsg); return; } } catch (const std::runtime_error& e) { wxString errorMsg(wxT("Error opening file\n")); errorMsg += wxT("Runtime Error\n"); errorMsg += wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(errorMsg); return; } catch (const std::exception& e) { wxString errorMsg(wxT("Error opening file\n")); errorMsg += wxT("Exception\n"); errorMsg += wxString( e.what(), wxConvLocal ); wxGetApp().ExceptMsg(errorMsg); return; } } // Show now a smal information dialog //std::count << srcFilter.c_str() << std::endl; wxString msg; msg = wxString::Format(wxT("%i"), nfiles); msg << src_ext; msg << wxT(" files \nwere converted to "); msg << dest_ext; wxMessageDialog Simple(this, msg); Simple.ShowModal(); } // end of wxStfConvertDlg } // Creates a graph. Called from view.cpp when a new drawing // view is created. wxStfGraph *wxStfParentFrame::CreateGraph(wxView *view, wxStfChildFrame *parent) { int width=800, height=600; parent->GetClientSize(&width, &height); // Non-retained graph wxStfGraph *graph = new wxStfGraph( view, parent, #ifndef __APPLE__ wxPoint(0, 0), #else wxDefaultPosition, #endif wxSize(width, height), wxFULL_REPAINT_ON_RESIZE | wxWANTS_CHARS ); return graph; } void wxStfParentFrame::OnPrint(wxCommandEvent& WXUNUSED(event)) { if (wxGetApp().GetActiveDoc()==NULL) return; wxPrintDialogData printDialogData(* m_printData); wxPrinter printer(& printDialogData); wxStfPreprintDlg myDlg(this); if (myDlg.ShowModal()!=wxID_OK) return; wxStfView* pView=wxGetApp().GetActiveView(); pView->GetGraph()->set_downsampling(myDlg.GetDownSampling()); pView->GetGraph()->set_noGimmicks(!myDlg.GetGimmicks()); wxStfPrintout printout(_T("Trace printout")); if (!printer.Print(this, &printout, true /*prompt*/)) { if (wxPrinter::GetLastError() == wxPRINTER_ERROR) wxMessageBox( _T("There was a problem printing.\nPerhaps your current printer is not set correctly?"), _T("Printing"), wxOK ); else wxMessageBox(_T("You canceled printing"), _T("Printing"), wxOK); } else { (*m_printData) = printer.GetPrintDialogData().GetPrintData(); } } void wxStfParentFrame::OnMpl(wxCommandEvent& WXUNUSED(event)) { if (wxGetApp().GetActiveDoc()==NULL) return; #ifdef WITH_PYTHON std::ostringstream mgr_name; mgr_name << "mpl" << GetMplFigNo(); wxWindow* pPython = MakePythonWindow("plotWindowMpl", mgr_name.str(), "Matplotlib", true, false, true, 800, 600).cppWindow; if ( pPython == 0 ) #endif wxGetApp().ErrorMsg(wxT("Can not create figure (python/matplotlib is not available)")); } void wxStfParentFrame::OnMplSpectrum(wxCommandEvent& WXUNUSED(event)) { if (wxGetApp().GetActiveDoc()==NULL) return; #ifdef WITH_PYTHON std::ostringstream mgr_name; mgr_name << "mpl" << GetMplFigNo(); wxWindow* pPython = MakePythonWindow("spectrumWindowMpl", mgr_name.str(), "Matplotlib", true, false, true, 800, 600).cppWindow; if ( pPython == 0 ) #endif wxGetApp().ErrorMsg(wxT("Can not create figure (python/matplotlib is not available)")); } void wxStfParentFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event)) { (*m_pageSetupData) = *m_printData; wxPageSetupDialog pageSetupDialog(this, m_pageSetupData.get()); pageSetupDialog.ShowModal(); (*m_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData(); (*m_pageSetupData) = pageSetupDialog.GetPageSetupDialogData(); } void wxStfParentFrame::OnToggleSelect(wxCommandEvent& WXUNUSED(event)) { wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pDoc!=NULL) { pDoc->ToggleSelect(); } } void wxStfParentFrame::OnToolFirst(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnFirst(); } } void wxStfParentFrame::OnToolNext(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnNext(); } } void wxStfParentFrame::OnToolPrevious(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnPrevious(); } } void wxStfParentFrame::OnToolLast(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnLast(); } } void wxStfParentFrame::OnToolXenl(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnXenllo(); } } void wxStfParentFrame::OnToolXshrink(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnXshrinklo(); } } void wxStfParentFrame::OnToolYenl(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnYenllo(); } } void wxStfParentFrame::OnToolYshrink(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnYshrinklo(); } } void wxStfParentFrame::OnToolUp(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnUp(); } } void wxStfParentFrame::OnToolDown(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnDown(); } } void wxStfParentFrame::OnToolFit(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->Fittowindow(true); } } void wxStfParentFrame::OnToolLeft(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnLeft(); } } void wxStfParentFrame::OnToolRight(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->OnRight(); } } void wxStfParentFrame::OnToolCh1(wxCommandEvent& WXUNUSED(event)) { // activate channel 1 if no channel is active: if (!m_scaleToolBar->GetToolToggled(ID_TOOL_CH1) && !m_scaleToolBar->GetToolToggled(ID_TOOL_CH2)) { m_scaleToolBar->ToggleTool(ID_TOOL_CH1,true); } m_scaleToolBar->Refresh(); } void wxStfParentFrame::OnToolCh2(wxCommandEvent& WXUNUSED(event)) { // activate channel 1 if no channel is active: if (!m_scaleToolBar->GetToolToggled(ID_TOOL_CH1) && !m_scaleToolBar->GetToolToggled(ID_TOOL_CH2)) { m_scaleToolBar->ToggleTool(ID_TOOL_CH1,true); } m_scaleToolBar->Refresh(); } void wxStfParentFrame::OnToolFitdecay(wxCommandEvent& event) { wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pDoc!=NULL) { pDoc->FitDecay(event); } } void wxStfParentFrame::SetSingleChannel(bool value) { if (!m_scaleToolBar) return; if (value) { if (!m_scaleToolBar->GetToolEnabled(ID_TOOL_CH1)) m_scaleToolBar->EnableTool(ID_TOOL_CH1,true); if (m_scaleToolBar->GetToolEnabled(ID_TOOL_CH2)) m_scaleToolBar->EnableTool(ID_TOOL_CH2,false); } else { if (!m_scaleToolBar->GetToolEnabled(ID_TOOL_CH1)) m_scaleToolBar->EnableTool(ID_TOOL_CH1,true); if (!m_scaleToolBar->GetToolEnabled(ID_TOOL_CH2)) m_scaleToolBar->EnableTool(ID_TOOL_CH2,true); } // Make sure at least one value is selected: if (!m_scaleToolBar->GetToolToggled(ID_TOOL_CH1) && (value || !m_scaleToolBar->GetToolToggled(ID_TOOL_CH2))) { m_scaleToolBar->ToggleTool(ID_TOOL_CH1, true); } m_scaleToolBar->Refresh(); } void wxStfParentFrame::OnToolSnapshotwmf(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->Snapshotwmf(); } } void wxStfParentFrame::OnToolMeasure(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::measure_cursor ); } void wxStfParentFrame::OnToolPeak(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::peak_cursor ); } void wxStfParentFrame::OnToolBase(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::base_cursor ); } void wxStfParentFrame::OnToolDecay(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::decay_cursor ); } #ifdef WITH_PSLOPE void wxStfParentFrame::OnToolPSlope(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::pslope_cursor ); } #endif void wxStfParentFrame::OnToolLatency(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::latency_cursor ); } void wxStfParentFrame::OnToolZoom(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::zoom_cursor ); } void wxStfParentFrame::OnToolEvent(wxCommandEvent& WXUNUSED(event)) { SetMouseQual( stf::event_cursor ); } void wxStfParentFrame::OnCh2zoom(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->Ch2zoom(); } } void wxStfParentFrame::OnCh2base(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->Ch2base(); } } void wxStfParentFrame::OnCh2pos(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->Ch2pos(); } } void wxStfParentFrame::OnCh2basezoom(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { pView->GetGraph()->Ch2basezoom(); } } void wxStfParentFrame::OnViewResults(wxCommandEvent& WXUNUSED(event)) { wxStfChildFrame* pChild=(wxStfChildFrame*)GetActiveChild(); if (pChild!=NULL) { pChild->GetCopyGrid()->ViewResults(); } } void wxStfParentFrame::OnScale(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); if (pView!=NULL) { if (GetActiveChild()->GetMenuBar() && GetActiveChild()->GetMenuBar()->GetMenu(2)->IsChecked(ID_SCALE)) { wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("ViewScaleBars"),1); wxGetApp().set_isBars(true); } else { wxGetApp().wxWriteProfileInt(wxT("Settings"),wxT("ViewScaleBars"),0); wxGetApp().set_isBars(false); } if (pView->GetGraph() != NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnAverage(wxCommandEvent& WXUNUSED(event)) { wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pDoc!=NULL) { pDoc->CreateAverage(false,false); } } void wxStfParentFrame::OnAlignedAverage(wxCommandEvent& WXUNUSED(event)) { wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pDoc!=NULL) { pDoc->CreateAverage(false,true); } } #if 0 void wxStfParentFrame::OnUserdef(wxCommandEvent& event) { wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pDoc!=NULL) { pDoc->Userdef(event.GetId()-ID_USERDEF1); } } #endif void wxStfParentFrame::OnSaveperspective(wxCommandEvent& WXUNUSED(event)) { wxStfChildFrame* pChild=(wxStfChildFrame*)GetActiveChild(); if (pChild!=NULL) { pChild->Saveperspective(); } } void wxStfParentFrame::OnLoadperspective(wxCommandEvent& WXUNUSED(event)) { wxStfChildFrame* pChild=(wxStfChildFrame*)GetActiveChild(); if (pChild!=NULL) { pChild->Loadperspective(); } } void wxStfParentFrame::OnRestoreperspective(wxCommandEvent& WXUNUSED(event)) { wxStfChildFrame* pChild=(wxStfChildFrame*)GetActiveChild(); if (pChild!=NULL) { pChild->Restoreperspective(); } } #ifdef WITH_PYTHON void wxStfParentFrame::OnViewshell(wxCommandEvent& WXUNUSED(event)) { // Save the current visibility state: bool old_state = m_mgr.GetPane(wxT("pythonShell")).IsShown(); // Toggle python shell visibility: m_mgr.GetPane(wxT("pythonShell")).Show( !old_state ); wxGetApp().wxWriteProfileInt( wxT("Settings"),wxT("ViewShell"), int(!old_state) ); m_mgr.Update(); } #endif void wxStfParentFrame::OnLStartMaxslope(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { // get previous mode: // bool prevMode=pDoc->GetLatencyStartMode()==stfio::riseMode; // toggle on if it wasn't the previous mode: // if (!prevMode) { pDoc->SetLatencyStartMode(stf::riseMode); wxGetApp().wxWriteProfileInt(wxT("Settings"), wxT("LatencyStartMode"), pDoc->GetLatencyStartMode()); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLStartHalfrise(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { pDoc->SetLatencyStartMode(stf::halfMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyStartMode"), pDoc->GetLatencyStartMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLStartPeak(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { pDoc->SetLatencyStartMode(stf::peakMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyStartMode"), pDoc->GetLatencyStartMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLStartManual(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { // Always keep manual mode as a default, even if attempted to uncheck: pDoc->SetLatencyStartMode(stf::manualMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyStartMode"), pDoc->GetLatencyStartMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLEndFoot(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { pDoc->SetLatencyEndMode(stf::footMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyEndMode"), pDoc->GetLatencyEndMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLEndMaxslope(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { pDoc->SetLatencyEndMode(stf::riseMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyEndMode"), pDoc->GetLatencyEndMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLEndHalfrise(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { pDoc->SetLatencyEndMode(stf::halfMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyEndMode"), pDoc->GetLatencyEndMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLEndPeak(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { pDoc->SetLatencyEndMode(stf::peakMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyEndMode"), pDoc->GetLatencyEndMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } void wxStfParentFrame::OnLEndManual(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL && pDoc!=NULL) { pDoc->SetLatencyEndMode(stf::manualMode); wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyEndMode"), pDoc->GetLatencyEndMode() ); if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } # if 0 void wxStfParentFrame::OnLWindow(wxCommandEvent& WXUNUSED(event)) { wxStfView* pView=wxGetApp().GetActiveView(); wxStfDoc* pDoc=wxGetApp().GetActiveDoc(); if (pView!=NULL) { // Select if (GetActiveChild()->GetMenuBar() && GetActiveChild()->GetMenuBar()->GetMenu(1)->IsChecked(ID_LATENCYWINDOW)) { wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyWindowMode"), stf::windowMode ); pDoc->SetLatencyWindowMode(stf::windowMode); } else { wxGetApp().wxWriteProfileInt( wxT("Settings"), wxT("LatencyWindowMode"), stf::defaultMode ); pDoc->SetLatencyWindowMode(stf::defaultMode); } if (pView->GetGraph()!=NULL) pView->GetGraph()->Refresh(); } } #endif stf::cursor_type wxStfParentFrame::GetMouseQual() const { if (m_cursorToolBar->GetToolToggled(ID_TOOL_MEASURE)) return stf::measure_cursor; if (m_cursorToolBar->GetToolToggled(ID_TOOL_PEAK)) return stf::peak_cursor; if (m_cursorToolBar->GetToolToggled(ID_TOOL_BASE)) return stf::base_cursor; if (m_cursorToolBar->GetToolToggled(ID_TOOL_DECAY)) return stf::decay_cursor; if (m_cursorToolBar->GetToolToggled(ID_TOOL_LATENCY)) return stf::latency_cursor; if (m_cursorToolBar->GetToolToggled(ID_TOOL_ZOOM)) return stf::zoom_cursor; if (m_cursorToolBar->GetToolToggled(ID_TOOL_EVENT)) return stf::event_cursor; #ifdef WITH_PSLOPE if (m_cursorToolBar->GetToolToggled(ID_TOOL_PSLOPE)) return stf::pslope_cursor; #endif return stf::undefined_cursor; } void wxStfParentFrame::SetMouseQual(stf::cursor_type value) { if (m_cursorToolBar == NULL) return; // Need to set everything to false explicitly first: m_cursorToolBar->ToggleTool(ID_TOOL_MEASURE,false); m_cursorToolBar->ToggleTool(ID_TOOL_PEAK,false); m_cursorToolBar->ToggleTool(ID_TOOL_BASE,false); m_cursorToolBar->ToggleTool(ID_TOOL_DECAY,false); m_cursorToolBar->ToggleTool(ID_TOOL_LATENCY,false); m_cursorToolBar->ToggleTool(ID_TOOL_ZOOM,false); m_cursorToolBar->ToggleTool(ID_TOOL_EVENT,false); #ifdef WITH_PSLOPE m_cursorToolBar->ToggleTool(ID_TOOL_PSLOPE,false); #endif // Then set the state of the selected button: if (value==stf::measure_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_MEASURE,true); if (value==stf::peak_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_PEAK,true); if (value==stf::base_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_BASE,true); if (value==stf::decay_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_DECAY,true); if (value==stf::latency_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_LATENCY,true); #ifdef WITH_PSLOPE if (value==stf::pslope_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_PSLOPE,true); #endif if (value==stf::zoom_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_ZOOM,true); if (value==stf::event_cursor) m_cursorToolBar->ToggleTool(ID_TOOL_EVENT,true); m_cursorToolBar->Refresh(); } void wxStfParentFrame::SetSelectedButton(bool selected) { if (m_cursorToolBar==NULL) return; m_cursorToolBar->ToggleTool(ID_TOOL_SELECT, selected); m_cursorToolBar->Refresh(); } stf::zoom_channels wxStfParentFrame::GetZoomQual() const { if (m_scaleToolBar->GetToolToggled(ID_TOOL_CH1)) { if (m_scaleToolBar->GetToolToggled(ID_TOOL_CH2)) { return stf::zoomboth; } else { return stf::zoomch1; } } return stf::zoomch2; } void wxStfParentFrame::SetZoomQual(stf::zoom_channels value) { if (m_scaleToolBar==NULL) return; if (value==stf::zoomch1) { m_scaleToolBar->ToggleTool(ID_TOOL_CH1,true); m_scaleToolBar->ToggleTool(ID_TOOL_CH2,false); } if (value==stf::zoomch2) { m_scaleToolBar->ToggleTool(ID_TOOL_CH1,false); m_scaleToolBar->ToggleTool(ID_TOOL_CH2,true); } if (value==stf::zoomboth) { m_scaleToolBar->ToggleTool(ID_TOOL_CH1,true); m_scaleToolBar->ToggleTool(ID_TOOL_CH2,true); } m_scaleToolBar->Refresh(); } stimfit-0.16.7/src/stimfit/gui/zoom.h0000775000175000017500000000424714750344764013166 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file zoom.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Declares the Zoom struct. */ #ifndef _ZOOM_H #define _ZOOM_H //! Handles y-scaling of traces class YZoom { public: //! Default constructor YZoom() : startPosY(500), yZoom(0.1), isLogScaleY(false) {} //! Constructor /*! \param spy1 The y offset in pixels. * \param yz1 The y-scaling. * \param lsy Currently unused. */ YZoom(long spy1, double yz1, bool lsy=false) : startPosY(spy1), yZoom(yz1), isLogScaleY(lsy) {} long startPosY; /*!< The y offset in pixels. */ double yZoom; /*!< The y-scaling. */ bool isLogScaleY; /*!< Currently unused. */ //! Overloaded multiplication operator. YZoom operator*( double factor ); }; //! Handles x-scaling of traces class XZoom { public: //! Default constructor XZoom() : startPosX(0), xZoom(0.1), isLogScaleX(false) {} //! Constructor /*! \param spx The x offset in pixels. * \param xz The x-scaling. * \param lsx Currently unused. */ XZoom( long spx, double xz, bool lsx=false ) : startPosX(spx), xZoom(xz), isLogScaleX(lsx) {} long startPosX; /*!< The x offset in pixels. */ double xZoom; /*!< The x-scaling. */ bool isLogScaleX; /*!< Currently unused. */ //! Overloaded multiplication operator. XZoom operator*( double factor ); }; #endif stimfit-0.16.7/src/stimfit/gui/printout.cpp0000775000175000017500000001714614750344764014423 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // printout.cpp // Controls printing of traces. // 2007-12-27, Christoph Schmidt-Hieber, University of Freiburg #include #ifndef WX_PRECOMP #include #endif #include #include "./app.h" #include "./view.h" #include "./parentframe.h" #include "./doc.h" #include "./printout.h" #include "./graph.h" wxStfPrintout::wxStfPrintout(const wxChar *title) : wxPrintout(title) , store_noGimmicks(false) { wxStfDoc* pDoc = wxGetApp().GetActiveDoc(); if (!pDoc) { wxGetApp().ErrorMsg(wxT("Null pointer (pDoc) in wxStfPrintout::wxStfPrintout()\nAborting printing")); return; } wxStfView* pView = (wxStfView*)pDoc->GetFirstView(); if (!pView) { wxGetApp().ErrorMsg(wxT("Null pointer (pView) in wxStfPrintout::wxStfPrintout()\nAborting printing")); return; } wxStfGraph* pGraph = pView->GetGraph(); if (!pGraph) { wxGetApp().ErrorMsg(wxT("Null pointer (pGraph) in wxStfPrintout::wxStfPrintout()\nAborting printing")); return; } store_noGimmicks=wxGetApp().GetActiveView()->GetGraph()->get_noGimmicks(); } bool wxStfPrintout::OnPrintPage(int WXUNUSED(page)) { wxDC* dc=GetDC(); if (dc) { DrawPageOne(); return true; } else return false; } bool wxStfPrintout::OnBeginDocument(int startPage, int endPage) { if (!wxPrintout::OnBeginDocument(startPage, endPage)) return false; return true; } void wxStfPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) { *minPage = 1; *maxPage = 1; *selPageFrom = 1; *selPageTo = 1; } bool wxStfPrintout::HasPage(int pageNum) { return (pageNum == 1); } void wxStfPrintout::DrawPageOne() { int x,y; GetPPIPrinter(&x,&y); // Get size of Graph, in pixels: wxStfDoc* pDoc = wxGetApp().GetActiveDoc(); if (!pDoc) { wxGetApp().ErrorMsg(wxT("Null pointer (pDoc) in wxStfPrintout::DrawPageOne()\nAborting printing")); return; } wxStfView* pView = (wxStfView*)pDoc->GetFirstView(); if (!pView) { wxGetApp().ErrorMsg(wxT("Null pointer (pView) in wxStfPrintout::DrawPageOne()\nAborting printing")); return; } wxStfGraph* pGraph = pView->GetGraph(); if (!pGraph) { wxGetApp().ErrorMsg(wxT("Null pointer (pGraph) in wxStfPrintout::DrawPageOne()\nAborting printing")); return; } wxRect screenRect(pGraph->GetRect()); // Get size of page, in pixels: wxRect printRect=GetLogicalPageMarginsRect(*(wxGetApp().GetMainFrame()->GetPageSetup())); // A first guess at the scale: double hScale=(double)printRect.height/(double)screenRect.height; double headerSizeY=0.0; // Space needed for the header: if (!store_noGimmicks) { headerSizeY=30.0*hScale; } else { pGraph->set_noGimmicks(true); } // Fit to width or fit to height? // If the screenRect's proportion is wider than the printRect's, // fit to width: double scale=1.0; wxRect propPrintRect(printRect); double prop=(double)screenRect.width/(double)screenRect.height; if (prop > (printRect.height-headerSizeY)/printRect.width) { scale=(double)printRect.width/(double)(screenRect.width); // keep width: propPrintRect.height=(int)((double)propPrintRect.width/prop); } else { scale=(double)(printRect.height-headerSizeY)/(double)(screenRect.height); propPrintRect.width=(int)((double)propPrintRect.height*prop); } // maximal extent of the Graph on paper: wxCoord maxX = (int)((double)(screenRect.width)*scale); wxCoord maxY = (int)((double)(screenRect.height)*scale); wxCoord xoff =(printRect.width - maxX) / 2.0; wxCoord yoff =(printRect.height - maxY) / 2.0; #ifdef __WXGTK__ xoff = -printRect.width*0.8; OffsetLogicalOrigin(xoff, 0); xoff = 0; #endif pGraph->set_isPrinted(true); pGraph->set_printScale(scale); // construct a rectangle with the same proportion as the graph on screen: pGraph->set_printRect(propPrintRect); if (!store_noGimmicks) { PrintHeader(GetDC(),hScale); } // create a font that looks similar to the screen font: wxFont font( (int)(6.0 * (double)x/72.0), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL ); GetDC()->SetFont(font); OffsetLogicalOrigin(xoff, (int)(yoff+headerSizeY)); pGraph->OnDraw(*GetDC()); pGraph->set_isPrinted(false); } void wxStfPrintout::PrintHeader(wxDC* pDC, double scale) { int ppiX,ppiY; GetPPIPrinter(&ppiX,&ppiY); double resScale = ppiX / 72.0; #ifdef _WINDOWS int fontScale=(int)(6.0 * resScale); #else int fontScale=(int)(10.0 * resScale); #endif int xstart=0; int ystart=0; // create a font that looks similar to the screen font: wxFont font( fontScale, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD ); GetDC()->SetFont(font); // File name and section number: wxString description; description << Doc()->GetFilename() << wxT(", Trace ") << (int)Doc()->GetCurSecIndex()+1 << wxT(" of ") << (int)Doc()->get()[Doc()->GetCurChIndex()].size(); pDC->DrawText(description,xstart,ystart); // Results: stfnum::Table table(Doc()->CurResultsTable()); font.SetWeight(wxFONTWEIGHT_NORMAL); pDC->SetFont(font); int xpos=xstart; for (std::size_t nRow=0;nRow<1;/*table.nRows()*/++nRow) { // row label: for (std::size_t nCol=0;nColDrawText(stf::std2wx(table.GetColLabel(nCol)),xpos,(int)(14.0*resScale)+ystart); if (!table.IsEmpty(nRow,nCol)) { wxString entry; entry << table.at(nRow,nCol); pDC->DrawText(entry,xpos,(int)(24.0*resScale)+ystart); } xpos+=colSize; } } try { stf::SectionAttributes sec_attr = Doc()->GetCurrentSectionAttributes(); if (sec_attr.isFitted) { wxRect WindowRect(GetLogicalPageMarginsRect(*(wxGetApp().GetMainFrame()->GetPageSetup()))); int increment=WindowRect.height/50; int yPos=(int)(WindowRect.height*0.5); int xPos=(int)(WindowRect.width*0.75); // print fit info line by line: for (std::size_t n=0;n < sec_attr.bestFit.nRows();++n) { pDC->DrawText(stf::std2wx(sec_attr.bestFit.GetRowLabel(n)),xPos,yPos); wxString value; value << sec_attr.bestFit.at(n,0); pDC->DrawText(value,(int)(xPos+40.0*resScale),yPos); yPos+=increment; } } } catch (const std::out_of_range& e) { } } stimfit-0.16.7/src/stimfit/stf.h0000664000175000017500000004367414750344764012216 // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /*! \file stimdefs.h * \author Christoph Schmidt-Hieber * \date 2008-01-16 * \brief Common definitions and classes. * * * Header file for common definitions and classes. */ #ifndef _STF_H_ #define _STF_H_ #ifndef _WINDOWS #if (__cplusplus < 201103) #include #else #include #include #endif #endif #if (__GNUC__ > 5) #include #endif #include #include #include #include "./gui/zoom.h" #ifdef _MSC_VER #pragma warning( disable : 4251 ) // Disable warning messages #pragma warning( disable : 4996 ) // Disable warning messages #endif //! Defines dll export or import functions for Windows #if defined(_WINDOWS) && !defined(__MINGW32__) #ifdef STFDLL #define StfDll __declspec( dllexport ) #else #define StfDll __declspec( dllimport ) #endif #else #define StfDll #endif #ifndef MODULE_ONLY #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #include #include #include #endif #include #include //! child frame type; depends on whether aui is used for the doc/view interface // typedef wxDocChildFrameAny wxStfChildType; typedef wxDocMDIChildFrame wxStfChildType; //! parent frame type; depends on whether aui is used for the doc/view interface typedef wxDocMDIParentFrame wxStfParentType; #else typedef std::string wxString; typedef int wxWindow; #define wxT(x) x #define wxCHECK_VERSION(major,minor,release) 0 #endif #include "../libstfio/stfio.h" #include "../libstfnum/stfnum.h" //! The stimfit namespace. /*! All essential core functions and classes are in this namespace. * Its purpose is to reduce name mangling problems. */ namespace stf { /*! \addtogroup stfgen * @{ */ //! Progress Info interface adapter; maps to wxProgressDialog class wxProgressInfo : public stfio::ProgressInfo { public: wxProgressInfo(const std::string& title, const std::string& message, int maximum, bool verbose=true); bool Update(int value, const std::string& newmsg="", bool* skip=NULL); private: wxProgressDialog pd; }; std::string wx2std(const wxString& wxs); wxString std2wx(const std::string& sst); //! Converts a Section to a wxString. /*! \param section The Section to be written to a string. * \return A string containing the x- and y-values of the section in two columns. */ wxString sectionToString(const Section& section); //! Creates a preview of a text file. /*! \param fName Full path name of the file. * \return A string showing at most the initial 100 lines of the text file. */ wxString CreatePreview(const wxString& fName); //! Strips the directory off a full path name, returns only the filename. /*! \param fName The full path of a file. * \return The file name without the directory. */ wxString noPath(const wxString& fName); //! Get a Recording, do something with it, return the new Recording. #if (__cplusplus < 201103) typedef boost::function&)> PluginFunc; #else typedef std::function&)> PluginFunc; #endif //! Represents user input from dialogs that can be used in plugins. struct UserInput { std::vector labels; /*!< Dialog entry labels. */ Vector_double defaults; /*!< Default dialog entries. */ std::string title; /*!< Dialog title. */ //! Constructor. /*! \param labels_ A vector of dialog entry label strings. * \param defaults_ A vector of default dialog entries. * \param title_ Dialog title. */ UserInput( const std::vector& labels_=std::vector(0), const Vector_double& defaults_=Vector_double(0), std::string title_="\0" ) : labels(labels_),defaults(defaults_),title(title_) { if (defaults.size()!=labels.size()) { defaults.resize(labels.size()); std::fill(defaults.begin(), defaults.end(), 0.0); } } }; //! User-defined plugin /*! Class used for extending Stimfit's functionality: * The client supplies a new menu entry and an ExtFunc * that will be called upon selection of that entry. */ struct Plugin { //! Constructor /*! \param menuEntry_ Menu entry string for this plugin. * \param pluginFunc_ Function to be executed by this plugin. * \param input_ Dialog entries required by this plugin. */ Plugin( const wxString& menuEntry_, const PluginFunc& pluginFunc_, const UserInput& input_=UserInput() ) : menuEntry(menuEntry_),pluginFunc(pluginFunc_),input(input_) { id = n_plugins; n_plugins++; } //! Destructor ~Plugin() { } int id; /*!< The plugin id; set automatically upon construction, so don't touch. */ static int n_plugins; /*!< Static plugin counter. Initialised in plugins/plugins.cpp. */ wxString menuEntry; /*!< Menu entry string for this plugin. */ PluginFunc pluginFunc; /*!< The function to be executed by this plugin. */ UserInput input; /*!< Dialog entries */ }; //! User-defined Python extension /*! Class used for extending Stimfit's functionality: * The client supplies a new menu entry and a Python function * that will be called upon selection of that entry. */ struct Extension { //! Constructor /*! \param menuEntry_ Menu entry string for this extension. * \param pyFunc_ Python function to be called. * \param description_ Description for this function. * \param requiresFile_ Whether a file needs to be open for this function to work */ Extension(const std::string& menuEntry_, void* pyFunc_, const std::string& description_, bool requiresFile_) : menuEntry(menuEntry_), pyFunc(pyFunc_), description(description_), requiresFile(requiresFile_) { id = n_extensions; n_extensions++; } //! Destructor ~Extension() { } int id; /*!< The extension id; set automatically upon construction, so don't touch. */ static int n_extensions; /*!< Static extension counter. Initialised in extensions/extensions.cpp. */ std::string menuEntry; /*!< Menu entry string for this extension. */ void* pyFunc; /*!< Python function to be called. */ std::string description; /*!< Description for this function. */ bool requiresFile; /*!< Whether a file needs to be open for this function to work */ }; //! Resource manager for ifstream objects. struct ifstreamMan { //! Constructor /*! See fstream documentation for details */ ifstreamMan( const wxString& filename ) : myStream( filename, wxT("r") ) {} //! Destructor ~ifstreamMan() { myStream.Close(); } //! The managed stream. wxFFile myStream; }; //! Resource manager for ofstream objects. struct ofstreamMan { //! Constructor /*! See fstream documentation for details */ ofstreamMan( const wxString& filename ) : myStream( filename, wxT("w") ) {} //! Destructor ~ofstreamMan() { myStream.Close(); } //! The managed stream. wxFFile myStream; }; //! Describes the attributes of an event. class Event { public: //! Constructor explicit Event(std::size_t start, std::size_t peak, std::size_t size, wxCheckBox* cb); //! Destructor ~Event(); //! Retrieves the start index of an event. /*! \return The start index of an event within a section. */ std::size_t GetEventStartIndex() const { return eventStartIndex; } //! Retrieves the index of an event's peak. /*! \return The index of an event's peak within a section. */ std::size_t GetEventPeakIndex() const { return eventPeakIndex; } //! Retrieves the size of an event. /*! \return The size of an event in units of data points. */ std::size_t GetEventSize() const { return eventSize; } //! Indicates whether an event should be discarded. /*! \return true if it should be discarded, false otherwise. */ bool GetDiscard() const { return !checkBox->GetValue(); } //! Get the check box associated with this event /*! \return The wxCheckBox associated with this event */ wxCheckBox* GetCheckBox() {return checkBox;} //! Sets the start index of an event. /*! \param value The start index of an event within a section. */ void SetEventStartIndex( std::size_t value ) { eventStartIndex = value; } //! Sets the index of an event's peak. /*! \param value The index of an event's peak within a section. */ void SetEventPeakIndex( std::size_t value ) { eventPeakIndex = value; } //! Sets the size of an event. /*! \param value The size of an event in units of data points. */ void SetEventSize( std::size_t value ) { eventSize = value; } //! Determines whether an event should be discarded. /*! \param true if it should be discarded, false otherwise. */ /*void SetDiscard( bool value ) { discard = value; }*/ //! Sets discard to true if it was false and vice versa. /*void ToggleStatus() { discard = !discard; }*/ private: std::size_t eventStartIndex; std::size_t eventPeakIndex; std::size_t eventSize; wxCheckBox* checkBox; }; //! A marker that can be set from Python /*! A pair of x,y coordinates */ struct PyMarker { //! Constructor /*! \param xv x-coordinate. * \param yv y-coordinate. */ PyMarker( double xv, double yv ) : x(xv), y(yv) {} double x; /*!< x-coordinate in units of sampling points */ double y; /*!< y-coordinate in trace units (e.g. mV) */ }; struct StfDll SectionAttributes { SectionAttributes(); std::vector eventList; std::vector pyMarkers; bool isFitted,isIntegrated; stfnum::storedFunc *fitFunc; Vector_double bestFitP; Vector_double quad_p; std::size_t storeFitBeg; std::size_t storeFitEnd; std::size_t storeIntBeg; std::size_t storeIntEnd; stfnum::Table bestFit; }; struct SectionPointer { SectionPointer(Section* pSec=NULL, const SectionAttributes& sa=SectionAttributes()); Section* pSection; SectionAttributes sec_attr; }; //! Add decimals if you are not satisfied. const double PI=3.14159265358979323846; //! Does what it says. /*! \param toRound The double to be rounded. * \return The rounded integer. */ int round(double toRound); //! Mouse cursor types enum cursor_type { measure_cursor, /*!< Measurement cursor (crosshair). */ peak_cursor, /*!< Peak calculation limits cursor. */ base_cursor, /*!< Baseline calculation limits cursor. */ decay_cursor, /*!< Fit limits cursor. */ latency_cursor, /*!< Latency cursor. */ zoom_cursor, /*!< Zoom rectangle cursor. */ event_cursor, /*!< Event mode cursor. */ #ifdef WITH_PSLOPE pslope_cursor, /*!< PSlope mode cursor. */ #endif undefined_cursor /*!< Undefined cursor. */ }; //! Determines which channels to scale enum zoom_channels { zoomch1, /*!< Scaling applies to channel 1 only. */ zoomch2, /*!< Scaling applies to channel 2 only. */ zoomboth /*!< Scaling applies to both channels. */ }; //! Latency cursor settings enum latency_mode { manualMode = 0, /*!< Set the corresponding latency cursor manually (by clicking on the graph). */ peakMode = 1, /*!< Set the corresponding latency cursor to the peak. */ riseMode = 2, /*!< Set the corresponding latency cursor to the maximal slope of rise. */ halfMode = 3, /*!< Set the corresponding latency cursor to the half-maximal amplitude. */ footMode = 4, /*!< Set the corresponding latency cursor to the beginning of an event. */ undefinedMode /*!< undefined mode. */ }; //! Latency window settings enum latency_window_mode { defaultMode = 0, /*!< Use the current peak cursor window for the active channel. */ windowMode = 1 /*!< Use a window of 100 sampling points around the peak. */ }; #ifdef WITH_PSLOPE //! PSlope start cursor settings enum pslope_mode_beg { psBeg_manualMode =0, /*< Set the start Slope cursor manually. */ psBeg_footMode =1, /*< Set the start Slope cursor to the beginning of an event. */ psBeg_thrMode =2, /*< Set the start Slope cursor to a threshold. */ psBeg_t50Mode =3, /*< Set the start Slope cursor to the half-width of an event*/ psBeg_undefined }; //! PSlope end cursor settings enum pslope_mode_end { psEnd_manualMode =0, /*< Set the end Slope cursor manually. */ psEnd_t50Mode =1, /*< Set the Slope cursor to the half-width of an event. */ psEnd_DeltaTMode =2, /*< Set the Slope cursor to a given distance from the first cursor. */ psEnd_peakMode =3, /*< Set the Slope cursor to the peak. */ psEnd_undefined }; #endif // WITH_PSLOPE //! Deconvolution enum extraction_mode { criterion, /*!< Clements & Bekkers criterion. */ correlation, /*!< Jonas et al. correlation coefficient. */ deconvolution /*!< Pernia-Andrade et al. deconvolution. */ }; /*@}*/ } // end of namespace inline int stf::round(double toRound) { return toRound <= 0.0 ? int(toRound-0.5) : int(toRound+0.5); } typedef std::vector< wxString >::iterator wxs_it; /*!< std::string iterator */ typedef std::vector< wxString >::const_iterator c_wxs_it; /*!< constant std::string iterator */ typedef std::vector< stf::Event >::iterator event_it; /*!< stf::Event iterator */ typedef std::vector< stf::Event >::const_iterator c_event_it; /*!< constant stf::Event iterator */ typedef std::vector< stf::PyMarker >::iterator marker_it; /*!< stf::PyMarker iterator */ typedef std::vector< stf::PyMarker >::const_iterator c_marker_it; /*!< constant stf::PyMarker iterator */ // Doxygen-links to documentation of frequently used wxWidgets-classes /*! \defgroup wxwidgets wxWidgets classes * @{ */ /*! \class wxApp * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxapp.html (wxWidgets documentation) */ /*! \class wxCheckBox * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxcheckbox.html (wxWidgets documentation) */ /*! \class wxCommandEvent * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxcommandevent.html (wxWidgets documentation) */ /*! \class wxDialog * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxdialog.html (wxWidgets documentation) */ /*! \class wxDocMDIChildFrame * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxdocmdichildframe.html (wxWidgets documentation) */ /*! \class wxDocMDIParentFrame * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxdocmdiparentframe.html (wxWidgets documentation) */ /*! \class wxDocument * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxdocument.html (wxWidgets documentation) */ /*! \class wxGrid * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxgrid.html (wxWidgets documentation) */ /*! \class wxGridCellCoordsArray * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxgridcellcoordsarray.html (wxWidgets documentation) */ /*! \class wxGridTableBase * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxgridtablebase.html (wxWidgets documentation) */ /*! \class wxPoint * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxpoint.html (wxWidgets documentation) */ /*! \class wxPrintout * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxprintout.html (wxWidgets documentation) */ /*! \class wxSize * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxsize.html (wxWidgets documentation) */ /*! \class wxString * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxstring.html (wxWidgets documentation) */ /*! \class wxThread * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxthread.html (wxWidgets documentation) */ /*! \class wxView * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxview.html (wxWidgets documentation) */ /*! \class wxWindow * \brief See http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html (wxWidgets documentation) */ /*@}*/ /*! \defgroup stdcpp C++ standard library classes * @{ */ /*! \namespace std * \brief The namespace of the C++ standard library (libstdc++). */ /*! \class std::map * \brief See http://www.sgi.com/tech/stl/Map.html (SGI's STL documentation) */ /*! \class std::vector * \brief See http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/classstd_1_1valarray.html (gcc's libstdc++ documentation) */ /*! \class std::vector * \brief See http://www.sgi.com/tech/stl/Vector.html (SGI's STL documentation) */ /*@}*/ #endif stimfit-0.16.7/doc/0000775000175000017500000000000014764352500007602 5stimfit-0.16.7/doc/Doxyfile.in0000664000175000017500000020177114750344764011655 # Doxyfile 1.5.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = Stimfit # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = YES # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = YES # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ../src/stimfit/gui/app.h \ ../src/stimfit/gui/copygrid.h \ ../src/stimfit/gui/copygrid.h \ ../src/stimfit/gui/doc.h \ ../src/stimfit/gui/childframe.h \ ../src/stimfit/gui/parentframe.h \ ../src/stimfit/gui/graph.h \ ../src/stimfit/gui/printout.h \ ../src/stimfit/gui/stfcheckbox.h \ ../src/stimfit/gui/table.h \ ../src/stimfit/gui/view.h \ ../src/stimfit/gui/zoom.h \ ../src/stimfit/gui/dlgs/convertdlg.h \ ../src/stimfit/gui/dlgs/cursorsdlg.h \ ../src/stimfit/gui/dlgs/eventdlg.h \ ../src/stimfit/gui/dlgs/fitseldlg.h \ ../src/stimfit/gui/dlgs/smalldlgs.h \ ../src/stimfit/gui/usrdlg/usrdlg.h \ ../src/libstfnum/fit.h \ ../src/libstfnum/measure.h \ ../src/libstfnum/funclib.h \ ../src/libstfnum/stfnum.h \ ../src/libstfio/channel.h \ ../src/libstfio/recording.h \ ../src/libstfio/section.h \ ../src/libstfio/stfio.h \ ../src/stimfit/stf.h ../src/libstfio/abf/abflib.h \ ../src/libstfio/ascii/asciilib.h \ ../src/libstfio/atf/atflib.h \ ../src/libstfio/axg/axglib.h \ ../src/libstfio/biosig/biosig.h \ ../src/libstfio/cfs/cfslib.h \ ../src/libstfio/heka/heka.h \ ../src/libstfio/hdf5/hdf5lib.h \ ../src/libstfio/igor/igorlib.h \ ../src/libstfio/son/sonlib.h \ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. # FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = lmodern \ textcomp \ amsmath # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _WINDOWS \ __UNIX__ \ WITH_PYTHON # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = YES # Enable the USE_MATHJAX option to render $\mbox{\LaTeX}$ formulas using # MathJax (see http://www.mathjax.org) which uses client side Javascript # for the rendering instead of using prerendered bitmaps. Use this if you # do not have LaTeX installed or if you want to formulas look prettier # in the HTML output. USE_MATHJAX = YES # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = teX/AMSmath TeX/AMSsymbols # Use this tag to change the font size of LaTeX formulas included as images # in the HTML documentation. The default is 10. when you change the font # size after a successful doxygen run you need to manually remove any # form_*.png images from the HTML output directory to force them to be # regenerated. FORMULA_FONTISZE = 16 stimfit-0.16.7/doc/Doxyfile0000664000175000017500000020175614764352426011252 # Doxyfile 1.5.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = Stimfit # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 0.16.7 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = YES # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = YES # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ../src/stimfit/gui/app.h \ ../src/stimfit/gui/copygrid.h \ ../src/stimfit/gui/copygrid.h \ ../src/stimfit/gui/doc.h \ ../src/stimfit/gui/childframe.h \ ../src/stimfit/gui/parentframe.h \ ../src/stimfit/gui/graph.h \ ../src/stimfit/gui/printout.h \ ../src/stimfit/gui/stfcheckbox.h \ ../src/stimfit/gui/table.h \ ../src/stimfit/gui/view.h \ ../src/stimfit/gui/zoom.h \ ../src/stimfit/gui/dlgs/convertdlg.h \ ../src/stimfit/gui/dlgs/cursorsdlg.h \ ../src/stimfit/gui/dlgs/eventdlg.h \ ../src/stimfit/gui/dlgs/fitseldlg.h \ ../src/stimfit/gui/dlgs/smalldlgs.h \ ../src/stimfit/gui/usrdlg/usrdlg.h \ ../src/libstfnum/fit.h \ ../src/libstfnum/measure.h \ ../src/libstfnum/funclib.h \ ../src/libstfnum/stfnum.h \ ../src/libstfio/channel.h \ ../src/libstfio/recording.h \ ../src/libstfio/section.h \ ../src/libstfio/stfio.h \ ../src/stimfit/stf.h ../src/libstfio/abf/abflib.h \ ../src/libstfio/ascii/asciilib.h \ ../src/libstfio/atf/atflib.h \ ../src/libstfio/axg/axglib.h \ ../src/libstfio/biosig/biosig.h \ ../src/libstfio/cfs/cfslib.h \ ../src/libstfio/heka/heka.h \ ../src/libstfio/hdf5/hdf5lib.h \ ../src/libstfio/igor/igorlib.h \ ../src/libstfio/son/sonlib.h \ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. # FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = lmodern \ textcomp \ amsmath # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _WINDOWS \ __UNIX__ \ WITH_PYTHON # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Options related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = YES # Enable the USE_MATHJAX option to render $\mbox{\LaTeX}$ formulas using # MathJax (see http://www.mathjax.org) which uses client side Javascript # for the rendering instead of using prerendered bitmaps. Use this if you # do not have LaTeX installed or if you want to formulas look prettier # in the HTML output. USE_MATHJAX = YES # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = teX/AMSmath TeX/AMSsymbols # Use this tag to change the font size of LaTeX formulas included as images # in the HTML documentation. The default is 10. when you change the font # size after a successful doxygen run you need to manually remove any # form_*.png images from the HTML output directory to force them to be # regenerated. FORMULA_FONTISZE = 16 stimfit-0.16.7/doc/sphinx/0000775000175000017500000000000014764352500011113 5stimfit-0.16.7/doc/sphinx/conf.py.in0000664000175000017500000001546514750344764012762 # -*- coding: utf-8 -*- # # Stimfit documentation documentation build configuration file, created by # sphinx-quickstart on Mon May 4 17:57:05 2009. # # This file is execfile()d with the current directory set to its containing dir. # # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os from sphinx import __display_version__ from sphinx.errors import VersionRequirementError # If your extensions (or modules documented by autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.append(os.path.abspath('.')) # General configuration # --------------------- needs_sphinx = '1.4.3' # required for sphinx.ext.imgmath current_sphinx = __display_version__ if needs_sphinx > current_sphinx: msg = 'Stimfit documentation needs at least Sphinx v%s' %needs_sphinx raise VersionRequirementError( msg ) # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx','sphinx.ext.imgmath'] # Add any paths that contain templates here, relative to this directory. templates_path = ['.templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'contents' # General information about the project. project = u'Stimfit' copyright = u'2018, Christoph Schmidt-Hieber' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '@PACKAGE_VERSION@' # The full version, including alpha/beta/rc tags. release = '@PACKAGE_VERSION@' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. today_fmt = '%d %B, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = ['.build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. show_authors = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # Options for HTML output # ----------------------- #html_theme = "alabaster" html_theme = "default" # html_theme_options = { # "rightsidebar": "false", # "relbarbgcolor": "black" # } html_show_sphinx = (False) # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. html_style = 'default.css' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. html_short_title = 'Stimfit documentation' # The name of an image file (relative to this directory) to place at the top # of the sidebar. html_logo = '../../src/stimfit/res/stimfit_128.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['.static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%d %B, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. html_additional_pages = {'index':'index.html'} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, the reST sources are included in the HTML build as _sources/. html_copy_source = False # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'Stimfitdoc' # Options for LaTeX output # ------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ ('contents', 'Stimfitdocumentation.tex', 'Stimfit Documentation', 'Christoph Schmidt-Hieber \& Jose Guzman', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/dev': None} stimfit-0.16.7/AUTHORS0000664000175000017500000000000014750344764010023 stimfit-0.16.7/configure.ac0000664000175000017500000003045614764352361011260 AC_INIT([stimfit],[0.16.7]) AC_CONFIG_SRCDIR(src/stimfit/gui/main.cpp) AM_INIT_AUTOMAKE([1.11]) AM_SILENT_RULES([yes]) AC_CONFIG_MACRO_DIR([m4]) AC_PROG_CC AC_PROG_INSTALL _LT_SET_OPTION([LT_INIT],[dlopen]) LT_INIT AC_PROG_CPP AC_PROG_AWK AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_MKDIR_P AC_PROG_CXX AC_PROG_LIBTOOL # BUILDDATE=`date` # Build a standalone python module AC_ARG_ENABLE([module], AS_HELP_STRING([--enable-module],[build a standalone python module; implies --enable-python]),[]) AM_CONDITIONAL(BUILD_MODULE, test "$enable_module" = "yes") # pbuilder debian package build AC_ARG_ENABLE([debian], AS_HELP_STRING([--enable-debian],[special build for pbuilder]),[]) AM_CONDITIONAL(BUILD_DEBIAN, test "$enable_debian" = "yes") AC_MSG_CHECKING(for kernel) case `uname` in Darwin) AC_MSG_RESULT(darwin) CXXFLAGS="${CXXFLAGS} -fPIC" CFLAGS="${CFLAGS} -fPIC" STFKERNEL="darwin" ;; *) # treat everything else (kfreebsd, hurd) as linux AC_MSG_RESULT(linux or similar) CXXFLAGS="-fPIC" CFLAGS="-fPIC" STFKERNEL="linux" ;; esac AM_CONDITIONAL([ISDARWIN], [test $STFKERNEL = "darwin"]) # https://stackoverflow.com/questions/11909347/autotools-check-for-c11 AC_MSG_CHECKING(for C++ standard (boost is not required with c++17 and later) ) DIALECT="-std=gnu++17" echo 'int main() {return 0;}' > ./log.cpp && $CXX $DIALECT ./log.cpp || DIALECT="-std=c++17" $CXX $DIALECT ./log.cpp || $DIALECT="no" if test $DIALECT = no; then AC_MSG_RESULT([c++17 not supported - boost is required]) else AC_MSG_RESULT($DIALECT) CXXFLAGS="${CXXFLAGS} ${DIALECT}" fi # Checks for python libraries. AC_ARG_ENABLE([python], AS_HELP_STRING( [--enable-python], [enable python console (default="yes")]),, [enable_python="yes"]) AM_CONDITIONAL(BUILD_PYTHON, test "$enable_python" = "yes") if (test "$enable_python" = "yes") || (test "$enable_module" = "yes"); then AC_PYTHON_DEVEL() AC_PROG_SWIG(1.3.17) SWIG_ENABLE_CXX SWIG_PYTHON AC_SUBST(SWIG) CXXFLAGS="${CXXFLAGS}" CFLAGS="${CFLAGS}" LIBPYTHON_LDFLAGS=$PYTHON_LDFLAGS LIBPYTHON_INCLUDES=$PYTHON_CPPFLAGS LIBNUMPY_INCLUDES=$PYTHON_NUMPY_INCLUDE LIBWXPYTHON_INCLUDES=$PYTHON_WXPYTHON_INCLUDE else LIBPYTHON_LDFLAGS= LIBPYTHON_INCLUDES= LIBNUMPY_INCLUDES= LIBWXPYTHON_INCLUDES= fi AC_SUBST(LIBPYTHON_LDFLAGS) AC_SUBST(LIBPYTHON_INCLUDES) AC_SUBST(LIBNUMPY_INCLUDES) AC_SUBST(LIBWXPYTHON_INCLUDES) AC_MSG_CHECKING(for kernel) case ${STFKERNEL} in darwin) LIBSTF_LDFLAGS="-avoid-version" if test "$enable_module" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DMODULE_ONLY" else CPPFLAGS="${CPPFLAGS}" fi STF_PYTHON_LIBNAME="libpystf.dylib" STFIO_PYTHON_LIBNAME="libpystfio.dylib" ARCH_FLAGS="" CFLAGS="${CFLAGS} ${ARCH_FLAGS}" CXXFLAGS="${CXXFLAGS} ${ARCH_FLAGS}" LDFLAGS="${LDFLAGS} ${ARCH_FLAGS}" OBJCFLAGS="${OBJCFLAGS} ${ARCH_FLAGS}" OBJCXXFLAGS="${OBJCXXFLAGS} ${ARCH_FLAGS}" ;; *) if test "$enable_module" = "yes" ; then LIBSTF_LDFLAGS="-avoid-version" CPPFLAGS="${CPPFLAGS} -DMODULE_ONLY" else if test "$enable_debian" = "yes" ; then LIBSTF_LDFLAGS="-Wl,-rpath,/usr/lib/stimfit -avoid-version" else LIBSTF_LDFLAGS="-Wl,-rpath,${prefix}/lib/stimfit -avoid-version" fi CPPFLAGS="${CPPFLAGS}" fi if test "$enable_debian" = "yes" ; then CPPFLAGS="${CPPFLAGS} `dpkg-buildflags --get CPPFLAGS`" CFLAGS="${CFLAGS} `dpkg-buildflags --get CFLAGS`" CXXFLAGS="${CXXFLAGS} `dpkg-buildflags --get CXXFLAGS`" LDFLAGS="${LDFLAGS} `dpkg-buildflags --get LDFLAGS`" fi STF_PYTHON_LIBNAME="libpystf.so" STFIO_PYTHON_LIBNAME="libpystfio.so" ;; esac AC_SUBST(LIBSTF_LDFLAGS) AC_SUBST(STF_PYTHON_LIBNAME) AC_SUBST(STFIO_PYTHON_LIBNAME) # Checks for python libraries. if test "$enable_python" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DWITH_PYTHON" fi AC_ARG_ENABLE([ipython], AS_HELP_STRING([--enable-ipython],[enable ipython as the default shell (experimental); implies --enable-python]),[]) if test "$enable_ipython" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DIPYTHON" fi # Build the exotic Stimfit flavour with Slope cursors AC_ARG_WITH([pslope], AS_HELP_STRING([--with-pslope],[include slope measure cursors]),[]) if test "$with_pslope" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DWITH_PSLOPE" fi # by default build WITH_BIOSIG AC_ARG_WITH([biosig], [AS_HELP_STRING([--without-biosig], [disable support for biosig])], [], AC_CHECK_LIB([biosig], [sread], [with_biosig="yes"], [with_biosig="no"]) ) AM_CONDITIONAL(WITH_BIOSIG, test "x$with_biosig" = "xyes") AC_ARG_WITH([biosiglite], AS_HELP_STRING([--with-biosiglite], [use builtin biosig library]), []) AM_CONDITIONAL(WITH_BIOSIGLITE, test "x$with_biosiglite" = "xyes") if test "x$with_biosiglite" = xyes ; then CPPFLAGS="${CPPFLAGS} -DWITH_BIOSIG -DWITH_BIOSIGLITE" LIBBIOSIG_LDFLAGS="" # LIBBIOSIG_LDFLAGS="-lcholmod" elif test "x$with_biosig" != xno ; then CPPFLAGS="${CPPFLAGS} -DWITH_BIOSIG" LIBBIOSIG_LDFLAGS="-lbiosig" else AC_MSG_WARN([Stimfit recommends using --with-biosig or --with-biosiglite]) fi AC_SUBST(LIBBIOSIG_LDFLAGS) AC_ARG_WITH([lapack-lib], AS_HELP_STRING([--with-lapack-lib=LAPACKLIB],[Provide full path to custom lapack library]), [ if test "$withval" != "yes" -a "$withval" != ""; then LAPACKLIB=$withval LIBLAPACK_LDFLAGS="$LAPACKLIB" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK" fi ]) AC_CHECK_LIB([fftw3], [fftw_malloc], HAVE_FFTW3="yes") if test "${HAVE_FFTW3}" != "yes" ; then AC_MSG_ERROR([Couldn't find fftw3.]) fi if test "$LAPACKLIB" = ""; then if test "$STFKERNEL" = "darwin" ; then # System LAPACK # LIBLAPACK_LDFLAGS="/usr/lib/liblapack.dylib -framework Accelerate" LIBLAPACK_LDFLAGS="-framework Accelerate" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK -DHAVE_LAPACK_SUFFIX" else AC_CHECK_LIB([openblas], [dgemm_], HAVE_OPENBLAS="yes",, [-lgomp -lpthread -lm]) if test "${HAVE_OPENBLAS}" != "yes" ; then AC_CHECK_LIB([lapack], [dgemm_], HAVE_LAPACKX="yes") if test "${HAVE_LAPACKX}" != "yes" ; then AC_CHECK_LIB([lapack3], [dgemm_], HAVE_LAPACK3="yes") if test "${HAVE_LAPACK3}" != "yes" ; then AC_CHECK_LIB([lapack-3], [dgemm_], HAVE_LAPACK_3="yes") if test "${HAVE_LAPACK_3}" != "yes" ; then AC_CHECK_LIB([blas], [dgemm_], HAVE_ATLAS="yes") LIBLAPACK_LDFLAGS="-llapack -lblas" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " else LIBLAPACK_LDFLAGS="-llapack-3" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " fi else LIBLAPACK_LDFLAGS=-llapack3 CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " fi else LIBLAPACK_LDFLAGS="-llapack -lblas" CPPFLAGS="${CPPFLAGS} -DHAVE_LAPACK " fi else LIBLAPACK_LDFLAGS="-lopenblas" CPPFLAGS="${CPPFLAGS} -DWITH_OPENBLAS -DHAVE_LAPACK" fi fi fi AC_SUBST(LIBLAPACK_LDFLAGS) # stuff not required for standalone module if test "$enable_module" != "yes"; then # Optionally enables aui for doc/view architecture AC_ARG_ENABLE([aui], AS_HELP_STRING([--enable-aui],[enable AUI for the doc/view architecture (experimental)]),[]) if test "$enable_aui" = "yes" ; then CPPFLAGS="${CPPFLAGS} -DWITH_AUIDOCVIEW" fi WXCONFIG=wx-config AC_ARG_WITH(wx-config, [[ --with-wx-config=FILE Use the given path to wx-config when determining wxWidgets configuration; defaults to "wx-config"]], [ if test "$withval" != "yes" -a "$withval" != ""; then WXCONFIG=$withval fi ]) wxversion=0 AC_DEFUN([WXTEST], [ AC_REQUIRE([AC_PROG_AWK]) AC_MSG_CHECKING([wxWidgets version]) if wxversion=`$WXCONFIG --version`; then AC_MSG_RESULT([$wxversion]) else AC_MSG_RESULT([not found]) AC_MSG_ERROR([wxWidgets is required. Try --with-wx-config.]) fi]) # Call WXTEST func WXTEST # Verify minimus requires AC_MSG_CHECKING(for wxWidgets libraries) vers=`echo $wxversion | $AWK 'BEGIN { FS = "."; } { printf "% d", ($1 * 1000 + $2) * 1000 + $3;}'` if test -n "$vers" && test "$vers" -ge 2008000; then WX_CPPFLAGS="`$WXCONFIG --cppflags`" WX_CXXFLAGS="`$WXCONFIG --cxxflags`" if test "$STFKERNEL" = "darwin" ; then if test "${PY_AC_VERSION:0:1}" -ge 3; then WX_LIBS="`$WXCONFIG --libs all`" else WX_LIBS="`$WXCONFIG --libs propgrid,aui,adv,core,net,base`" fi else WX_LIBS="`$WXCONFIG --libs base,core,adv,aui,net`" fi AC_MSG_RESULT([$WX_LIBS]) else AC_MSG_ERROR([wxWidgets 2.8.0 or newer is required]) fi # CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" # CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS" dnl included in cppflags AC_SUBST(WX_LIBS) AC_SUBST(WX_CPPFLAGS) AC_SUBST(WX_CXXFLAGS) dnl default value is to (silently) do nothing in the makefile POSTLINK_COMMAND="@true" MACSETFILE="@true" AC_MSG_CHECKING(for wxWidgets platform) WX_BASENAME="`$WXCONFIG --basename`" case $WX_BASENAME in *wx_osx*) AC_MSG_RESULT($WX_BASENAME) AC_CHECK_PROG(REZ, Rez, Rez, /Developer/Tools/Rez) POSTLINK_COMMAND="\$(REZ) -d __DARWIN__ -t APPL -o" AC_CHECK_PROG(SETFILE, SetFile, SetFile, /Developer/Tools/SetFile) MACSETFILE="\$(SETFILE)" ;; *wx_mac*) AC_MSG_RESULT($WX_BASENAME) AC_CHECK_PROG(REZ, Rez, Rez, /Developer/Tools/Rez) POSTLINK_COMMAND="\$(REZ) -d __DARWIN__ -t APPL -o" AC_CHECK_PROG(SETFILE, SetFile, SetFile, /Developer/Tools/SetFile) MACSETFILE="\$(SETFILE)" ;; *) AC_MSG_RESULT(other) ;; esac AC_SUBST(POSTLINK_COMMAND) AC_SUBST(MACSETFILE) fi # Checks for hdf5 libraries. AC_ARG_WITH([hdf5-prefix], AS_HELP_STRING([--with-hdf5-prefix=HDF5_PREFIX],[Provide full path to hdf5 prefix]), [ if test "$withval" != "yes" -a "$withval" != ""; then HDF5_PREFIX=${withval} LDFLAGS="${LDFLAGS} -L${HDF5_PREFIX}/lib" CPPFLAGS="${CPPFLAGS} -I${HDF5_PREFIX}/include" fi ]) if test "${HDF5PREFIX}" = ""; then if test "$STFKERNEL" = "linux" ; then PKG_CHECK_MODULES([HDF5], [hdf5], [ CPPFLAGS="${CPPFLAGS} ${HDF5_CFLAGS} -DH5_USE_16_API" LIBHDF5_LDFLAGS="${HDF5_LIBS} -lhdf5_hl" LDFLAGS="${LDFLAGS} ${LIBHDF5_LDFLAGS}" ], [ HDF5_CFLAGS="" HDF5_LIBS="" ]) fi fi AC_CHECK_HEADER([hdf5.h], [], [AC_MSG_ERROR([Couldn't find hdf5 header])]) AC_CHECK_LIB([hdf5],[H5Fopen],HAVE_HDF5="yes") if test "${HDF5_CFLAGS}" = ""; then CPPFLAGS="${CPPFLAGS} -DH5_USE_16_API" LIBHDF5_LDFLAGS="-lhdf5 -lhdf5_hl" fi AC_SUBST(LIBHDF5_LDFLAGS) AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug],[build stimfit in debug mode]),[ ]) if test "$enable_debug" = "yes" ; then CPPFLAGS="${CPPFLAGS} -D_STFDEBUG " OPT_CXXFLAGS="-O0 -g3" CFLAGS="${CFLAGS} -O0 -g3" else OPT_CXXFLAGS="-O2 -g" CFLAGS="${CFLAGS} -O2 -g" fi AC_SUBST(OPT_CXXFLAGS) # gtest GT_CPPFLAGS="" GT_CXXFLAGS="" GT_LIBS="-lpthread" GT_LDFLAGS="" AC_SUBST(GT_CPPFLAGS) AC_SUBST(GT_CXXFLAGS) AC_SUBST(GT_LIBS) AC_SUBST(GT_LDFLAGS) # end gtest # CPPFLAGS="${CPPFLAGS} -DSTFDATE='\"${BUILDDATE}\"'" CXXFLAGS="${CXXFLAGS} -Wall" AC_CONFIG_HEADERS([stfconf.h]) AC_CONFIG_FILES([Makefile src/Makefile src/libstfio/Makefile src/libstfnum/Makefile src/libbiosiglite/Makefile src/pystfio/Makefile src/stimfit/Makefile src/stimfit/py/Makefile dist/macosx/stimfit.plist dist/macosx/macports/insert_checksums.sh dist/macosx/scripts/mkimage.sh dist/macosx/package.pmdoc/index.xml dist/debian/mkdeb.sh dist/debian/mkquick.sh setup.py dist/conda/py-stfio-debug/meta.yaml dist/conda/py-stfio/meta.yaml doc/Doxyfile doc/sphinx/conf.py Makefile.static ]) AC_OUTPUT stimfit-0.16.7/COPYING0000664000175000017500000004313114750344764010022 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. stimfit-0.16.7/m4/0000775000175000017500000000000014764352500007355 5stimfit-0.16.7/m4/ltoptions.m40000644000175000017500000003427514764352406011610 # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # 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. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [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], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [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], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [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], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) stimfit-0.16.7/m4/acsite.m40000775000175000017500000004206114751351322011012 AC_DEFUN([AC_PYTHON_DEVEL],[ # # Allow the use of a (user set) custom python version # AC_ARG_VAR([PYTHON_VERSION],[The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name.]) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path]) PYTHON_VERSION="" fi # # Check for a version of Python >= 2.1.0 # AC_MSG_CHECKING([for a version of Python >= '2.1.0']) ac_supports_python_ver=`$PYTHON -c "import sys, string; \ ver = sys.version.split()[[0]]; \ print(ver >= '2.1.0')"` if test "$ac_supports_python_ver" != "True"; then if test -z "$PYTHON_NOVERSIONCHECK"; then AC_MSG_RESULT([no]) AC_MSG_FAILURE([ This version of the AC@&t@_PYTHON_DEVEL macro doesn't work properly with versions of Python before 2.1.0. You may need to re-run configure, setting the variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG, PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand. Moreover, to disable this check, set PYTHON_NOVERSIONCHECK to something else than an empty string. ]) else AC_MSG_RESULT([skip at user request]) fi else AC_MSG_RESULT([yes]) fi # # if the macro parameter ``version'' is set, honour it # if test -n "$1"; then AC_MSG_CHECKING([for a version of Python $1]) ac_supports_python_ver=`$PYTHON -c "import sys, string; \ ver = sys.version.split()[[0]]; \ sys.stdout.write(ver + '$1' + '\n')"` if test "$ac_supports_python_ver" = "True"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) AC_MSG_ERROR([this package requires Python $1. If you have it installed, but it isn't the default Python interpreter in your system path, please pass the PYTHON_VERSION variable to configure. See ``configure --help'' for reference. ]) PYTHON_VERSION="" fi fi # # Check if you have distutils, else fail # AC_MSG_CHECKING([for the distutils Python package]) ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` if test $? -eq 0; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot import Python module "distutils". Please check your Python installation. The error was: $ac_distutils_result]) PYTHON_VERSION="" fi # # Check for Python include path # AC_MSG_CHECKING([for Python include path]) if test -z "$PYTHON_CPPFLAGS"; then python_path=`$PYTHON -c "import distutils.sysconfig, sys; \ sys.stdout.write(distutils.sysconfig.get_python_inc() + '\n');"` if test -n "${python_path}"; then python_path="-I$python_path" fi PYTHON_CPPFLAGS=$python_path fi AC_MSG_RESULT([$PYTHON_CPPFLAGS]) AC_SUBST([PYTHON_CPPFLAGS]) # # Check for Python library path # # # Check for Python library path # AC_MSG_CHECKING([for Python library path]) if test -z "$PYTHON_LDFLAGS"; then # (makes two attempts to ensure we've got a version number # from the interpreter) py_version=`$PYTHON -c \ "import sys; from distutils.sysconfig import * if get_config_vars('LDVERSION')[[0]] is None: sys.stdout.write(' '.join(get_config_vars('VERSION'))+'\n') else: sys.stdout.write(' '.join(get_config_vars('LDVERSION'))+'\n')"` if test "$py_version" == "[None]"; then if test -n "$PYTHON_VERSION"; then py_version=$PYTHON_VERSION else py_version=`$PYTHON -c "import sys; \ sys.stdout.write(sys.version[[:3]] + '\n')"` fi fi PY_AC_VERSION=$py_version PYTHON_LDFLAGS=`$PYTHON -c "import sys; from distutils.sysconfig import *; \ sys.stdout.write('-L' + get_config_vars()[['LIBDIR']] + \ ' -lpython' + '\n');"`$py_version fi AC_MSG_RESULT([$PYTHON_LDFLAGS]) AC_SUBST([PYTHON_LDFLAGS]) AC_SUBST([PY_AC_VERSION]) # # Check for prefixed site packages # AC_MSG_CHECKING([for prefixed Python site-packages path]) if test -z "$PYTHON_SITE_PKG"; then PYTHON_SITE_PKG=`$PYTHON -c \ "import sys, distutils.sysconfig; \ acprefix = \"${prefix}\" if acprefix is \"NONE\": acprefix=\"/usr/local/\" sys.stdout.write(distutils.sysconfig.get_python_lib(0,1,prefix=acprefix)+'\n');"` PYTHON_SITE_PKG="${PYTHON_SITE_PKG}/dist-packages" fi AC_MSG_RESULT([$PYTHON_SITE_PKG]) AC_SUBST([PYTHON_SITE_PKG]) # # Check for prefixed dist packages # AC_MSG_CHECKING([for prefixed Python dist-packages path]) if test -z "$PYTHON_PRE_DIST_PKG"; then PYTHON_PRE_DIST_PKG=`$PYTHON -c \ "import sys, distutils.sysconfig; \ acprefix = \"${prefix}\" if acprefix is \"NONE\": acprefix=\"/usr/local/\" sys.stdout.write(distutils.sysconfig.get_python_lib(0,0,prefix=acprefix)+'\n');"` PYTHON_PRE_DIST_PKG=${PYTHON_PRE_DIST_PKG} fi AC_MSG_RESULT([$PYTHON_PRE_DIST_PKG]) AC_SUBST([PYTHON_PRE_DIST_PKG]) # # Check for unprefixed dist packages path # AC_MSG_CHECKING([for unprefixed Python dist-packages path]) if test -z "$PYTHON_DIST_PKG"; then PYTHON_DIST_PKG=`$PYTHON -c \ "import sys, distutils.sysconfig; \ sys.stdout.write(distutils.sysconfig.get_python_lib(0,0)+'\n');"` PYTHON_DIST_PKG=${PYTHON_DIST_PKG} fi AC_MSG_RESULT([$PYTHON_DIST_PKG]) AC_SUBST([PYTHON_DIST_PKG]) # # Check if you have numpy, else fail # AC_MSG_CHECKING([for numpy]) ac_numpy_result=`$PYTHON -c "import numpy" 2>&1` if test -z "$ac_numpy_result"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot import Python module "numpy". Please check your numpy installation. The error was: $ac_numpy_result]) PYTHON_VERSION="" fi # # Check for numpy headers # AC_MSG_CHECKING([for numpy include path]) if test -z "$PYTHON_NUMPY_INCLUDE"; then PYTHON_NUMPY_INCLUDE=-I`$PYTHON -c "import sys, numpy; \ sys.stdout.write(numpy.get_include() + '\n');"` fi AC_MSG_RESULT([$PYTHON_NUMPY_INCLUDE]) AC_SUBST([PYTHON_NUMPY_INCLUDE]) # # Check if you have wxPython, else fail # AC_MSG_CHECKING([for wxPython]) ac_wxpython_result=`$PYTHON -c "import wx" 2>&1` if test -z "$ac_wxpython_result"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot import Python module "wxpython". Please check your wxpython installation. The error was: $ac_wxpython_result]) PYTHON_VERSION="" fi # # Check for wxpython headers # AC_MSG_CHECKING([for wxpython include path]) if test -z "$PYTHON_WXPYTHON_INCLUDE"; then PYTHON_WXPYTHON_INCLUDE=-I`$PYTHON -c "import os, sys, wx; \ sys.stdout.write(os.path.join(os.path.dirname(wx.__spec__.origin), 'include') + '\n');"` fi AC_MSG_RESULT([$PYTHON_WXPYTHON_INCLUDE]) AC_SUBST([PYTHON_WXPYTHON_INCLUDE]) # # libraries which must be linked in when embedding # AC_MSG_CHECKING(python extra libraries) if test -z "$PYTHON_EXTRA_LIBS"; then PYTHON_EXTRA_LIBS=`$PYTHON -c "import sys, distutils.sysconfig; \ conf = distutils.sysconfig.get_config_var; \ sys.stdout.write(conf('LOCALMODLIBS') + ' ' + conf('LIBS') + ' ' + '\n')"` fi AC_MSG_RESULT([$PYTHON_EXTRA_LIBS]) AC_SUBST(PYTHON_EXTRA_LIBS) # # linking flags needed when embedding # AC_MSG_CHECKING(python extra linking flags) if test -z "$PYTHON_EXTRA_LDFLAGS"; then PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import sys, distutils.sysconfig; \ conf = distutils.sysconfig.get_config_var; \ sys.stdout.write(conf('LINKFORSHARED')+'\n')"` fi AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) AC_SUBST(PYTHON_EXTRA_LDFLAGS) # # final check to see if everything compiles alright # AC_MSG_CHECKING([consistency of all components of python development environment]) AC_LANG_PUSH([C]) # save current global flags LIBS="$ac_save_LIBS $PYTHON_LDFLAGS -lm" CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS" AC_TRY_LINK([ #include ],[ Py_Initialize(); ],[pythonexists=yes],[pythonexists=no]) AC_MSG_RESULT([$pythonexists]) if test ! "$pythonexists" = "yes"; then AC_MSG_ERROR([ Could not link test program to Python. Maybe the main Python library has been installed in some non-standard library path. If so, pass it to configure, via the LDFLAGS environment variable. Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib" ============================================================================ ERROR! You probably have to install the development version of the Python package for your distribution. The exact name of this package varies among them. ============================================================================ ]) PYTHON_VERSION="" fi AC_LANG_POP # turn back to default flags CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" # # all done! # ]) ##### http://autoconf-archive.cryp.to/ac_pkg_swig.html # # SYNOPSIS # # AC_PROG_SWIG([major.minor.micro]) # # DESCRIPTION # # This macro searches for a SWIG installation on your system. If # found you should call SWIG via $(SWIG). You can use the optional # first argument to check if the version of the available SWIG is # greater than or equal to the value of the argument. It should have # the format: N[.N[.N]] (N is a number between 0 and 999. Only the # first N is mandatory.) # # If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks # that the swig package is this version number or higher. # # In configure.in, use as: # # AC_PROG_SWIG(1.3.17) # SWIG_ENABLE_CXX # SWIG_MULTI_MODULE_SUPPORT # SWIG_PYTHON # # LAST MODIFICATION # # 2006-10-22 # # COPYLEFT # # Copyright (c) 2006 Sebastian Huber # Copyright (c) 2006 Alan W. Irwin # Copyright (c) 2006 Rafael Laboissiere # Copyright (c) 2006 Andrew Collier # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # # As a special exception, the respective Autoconf Macro's copyright # owner gives unlimited permission to copy, distribute and modify the # configure scripts that are the output of Autoconf when processing # the Macro. You need not follow the terms of the GNU General Public # License when using or distributing such scripts, even though # portions of the text of the Macro appear in them. The GNU General # Public License (GPL) does govern all other use of the material that # constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the # Autoconf Macro released by the Autoconf Macro Archive. When you # make and distribute a modified version of the Autoconf Macro, you # may extend this special exception to the GPL to apply to your # modified version as well. AC_DEFUN([AC_PROG_SWIG],[ AC_PATH_PROG([SWIG],[swig]) if test -z "$SWIG" ; then AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org]) SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false' elif test -n "$1" ; then AC_MSG_CHECKING([for SWIG version]) [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`] AC_MSG_RESULT([$swig_version]) if test -n "$swig_version" ; then # Calculate the required version number components [required=$1] [required_major=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_major" ; then [required_major=0] fi [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] [required_minor=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_minor" ; then [required_minor=0] fi [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] [required_patch=`echo $required | sed 's/[^0-9].*//'`] if test -z "$required_patch" ; then [required_patch=0] fi # Calculate the available version number components [available=$swig_version] [available_major=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_major" ; then [available_major=0] fi [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] [available_minor=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_minor" ; then [available_minor=0] fi [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] [available_patch=`echo $available | sed 's/[^0-9].*//'`] if test -z "$available_patch" ; then [available_patch=0] fi if test $available_major -ne $required_major \ -o $available_minor -ne $required_minor \ -o $available_patch -lt $required_patch ; then if test $available_major -lt $required_major ; then AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org]) SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false' fi else AC_MSG_NOTICE([SWIG executable is '$SWIG']) SWIG_LIB=`$SWIG -swiglib` AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB']) fi else AC_MSG_WARN([cannot determine SWIG version]) SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false' fi fi AC_SUBST([SWIG_LIB]) ]) AC_DEFUN([SWIG_ENABLE_CXX],[ AC_REQUIRE([AC_PROG_SWIG]) AC_REQUIRE([AC_PROG_CXX]) SWIG="$SWIG -c++" ]) AC_DEFUN([SWIG_PYTHON],[ AC_REQUIRE([AC_PROG_SWIG]) AC_REQUIRE([AC_PYTHON_DEVEL]) test "x$1" != "xno" || swig_shadow=" -noproxy" AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow]) AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS]) ]) stimfit-0.16.7/m4/lt~obsolete.m40000644000175000017500000001400714764352406012116 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # 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. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) stimfit-0.16.7/m4/libtool.m40000644000175000017500000113165214764352406011217 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # 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. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # 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 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 this program. If not, see . ]) # serial 59 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl 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 set != "${COLLECT_NAMES+set}"; 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 and # ICC, which need '.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 _LT_CC_BASENAME([$compiler]) # 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 _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# 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' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # 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' _LT_CONFIG_STATUS_DECLARATIONS 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 lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that 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 # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _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 set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # 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 '$q' "$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" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # 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 ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl 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* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl 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* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [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" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [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" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $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*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; 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 no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="$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" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$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_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$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 _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`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 "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # 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*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ 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" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || 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 what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD 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* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD 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" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) 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 ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS _LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. _LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # 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 bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # 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\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD 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 $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" 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>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl 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; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # 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 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; 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" && \ test undefined != "$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`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 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 ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "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 -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 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 AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; 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 AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && 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" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) 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 _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=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\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD 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_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $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* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) 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 AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [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]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # 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 no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -z "$STRIP"; then AC_MSG_RESULT([no]) else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; 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` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac 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" elif test -n "$lt_multi_os_dir"; then 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 AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; 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 # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # 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' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # 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' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac 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%'\''`; $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 # correct to gnu/linux during the next big refactor 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,$cc_basename in yes,*) # gcc 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' m4_if([$1], [],[ 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 dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # 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' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # 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`' m4_if([$1], [],[ 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 # correct to gnu/linux during the next big refactor 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* | midnightbsd*) # 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$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' 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 # correct to gnu/linux during the next big refactor 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=no 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 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; 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 # correct to gnu/linux during the next big refactor 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 yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor 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 ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # 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 dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor 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 AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) 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 # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) 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' ;; netbsdelf*-gnu) 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=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_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 # correct to gnu/linux during the next big refactor 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* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi 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 shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec 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' ;; 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 # correct to gnu/linux during the next big refactor 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 yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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=sco 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 yes = "$with_gnu_ld"; 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 # correct to gnu/linux during the next big refactor 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 # correct to gnu/linux during the next big refactor 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 ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[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]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [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 dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" 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]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) 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 yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [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 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [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 # that 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='$FILECMD -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. if ( 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 # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' 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* | midnightbsd*) 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=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD 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 glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) 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=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; 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 ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi 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 _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$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 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=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_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 # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) 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]) if test no != "$lt_cv_path_NM"; 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 AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # 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 ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; 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 if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # 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"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$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"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/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, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,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 lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # 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 AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && 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 /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #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. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$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_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) 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 AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-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_TAGVAR(lt_prog_compiler_pic, $1)='-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 m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; 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_TAGVAR(lt_prog_compiler_pic, $1)=-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_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--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 ;; 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). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+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_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-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_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-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_TAGVAR(lt_prog_compiler_pic, $1)='-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 m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; 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_TAGVAR(lt_prog_compiler_pic, $1)='-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_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; 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). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-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_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] 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 GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # 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'. _LT_TAGVAR(exclude_expsyms, $1)=['_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. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=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 yes = "$with_gnu_ld"; 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 yes = "$lt_use_gnu_ld_interface"; 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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$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 _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 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 ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=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 _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$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)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$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, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); 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 _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$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. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$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) tmp_diet=no if test linux-dietlibc = "$host_os"; 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 no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$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 _LT_TAGVAR(whole_archive_flag_spec, $1)='$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 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-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 _LT_TAGVAR(whole_archive_flag_spec, $1)='$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' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$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' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='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 tcc*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='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 $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $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 _LT_TAGVAR(ld_shlibs, $1)=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 _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** 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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$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. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; 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 GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | 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 # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; 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. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; 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 _LT_TAGVAR(hardcode_direct, $1)=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 _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; 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 yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$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. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$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. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$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. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$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)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # 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. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=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. _LT_TAGVAR(archive_cmds, $1)='$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. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=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*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # 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) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_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' # 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. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_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 $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$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' _LT_TAGVAR(archive_expsym_cmds, $1)='$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 _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$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 _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$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 _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_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' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$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' _LT_TAGVAR(archive_expsym_cmds, $1)='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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $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='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='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' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=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 yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT 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. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) 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. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [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]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$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);}' _LT_TAG_COMPILER # 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 _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## 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_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && 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 yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$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 yes != "$_lt_caught_CXX_error"; 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. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS 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++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_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 yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$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' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$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 _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= 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. _LT_TAGVAR(archive_cmds, $1)='$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 AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; 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 # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive 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 if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; 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. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; 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 _LT_TAGVAR(hardcode_direct, $1)=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 _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; 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 yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$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. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$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. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$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. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # 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. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$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, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); 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 _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=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 _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$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 yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=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 _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$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 yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $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 _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$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. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$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++ _LT_TAGVAR(archive_cmds, $1)='$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. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -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 _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -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 _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | 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. _LT_TAGVAR(archive_cmds, $1)='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' _LT_TAGVAR(archive_expsym_cmds, $1)='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"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$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."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$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 _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='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`"' _LT_TAGVAR(old_archive_cmds, $1)='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' _LT_TAGVAR(archive_cmds, $1)='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' _LT_TAGVAR(archive_expsym_cmds, $1)='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 _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$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++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # 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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='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 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$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' _LT_TAGVAR(compiler_needs_object, $1)=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. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=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*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=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. _LT_TAGVAR(archive_cmds, $1)='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' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$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' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$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' _LT_TAGVAR(archive_expsym_cmds, $1)='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' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # 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 yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$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' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # 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 _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='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' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=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?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=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. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$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. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -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. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='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 $wl-h $wl$soname -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 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT 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. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$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 _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$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... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS 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 yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf 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). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); 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 $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev 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 "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $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 "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$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 no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [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. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 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 yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && 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 yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$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... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC 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 yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && 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 yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$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... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## 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_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## 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_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_FILECMD # ---------------- # Check for a file(cmd) program that can be used to detect file type and magic m4_defun([_LT_DECL_FILECMD], [AC_CHECK_TOOL([FILECMD], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ])# _LD_DECL_FILECMD # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # 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 _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS stimfit-0.16.7/m4/ltversion.m40000644000175000017500000000131214764352406011564 # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, # Inc. # Written by Scott James Remnant, 2004 # # 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. # @configure_input@ # serial 4245 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.7]) m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.7' macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) stimfit-0.16.7/m4/ltsugar.m40000644000175000017500000001045314764352406011226 # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # 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. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) stimfit-0.16.7/config.guess0000755000175000017500000014051214764352410011276 #! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-09' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_X32 >/dev/null then LIBCABI=${LIBC}x32 fi fi GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; x86_64:Haiku:*:*) GUESS=x86_64-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&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` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: stimfit-0.16.7/autogen.sh0000775000175000017500000013443114750344764010774 #!/bin/sh # a u t o g e n . s h # # Copyright (c) 2005-2009 United States Government as represented by # the U.S. Army Research Laboratory. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # 3. The name of the author may not be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. # ### # # Script for automatically preparing the sources for compilation by # performing the myriad of necessary steps. The script attempts to # detect proper version support, and outputs warnings about particular # systems that have autotool peculiarities. # # Basically, if everything is set up and installed correctly, the # script will validate that minimum versions of the GNU Build System # tools are installed, account for several common configuration # issues, and then simply run autoreconf for you. # # If autoreconf fails, which can happen for many valid configurations, # this script proceeds to run manual preparation steps effectively # providing a POSIX shell script (mostly complete) reimplementation of # autoreconf. # # The AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER # environment variables and corresponding _OPTIONS variables (e.g. # AUTORECONF_OPTIONS) may be used to override the default automatic # detection behaviors. Similarly the _VERSION variables will override # the minimum required version numbers. # # Examples: # # To obtain help on usage: # ./autogen.sh --help # # To obtain verbose output: # ./autogen.sh --verbose # # To skip autoreconf and prepare manually: # AUTORECONF=false ./autogen.sh # # To verbosely try running with an older (unsupported) autoconf: # AUTOCONF_VERSION=2.50 ./autogen.sh --verbose # # Author: # Christopher Sean Morrison # # Patches: # Sebastian Pipping # ###################################################################### # set to minimum acceptable version of autoconf if [ "x$AUTOCONF_VERSION" = "x" ] ; then AUTOCONF_VERSION=2.52 fi # set to minimum acceptable version of automake if [ "x$AUTOMAKE_VERSION" = "x" ] ; then AUTOMAKE_VERSION=1.11 fi # set to minimum acceptable version of libtool if [ "x$LIBTOOL_VERSION" = "x" ] ; then LIBTOOL_VERSION=1.4.2 fi ################## # ident function # ################## ident ( ) { # extract copyright from header __copyright="`grep Copyright $AUTOGEN_SH | head -${HEAD_N}1 | awk '{print $4}'`" if [ "x$__copyright" = "x" ] ; then __copyright="`date +%Y`" fi # extract version from CVS Id string __id="$Id: autogen.sh 33925 2009-03-01 23:27:06Z brlcad $" __version="`echo $__id | sed 's/.*\([0-9][0-9][0-9][0-9]\)[-\/]\([0-9][0-9]\)[-\/]\([0-9][0-9]\).*/\1\2\3/'`" if [ "x$__version" = "x" ] ; then __version="" fi echo "autogen.sh build preparation script by Christopher Sean Morrison" echo " + config.guess download patch by Sebastian Pipping (2008-12-03)" echo "revised 3-clause BSD-style license, copyright (c) $__copyright" echo "script version $__version, ISO/IEC 9945 POSIX shell script" } ################## # USAGE FUNCTION # ################## usage ( ) { echo "Usage: $AUTOGEN_SH [-h|--help] [-v|--verbose] [-q|--quiet] [-d|--download] [--version]" echo " --help Help on $NAME_OF_AUTOGEN usage" echo " --verbose Verbose progress output" echo " --quiet Quiet suppressed progress output" echo " --download Download the latest config.guess from gnulib" echo " --version Only perform GNU Build System version checks" echo echo "Description: This script will validate that minimum versions of the" echo "GNU Build System tools are installed and then run autoreconf for you." echo "Should autoreconf fail, manual preparation steps will be run" echo "potentially accounting for several common preparation issues. The" echo "AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER," echo "PROJECT, & CONFIGURE environment variables and corresponding _OPTIONS" echo "variables (e.g. AUTORECONF_OPTIONS) may be used to override the" echo "default automatic detection behavior." echo ident return 0 } ########################## # VERSION_ERROR FUNCTION # ########################## version_error ( ) { if [ "x$1" = "x" ] ; then echo "INTERNAL ERROR: version_error was not provided a version" exit 1 fi if [ "x$2" = "x" ] ; then echo "INTERNAL ERROR: version_error was not provided an application name" exit 1 fi $ECHO $ECHO "ERROR: To prepare the ${PROJECT} build system from scratch," $ECHO " at least version $1 of $2 must be installed." $ECHO $ECHO "$NAME_OF_AUTOGEN does not need to be run on the same machine that will" $ECHO "run configure or make. Either the GNU Autotools will need to be installed" $ECHO "or upgraded on this system, or $NAME_OF_AUTOGEN must be run on the source" $ECHO "code on another system and then transferred to here. -- Cheers!" $ECHO } ########################## # VERSION_CHECK FUNCTION # ########################## version_check ( ) { if [ "x$1" = "x" ] ; then echo "INTERNAL ERROR: version_check was not provided a minimum version" exit 1 fi _min="$1" if [ "x$2" = "x" ] ; then echo "INTERNAL ERROR: version check was not provided a comparison version" exit 1 fi _cur="$2" # needed to handle versions like 1.10 and 1.4-p6 _min="`echo ${_min}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`" _cur="`echo ${_cur}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`" _min_major="`echo $_min | cut -d. -f1`" _min_minor="`echo $_min | cut -d. -f2`" _min_patch="`echo $_min | cut -d. -f3`" _cur_major="`echo $_cur | cut -d. -f1`" _cur_minor="`echo $_cur | cut -d. -f2`" _cur_patch="`echo $_cur | cut -d. -f3`" if [ "x$_min_major" = "x" ] ; then _min_major=0 fi if [ "x$_min_minor" = "x" ] ; then _min_minor=0 fi if [ "x$_min_patch" = "x" ] ; then _min_patch=0 fi if [ "x$_cur_minor" = "x" ] ; then _cur_major=0 fi if [ "x$_cur_minor" = "x" ] ; then _cur_minor=0 fi if [ "x$_cur_patch" = "x" ] ; then _cur_patch=0 fi $VERBOSE_ECHO "Checking if ${_cur_major}.${_cur_minor}.${_cur_patch} is greater than ${_min_major}.${_min_minor}.${_min_patch}" if [ $_min_major -lt $_cur_major ] ; then return 0 elif [ $_min_major -eq $_cur_major ] ; then if [ $_min_minor -lt $_cur_minor ] ; then return 0 elif [ $_min_minor -eq $_cur_minor ] ; then if [ $_min_patch -lt $_cur_patch ] ; then return 0 elif [ $_min_patch -eq $_cur_patch ] ; then return 0 fi fi fi return 1 } ###################################### # LOCATE_CONFIGURE_TEMPLATE FUNCTION # ###################################### locate_configure_template ( ) { _pwd="`pwd`" if test -f "./configure.ac" ; then echo "./configure.ac" elif test -f "./configure.in" ; then echo "./configure.in" elif test -f "$_pwd/configure.ac" ; then echo "$_pwd/configure.ac" elif test -f "$_pwd/configure.in" ; then echo "$_pwd/configure.in" elif test -f "$PATH_TO_AUTOGEN/configure.ac" ; then echo "$PATH_TO_AUTOGEN/configure.ac" elif test -f "$PATH_TO_AUTOGEN/configure.in" ; then echo "$PATH_TO_AUTOGEN/configure.in" fi } ################## # argument check # ################## ARGS="$*" PATH_TO_AUTOGEN="`dirname $0`" NAME_OF_AUTOGEN="`basename $0`" AUTOGEN_SH="$PATH_TO_AUTOGEN/$NAME_OF_AUTOGEN" LIBTOOL_M4="${PATH_TO_AUTOGEN}/misc/libtool.m4" if [ "x$HELP" = "x" ] ; then HELP=no fi if [ "x$QUIET" = "x" ] ; then QUIET=no fi if [ "x$VERBOSE" = "x" ] ; then VERBOSE=no fi if [ "x$VERSION_ONLY" = "x" ] ; then VERSION_ONLY=no fi if [ "x$DOWNLOAD" = "x" ] ; then DOWNLOAD=no fi if [ "x$AUTORECONF_OPTIONS" = "x" ] ; then AUTORECONF_OPTIONS="-i -f" fi if [ "x$AUTOCONF_OPTIONS" = "x" ] ; then AUTOCONF_OPTIONS="-f" fi if [ "x$AUTOMAKE_OPTIONS" = "x" ] ; then AUTOMAKE_OPTIONS="-a -c -f" fi ALT_AUTOMAKE_OPTIONS="-a -c" if [ "x$LIBTOOLIZE_OPTIONS" = "x" ] ; then LIBTOOLIZE_OPTIONS="--automake -c -f" fi ALT_LIBTOOLIZE_OPTIONS="--automake --copy --force" if [ "x$ACLOCAL_OPTIONS" = "x" ] ; then ACLOCAL_OPTIONS="" fi if [ "x$AUTOHEADER_OPTIONS" = "x" ] ; then AUTOHEADER_OPTIONS="" fi if [ "x$CONFIG_GUESS_URL" = "x" ] ; then CONFIG_GUESS_URL="http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob_plain;f=build-aux/config.guess;hb=HEAD" fi for arg in $ARGS ; do case "x$arg" in x--help) HELP=yes ;; x-[hH]) HELP=yes ;; x--quiet) QUIET=yes ;; x-[qQ]) QUIET=yes ;; x--verbose) VERBOSE=yes ;; x-[dD]) DOWNLOAD=yes ;; x--download) DOWNLOAD=yes ;; x-[vV]) VERBOSE=yes ;; x--version) VERSION_ONLY=yes ;; *) echo "Unknown option: $arg" echo usage exit 1 ;; esac done ##################### # environment check # ##################### # sanity check before recursions potentially begin if [ ! -f "$AUTOGEN_SH" ] ; then echo "INTERNAL ERROR: $AUTOGEN_SH does not exist" if [ ! "x$0" = "x$AUTOGEN_SH" ] ; then echo "INTERNAL ERROR: dirname/basename inconsistency: $0 != $AUTOGEN_SH" fi exit 1 fi # force locale setting to C so things like date output as expected LC_ALL=C # commands that this script expects for __cmd in echo head tail pwd ; do echo "test" | $__cmd > /dev/null 2>&1 if [ $? != 0 ] ; then echo "INTERNAL ERROR: '${__cmd}' command is required" exit 2 fi done echo "test" | grep "test" > /dev/null 2>&1 if test ! x$? = x0 ; then echo "INTERNAL ERROR: grep command is required" exit 1 fi echo "test" | sed "s/test/test/" > /dev/null 2>&1 if test ! x$? = x0 ; then echo "INTERNAL ERROR: sed command is required" exit 1 fi # determine the behavior of echo case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac # determine the behavior of head case "x`echo 'head' | head -n 1 2>&1`" in *xhead*) HEAD_N="n " ;; *) HEAD_N="" ;; esac # determine the behavior of tail case "x`echo 'tail' | tail -n 1 2>&1`" in *xtail*) TAIL_N="n " ;; *) TAIL_N="" ;; esac VERBOSE_ECHO=: ECHO=: if [ "x$QUIET" = "xyes" ] ; then if [ "x$VERBOSE" = "xyes" ] ; then echo "Verbose output quelled by quiet option. Further output disabled." fi else ECHO=echo if [ "x$VERBOSE" = "xyes" ] ; then echo "Verbose output enabled" VERBOSE_ECHO=echo fi fi # allow a recursive run to disable further recursions if [ "x$RUN_RECURSIVE" = "x" ] ; then RUN_RECURSIVE=yes fi ################################################ # check for help arg and bypass version checks # ################################################ if [ "x`echo $ARGS | sed 's/.*[hH][eE][lL][pP].*/help/'`" = "xhelp" ] ; then HELP=yes fi if [ "x$HELP" = "xyes" ] ; then usage $ECHO "---" $ECHO "Help was requested. No preparation or configuration will be performed." exit 0 fi ####################### # set up signal traps # ####################### untrap_abnormal ( ) { for sig in 1 2 13 15; do trap - $sig done } # do this cleanup whenever we exit. trap ' # start from the root if test -d "$START_PATH" ; then cd "$START_PATH" fi # restore/delete backup files if test "x$PFC_INIT" = "x1" ; then recursive_restore fi ' 0 # trap SIGHUP (1), SIGINT (2), SIGPIPE (13), SIGTERM (15) for sig in 1 2 13 15; do trap ' $ECHO "" $ECHO "Aborting $NAME_OF_AUTOGEN: caught signal '$sig'" # start from the root if test -d "$START_PATH" ; then cd "$START_PATH" fi # clean up on abnormal exit $VERBOSE_ECHO "rm -rf autom4te.cache" rm -rf autom4te.cache if test -f "acinclude.m4.$$.backup" ; then $VERBOSE_ECHO "cat acinclude.m4.$$.backup > acinclude.m4" chmod u+w acinclude.m4 cat acinclude.m4.$$.backup > acinclude.m4 $VERBOSE_ECHO "rm -f acinclude.m4.$$.backup" rm -f acinclude.m4.$$.backup fi { (exit 1); exit 1; } ' $sig done ############################# # look for a configure file # ############################# if [ "x$CONFIGURE" = "x" ] ; then CONFIGURE="`locate_configure_template`" if [ ! "x$CONFIGURE" = "x" ] ; then $VERBOSE_ECHO "Found a configure template: $CONFIGURE" fi else $ECHO "Using CONFIGURE environment variable override: $CONFIGURE" fi if [ "x$CONFIGURE" = "x" ] ; then if [ "x$VERSION_ONLY" = "xyes" ] ; then CONFIGURE=/dev/null else $ECHO $ECHO "A configure.ac or configure.in file could not be located implying" $ECHO "that the GNU Build System is at least not used in this directory. In" $ECHO "any case, there is nothing to do here without one of those files." $ECHO $ECHO "ERROR: No configure.in or configure.ac file found in `pwd`" exit 1 fi fi #################### # get project name # #################### if [ "x$PROJECT" = "x" ] ; then PROJECT="`grep AC_INIT $CONFIGURE | grep -v '.*#.*AC_INIT' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_INIT(\([^,)]*\).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" if [ "x$PROJECT" = "xAC_INIT" ] ; then # projects might be using the older/deprecated arg-less AC_INIT .. look for AM_INIT_AUTOMAKE instead PROJECT="`grep AM_INIT_AUTOMAKE $CONFIGURE | grep -v '.*#.*AM_INIT_AUTOMAKE' | tail -${TAIL_N}1 | sed 's/^[ ]*AM_INIT_AUTOMAKE(\([^,)]*\).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" fi if [ "x$PROJECT" = "xAM_INIT_AUTOMAKE" ] ; then PROJECT="project" fi if [ "x$PROJECT" = "x" ] ; then PROJECT="project" fi else $ECHO "Using PROJECT environment variable override: $PROJECT" fi $ECHO "Preparing the $PROJECT build system...please wait" $ECHO ######################## # check for autoreconf # ######################## HAVE_AUTORECONF=no if [ "x$AUTORECONF" = "x" ] ; then for AUTORECONF in autoreconf ; do $VERBOSE_ECHO "Checking autoreconf version: $AUTORECONF --version" $AUTORECONF --version > /dev/null 2>&1 if [ $? = 0 ] ; then HAVE_AUTORECONF=yes break fi done else HAVE_AUTORECONF=yes $ECHO "Using AUTORECONF environment variable override: $AUTORECONF" fi ########################## # autoconf version check # ########################## _acfound=no if [ "x$AUTOCONF" = "x" ] ; then for AUTOCONF in autoconf ; do $VERBOSE_ECHO "Checking autoconf version: $AUTOCONF --version" $AUTOCONF --version > /dev/null 2>&1 if [ $? = 0 ] ; then _acfound=yes break fi done else _acfound=yes $ECHO "Using AUTOCONF environment variable override: $AUTOCONF" fi _report_error=no if [ ! "x$_acfound" = "xyes" ] ; then $ECHO "ERROR: Unable to locate GNU Autoconf." _report_error=yes else _version="`$AUTOCONF --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`" if [ "x$_version" = "x" ] ; then _version="0.0.0" fi $ECHO "Found GNU Autoconf version $_version" version_check "$AUTOCONF_VERSION" "$_version" if [ $? -ne 0 ] ; then _report_error=yes fi fi if [ "x$_report_error" = "xyes" ] ; then version_error "$AUTOCONF_VERSION" "GNU Autoconf" exit 1 fi ########################## # automake version check # ########################## _amfound=no if [ "x$AUTOMAKE" = "x" ] ; then for AUTOMAKE in automake ; do $VERBOSE_ECHO "Checking automake version: $AUTOMAKE --version" $AUTOMAKE --version > /dev/null 2>&1 if [ $? = 0 ] ; then _amfound=yes break fi done else _amfound=yes $ECHO "Using AUTOMAKE environment variable override: $AUTOMAKE" fi _report_error=no if [ ! "x$_amfound" = "xyes" ] ; then $ECHO $ECHO "ERROR: Unable to locate GNU Automake." _report_error=yes else _version="`$AUTOMAKE --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`" if [ "x$_version" = "x" ] ; then _version="0.0.0" fi $ECHO "Found GNU Automake version $_version" version_check "$AUTOMAKE_VERSION" "$_version" if [ $? -ne 0 ] ; then _report_error=yes fi fi if [ "x$_report_error" = "xyes" ] ; then version_error "$AUTOMAKE_VERSION" "GNU Automake" exit 1 fi ######################## # check for libtoolize # ######################## HAVE_LIBTOOLIZE=yes HAVE_ALT_LIBTOOLIZE=no _ltfound=no if [ "x$LIBTOOLIZE" = "x" ] ; then LIBTOOLIZE=libtoolize $VERBOSE_ECHO "Checking libtoolize version: $LIBTOOLIZE --version" $LIBTOOLIZE --version > /dev/null 2>&1 if [ ! $? = 0 ] ; then HAVE_LIBTOOLIZE=no $ECHO if [ "x$HAVE_AUTORECONF" = "xno" ] ; then $ECHO "Warning: libtoolize does not appear to be available." else $ECHO "Warning: libtoolize does not appear to be available. This means that" $ECHO "the automatic build preparation via autoreconf will probably not work." $ECHO "Preparing the build by running each step individually, however, should" $ECHO "work and will be done automatically for you if autoreconf fails." fi # look for some alternates for tool in glibtoolize libtoolize15 libtoolize14 libtoolize13 ; do $VERBOSE_ECHO "Checking libtoolize alternate: $tool --version" _glibtoolize="`$tool --version > /dev/null 2>&1`" if [ $? = 0 ] ; then $VERBOSE_ECHO "Found $tool --version" _glti="`which $tool`" if [ "x$_glti" = "x" ] ; then $VERBOSE_ECHO "Cannot find $tool with which" continue; fi if test ! -f "$_glti" ; then $VERBOSE_ECHO "Cannot use $tool, $_glti is not a file" continue; fi _gltidir="`dirname $_glti`" if [ "x$_gltidir" = "x" ] ; then $VERBOSE_ECHO "Cannot find $tool path with dirname of $_glti" continue; fi if test ! -d "$_gltidir" ; then $VERBOSE_ECHO "Cannot use $tool, $_gltidir is not a directory" continue; fi HAVE_ALT_LIBTOOLIZE=yes LIBTOOLIZE="$tool" $ECHO $ECHO "Fortunately, $tool was found which means that your system may simply" $ECHO "have a non-standard or incomplete GNU Autotools install. If you have" $ECHO "sufficient system access, it may be possible to quell this warning by" $ECHO "running:" $ECHO sudo -V > /dev/null 2>&1 if [ $? = 0 ] ; then $ECHO " sudo ln -s $_glti $_gltidir/libtoolize" $ECHO else $ECHO " ln -s $_glti $_gltidir/libtoolize" $ECHO $ECHO "Run that as root or with proper permissions to the $_gltidir directory" $ECHO fi _ltfound=yes break fi done else _ltfound=yes fi else _ltfound=yes $ECHO "Using LIBTOOLIZE environment variable override: $LIBTOOLIZE" fi ############################ # libtoolize version check # ############################ _report_error=no if [ ! "x$_ltfound" = "xyes" ] ; then $ECHO $ECHO "ERROR: Unable to locate GNU Libtool." _report_error=yes else _version="`$LIBTOOLIZE --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`" if [ "x$_version" = "x" ] ; then _version="0.0.0" fi $ECHO "Found GNU Libtool version $_version" version_check "$LIBTOOL_VERSION" "$_version" if [ $? -ne 0 ] ; then _report_error=yes fi fi if [ "x$_report_error" = "xyes" ] ; then version_error "$LIBTOOL_VERSION" "GNU Libtool" exit 1 fi ##################### # check for aclocal # ##################### if [ "x$ACLOCAL" = "x" ] ; then for ACLOCAL in aclocal ; do $VERBOSE_ECHO "Checking aclocal version: $ACLOCAL --version" $ACLOCAL --version > /dev/null 2>&1 if [ $? = 0 ] ; then break fi done else $ECHO "Using ACLOCAL environment variable override: $ACLOCAL" fi ######################## # check for autoheader # ######################## if [ "x$AUTOHEADER" = "x" ] ; then for AUTOHEADER in autoheader ; do $VERBOSE_ECHO "Checking autoheader version: $AUTOHEADER --version" $AUTOHEADER --version > /dev/null 2>&1 if [ $? = 0 ] ; then break fi done else $ECHO "Using AUTOHEADER environment variable override: $AUTOHEADER" fi ######################### # check if version only # ######################### $VERBOSE_ECHO "Checking whether to only output version information" if [ "x$VERSION_ONLY" = "xyes" ] ; then $ECHO ident $ECHO "---" $ECHO "Version requested. No preparation or configuration will be performed." exit 0 fi ################################# # PROTECT_FROM_CLOBBER FUNCTION # ################################# protect_from_clobber ( ) { PFC_INIT=1 # protect COPYING & INSTALL from overwrite by automake. the # automake force option will (inappropriately) ignore the existing # contents of a COPYING and/or INSTALL files (depending on the # version) instead of just forcing *missing* files like it does # for AUTHORS, NEWS, and README. this is broken but extremely # prevalent behavior, so we protect against it by keeping a backup # of the file that can later be restored. for file in COPYING INSTALL ; do if test -f ${file} ; then if test -f ${file}.$$.protect_from_automake.backup ; then $VERBOSE_ECHO "Already backed up ${file} in `pwd`" else $VERBOSE_ECHO "Backing up ${file} in `pwd`" $VERBOSE_ECHO "cp -p ${file} ${file}.$$.protect_from_automake.backup" cp -p ${file} ${file}.$$.protect_from_automake.backup fi fi done } ############################## # RECURSIVE_PROTECT FUNCTION # ############################## recursive_protect ( ) { # for projects using recursive configure, run the build # preparation steps for the subdirectories. this function assumes # START_PATH was set to pwd before recursion begins so that # relative paths work. # git 'r done, protect COPYING and INSTALL from being clobbered protect_from_clobber if test -d autom4te.cache ; then $VERBOSE_ECHO "Found an autom4te.cache directory, deleting it" $VERBOSE_ECHO "rm -rf autom4te.cache" rm -rf autom4te.cache fi # find configure template _configure="`locate_configure_template`" if [ "x$_configure" = "x" ] ; then return fi # $VERBOSE_ECHO "Looking for configure template found `pwd`/$_configure" # look for subdirs # $VERBOSE_ECHO "Looking for subdirs in `pwd`" _det_config_subdirs="`grep AC_CONFIG_SUBDIRS $_configure | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" CHECK_DIRS="" for dir in $_det_config_subdirs ; do if test -d "`pwd`/$dir" ; then CHECK_DIRS="$CHECK_DIRS \"`pwd`/$dir\"" fi done # process subdirs if [ ! "x$CHECK_DIRS" = "x" ] ; then $VERBOSE_ECHO "Recursively scanning the following directories:" $VERBOSE_ECHO " $CHECK_DIRS" for dir in $CHECK_DIRS ; do $VERBOSE_ECHO "Protecting files from automake in $dir" cd "$START_PATH" eval "cd $dir" # recursively git 'r done recursive_protect done fi } # end of recursive_protect ############################# # RESTORE_CLOBBERED FUNCION # ############################# restore_clobbered ( ) { # The automake (and autoreconf by extension) -f/--force-missing # option may overwrite COPYING and INSTALL even if they do exist. # Here we restore the files if necessary. spacer=no for file in COPYING INSTALL ; do if test -f ${file}.$$.protect_from_automake.backup ; then if test -f ${file} ; then # compare entire content, restore if needed if test "x`cat ${file}`" != "x`cat ${file}.$$.protect_from_automake.backup`" ; then if test "x$spacer" = "xno" ; then $VERBOSE_ECHO spacer=yes fi # restore the backup $VERBOSE_ECHO "Restoring ${file} from backup (automake -f likely clobbered it)" $VERBOSE_ECHO "rm -f ${file}" rm -f ${file} $VERBOSE_ECHO "mv ${file}.$$.protect_from_automake.backup ${file}" mv ${file}.$$.protect_from_automake.backup ${file} fi # check contents elif test -f ${file}.$$.protect_from_automake.backup ; then $VERBOSE_ECHO "mv ${file}.$$.protect_from_automake.backup ${file}" mv ${file}.$$.protect_from_automake.backup ${file} fi # -f ${file} # just in case $VERBOSE_ECHO "rm -f ${file}.$$.protect_from_automake.backup" rm -f ${file}.$$.protect_from_automake.backup fi # -f ${file}.$$.protect_from_automake.backup done CONFIGURE="`locate_configure_template`" if [ "x$CONFIGURE" = "x" ] ; then return fi _aux_dir="`grep AC_CONFIG_AUX_DIR $CONFIGURE | grep -v '.*#.*AC_CONFIG_AUX_DIR' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_CONFIG_AUX_DIR(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" if test ! -d "$_aux_dir" ; then _aux_dir=. fi for file in config.guess config.sub ltmain.sh ; do if test -f "${_aux_dir}/${file}" ; then $VERBOSE_ECHO "rm -f \"${_aux_dir}/${file}.backup\"" rm -f "${_aux_dir}/${file}.backup" fi done } # end of restore_clobbered ############################## # RECURSIVE_RESTORE FUNCTION # ############################## recursive_restore ( ) { # restore COPYING and INSTALL from backup if they were clobbered # for each directory recursively. # git 'r undone restore_clobbered # find configure template _configure="`locate_configure_template`" if [ "x$_configure" = "x" ] ; then return fi # look for subdirs _det_config_subdirs="`grep AC_CONFIG_SUBDIRS $_configure | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" CHECK_DIRS="" for dir in $_det_config_subdirs ; do if test -d "`pwd`/$dir" ; then CHECK_DIRS="$CHECK_DIRS \"`pwd`/$dir\"" fi done # process subdirs if [ ! "x$CHECK_DIRS" = "x" ] ; then $VERBOSE_ECHO "Recursively scanning the following directories:" $VERBOSE_ECHO " $CHECK_DIRS" for dir in $CHECK_DIRS ; do $VERBOSE_ECHO "Checking files for automake damage in $dir" cd "$START_PATH" eval "cd $dir" # recursively git 'r undone recursive_restore done fi } # end of recursive_restore ####################### # INITIALIZE FUNCTION # ####################### initialize ( ) { # this routine performs a variety of directory-specific # initializations. some are sanity checks, some are preventive, # and some are necessary setup detection. # # this function sets: # CONFIGURE # SEARCH_DIRS # CONFIG_SUBDIRS ################################## # check for a configure template # ################################## CONFIGURE="`locate_configure_template`" if [ "x$CONFIGURE" = "x" ] ; then $ECHO $ECHO "A configure.ac or configure.in file could not be located implying" $ECHO "that the GNU Build System is at least not used in this directory. In" $ECHO "any case, there is nothing to do here without one of those files." $ECHO $ECHO "ERROR: No configure.in or configure.ac file found in `pwd`" exit 1 fi ##################### # detect an aux dir # ##################### _aux_dir="`grep AC_CONFIG_AUX_DIR $CONFIGURE | grep -v '.*#.*AC_CONFIG_AUX_DIR' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_CONFIG_AUX_DIR(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" if test ! -d "$_aux_dir" ; then _aux_dir=. else $VERBOSE_ECHO "Detected auxillary directory: $_aux_dir" fi ################################ # detect a recursive configure # ################################ CONFIG_SUBDIRS="" _det_config_subdirs="`grep AC_CONFIG_SUBDIRS $CONFIGURE | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" for dir in $_det_config_subdirs ; do if test -d "`pwd`/$dir" ; then $VERBOSE_ECHO "Detected recursive configure directory: `pwd`/$dir" CONFIG_SUBDIRS="$CONFIG_SUBDIRS `pwd`/$dir" fi done ########################################################### # make sure certain required files exist for GNU projects # ########################################################### _marker_found="" _marker_found_message_intro='Detected non-GNU marker "' _marker_found_message_mid='" in ' for marker in foreign cygnus ; do _marker_found_message=${_marker_found_message_intro}${marker}${_marker_found_message_mid} _marker_found="`grep 'AM_INIT_AUTOMAKE.*'${marker} $CONFIGURE`" if [ ! "x$_marker_found" = "x" ] ; then $VERBOSE_ECHO "${_marker_found_message}`basename \"$CONFIGURE\"`" break fi if test -f "`dirname \"$CONFIGURE\"/Makefile.am`" ; then _marker_found="`grep 'AUTOMAKE_OPTIONS.*'${marker} Makefile.am`" if [ ! "x$_marker_found" = "x" ] ; then $VERBOSE_ECHO "${_marker_found_message}Makefile.am" break fi fi done if [ "x${_marker_found}" = "x" ] ; then _suggest_foreign=no for file in AUTHORS COPYING ChangeLog INSTALL NEWS README ; do if [ ! -f $file ] ; then $VERBOSE_ECHO "Touching ${file} since it does not exist" _suggest_foreign=yes touch $file fi done if [ "x${_suggest_foreign}" = "xyes" ] ; then $ECHO $ECHO "Warning: Several files expected of projects that conform to the GNU" $ECHO "coding standards were not found. The files were automatically added" $ECHO "for you since you do not have a 'foreign' declaration specified." $ECHO $ECHO "Considered adding 'foreign' to AM_INIT_AUTOMAKE in `basename \"$CONFIGURE\"`" if test -f "`dirname \"$CONFIGURE\"/Makefile.am`" ; then $ECHO "or to AUTOMAKE_OPTIONS in your top-level Makefile.am file." fi $ECHO fi fi ################################################## # make sure certain generated files do not exist # ################################################## for file in config.guess config.sub ltmain.sh ; do if test -f "${_aux_dir}/${file}" ; then $VERBOSE_ECHO "mv -f \"${_aux_dir}/${file}\" \"${_aux_dir}/${file}.backup\"" mv -f "${_aux_dir}/${file}" "${_aux_dir}/${file}.backup" fi done ############################ # search alternate m4 dirs # ############################ SEARCH_DIRS="" for dir in m4 ; do if [ -d $dir ] ; then $VERBOSE_ECHO "Found extra aclocal search directory: $dir" SEARCH_DIRS="$SEARCH_DIRS -I $dir" fi done ###################################### # remove any previous build products # ###################################### if test -d autom4te.cache ; then $VERBOSE_ECHO "Found an autom4te.cache directory, deleting it" $VERBOSE_ECHO "rm -rf autom4te.cache" rm -rf autom4te.cache fi # tcl/tk (and probably others) have a customized aclocal.m4, so can't delete it # if test -f aclocal.m4 ; then # $VERBOSE_ECHO "Found an aclocal.m4 file, deleting it" # $VERBOSE_ECHO "rm -f aclocal.m4" # rm -f aclocal.m4 # fi } # end of initialize() ############## # initialize # ############## # stash path START_PATH="`pwd`" # Before running autoreconf or manual steps, some prep detection work # is necessary or useful. Only needs to occur once per directory, but # does need to traverse the entire subconfigure hierarchy to protect # files from being clobbered even by autoreconf. recursive_protect # start from where we started cd "$START_PATH" # get ready to process initialize ######################################### # DOWNLOAD_GNULIB_CONFIG_GUESS FUNCTION # ######################################### # TODO - should make sure wget/curl exist and/or work before trying to # use them. download_gnulib_config_guess () { # abuse gitweb to download gnulib's latest config.guess via HTTP config_guess_temp="config.guess.$$.download" ret=1 for __cmd in wget curl fetch ; do $VERBOSE_ECHO "Checking for command ${__cmd}" ${__cmd} --version > /dev/null 2>&1 ret=$? if [ ! $ret = 0 ] ; then continue fi __cmd_version=`${__cmd} --version | head -n 1 | sed -e 's/^[^0-9]\+//' -e 's/ .*//'` $VERBOSE_ECHO "Found ${__cmd} ${__cmd_version}" opts="" case ${__cmd} in wget) opts="-O" ;; curl) opts="-o" ;; fetch) opts="-t 5 -f" ;; esac $VERBOSE_ECHO "Running $__cmd \"${CONFIG_GUESS_URL}\" $opts \"${config_guess_temp}\"" eval "$__cmd \"${CONFIG_GUESS_URL}\" $opts \"${config_guess_temp}\"" > /dev/null 2>&1 if [ $? = 0 ] ; then mv -f "${config_guess_temp}" ${_aux_dir}/config.guess ret=0 break fi done if [ ! $ret = 0 ] ; then $ECHO "Warning: config.guess download failed from: $CONFIG_GUESS_URL" rm -f "${config_guess_temp}" fi } ############################## # LIBTOOLIZE_NEEDED FUNCTION # ############################## libtoolize_needed () { ret=1 # means no, don't need libtoolize for feature in AC_PROG_LIBTOOL AM_PROG_LIBTOOL LT_INIT ; do $VERBOSE_ECHO "Searching for $feature in $CONFIGURE" found="`grep \"^$feature.*\" $CONFIGURE`" if [ ! "x$found" = "x" ] ; then ret=0 # means yes, need to run libtoolize break fi done return ${ret} } ############################################ # prepare build via autoreconf or manually # ############################################ reconfigure_manually=no if [ "x$HAVE_AUTORECONF" = "xyes" ] ; then $ECHO $ECHO $ECHO_N "Automatically preparing build ... $ECHO_C" $VERBOSE_ECHO "$AUTORECONF $SEARCH_DIRS $AUTORECONF_OPTIONS" autoreconf_output="`$AUTORECONF $SEARCH_DIRS $AUTORECONF_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$autoreconf_output" if [ ! $ret = 0 ] ; then if [ "x$HAVE_ALT_LIBTOOLIZE" = "xyes" ] ; then if [ ! "x`echo \"$autoreconf_output\" | grep libtoolize | grep \"No such file or directory\"`" = "x" ] ; then $ECHO $ECHO "Warning: autoreconf failed but due to what is usually a common libtool" $ECHO "misconfiguration issue. This problem is encountered on systems that" $ECHO "have installed libtoolize under a different name without providing a" $ECHO "symbolic link or without setting the LIBTOOLIZE environment variable." $ECHO $ECHO "Restarting the preparation steps with LIBTOOLIZE set to $LIBTOOLIZE" export LIBTOOLIZE RUN_RECURSIVE=no export RUN_RECURSIVE untrap_abnormal $VERBOSE_ECHO sh $AUTOGEN_SH "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" sh "$AUTOGEN_SH" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" exit $? fi fi $ECHO "Warning: $AUTORECONF failed" if test -f ltmain.sh ; then $ECHO "libtoolize being run by autoreconf is not creating ltmain.sh in the auxillary directory like it should" fi $ECHO "Attempting to run the preparation steps individually" reconfigure_manually=yes else if [ "x$DOWNLOAD" = "xyes" ] ; then if libtoolize_needed ; then download_gnulib_config_guess fi fi fi else reconfigure_manually=yes fi ############################ # LIBTOOL_FAILURE FUNCTION # ############################ libtool_failure ( ) { # libtool is rather error-prone in comparison to the other # autotools and this routine attempts to compensate for some # common failures. the output after a libtoolize failure is # parsed for an error related to AC_PROG_LIBTOOL and if found, we # attempt to inject a project-provided libtool.m4 file. _autoconf_output="$1" if [ "x$RUN_RECURSIVE" = "xno" ] ; then # we already tried the libtool.m4, don't try again return 1 fi if test -f "$LIBTOOL_M4" ; then found_libtool="`$ECHO $_autoconf_output | grep AC_PROG_LIBTOOL`" if test ! "x$found_libtool" = "x" ; then if test -f acinclude.m4 ; then rm -f acinclude.m4.$$.backup $VERBOSE_ECHO "cat acinclude.m4 > acinclude.m4.$$.backup" cat acinclude.m4 > acinclude.m4.$$.backup fi $VERBOSE_ECHO "cat \"$LIBTOOL_M4\" >> acinclude.m4" chmod u+w acinclude.m4 cat "$LIBTOOL_M4" >> acinclude.m4 # don't keep doing this RUN_RECURSIVE=no export RUN_RECURSIVE untrap_abnormal $ECHO $ECHO "Restarting the preparation steps with libtool macros in acinclude.m4" $VERBOSE_ECHO sh $AUTOGEN_SH "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" sh "$AUTOGEN_SH" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" exit $? fi fi } ########################### # MANUAL_AUTOGEN FUNCTION # ########################### manual_autogen ( ) { ################################################## # Manual preparation steps taken are as follows: # # aclocal [-I m4] # # libtoolize --automake -c -f # # aclocal [-I m4] # # autoconf -f # # autoheader # # automake -a -c -f # ################################################## ########### # aclocal # ########### $VERBOSE_ECHO "$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS" aclocal_output="`$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$aclocal_output" if [ ! $ret = 0 ] ; then $ECHO "ERROR: $ACLOCAL failed" && exit 2 ; fi ############## # libtoolize # ############## if libtoolize_needed ; then if [ "x$HAVE_LIBTOOLIZE" = "xyes" ] ; then $VERBOSE_ECHO "$LIBTOOLIZE $LIBTOOLIZE_OPTIONS" libtoolize_output="`$LIBTOOLIZE $LIBTOOLIZE_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$libtoolize_output" if [ ! $ret = 0 ] ; then $ECHO "ERROR: $LIBTOOLIZE failed" && exit 2 ; fi else if [ "x$HAVE_ALT_LIBTOOLIZE" = "xyes" ] ; then $VERBOSE_ECHO "$LIBTOOLIZE $ALT_LIBTOOLIZE_OPTIONS" libtoolize_output="`$LIBTOOLIZE $ALT_LIBTOOLIZE_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$libtoolize_output" if [ ! $ret = 0 ] ; then $ECHO "ERROR: $LIBTOOLIZE failed" && exit 2 ; fi fi fi ########### # aclocal # ########### # re-run again as instructed by libtoolize $VERBOSE_ECHO "$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS" aclocal_output="`$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$aclocal_output" # libtoolize might put ltmain.sh in the wrong place if test -f ltmain.sh ; then if test ! -f "${_aux_dir}/ltmain.sh" ; then $ECHO $ECHO "Warning: $LIBTOOLIZE is creating ltmain.sh in the wrong directory" $ECHO $ECHO "Fortunately, the problem can be worked around by simply copying the" $ECHO "file to the appropriate location (${_aux_dir}/). This has been done for you." $ECHO $VERBOSE_ECHO "cp -p ltmain.sh \"${_aux_dir}/ltmain.sh\"" cp -p ltmain.sh "${_aux_dir}/ltmain.sh" $ECHO $ECHO_N "Continuing build preparation ... $ECHO_C" fi fi # ltmain.sh if [ "x$DOWNLOAD" = "xyes" ] ; then download_gnulib_config_guess fi fi # libtoolize_needed ############ # autoconf # ############ $VERBOSE_ECHO $VERBOSE_ECHO "$AUTOCONF $AUTOCONF_OPTIONS" autoconf_output="`$AUTOCONF $AUTOCONF_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$autoconf_output" if [ ! $ret = 0 ] ; then # retry without the -f and check for usage of macros that are too new ac2_59_macros="AC_C_RESTRICT AC_INCLUDES_DEFAULT AC_LANG_ASSERT AC_LANG_WERROR AS_SET_CATFILE" ac2_55_macros="AC_COMPILER_IFELSE AC_FUNC_MBRTOWC AC_HEADER_STDBOOL AC_LANG_CONFTEST AC_LANG_SOURCE AC_LANG_PROGRAM AC_LANG_CALL AC_LANG_FUNC_TRY_LINK AC_MSG_FAILURE AC_PREPROC_IFELSE" ac2_54_macros="AC_C_BACKSLASH_A AC_CONFIG_LIBOBJ_DIR AC_GNU_SOURCE AC_PROG_EGREP AC_PROG_FGREP AC_REPLACE_FNMATCH AC_FUNC_FNMATCH_GNU AC_FUNC_REALLOC AC_TYPE_MBSTATE_T" macros_to_search="" ac_major="`echo ${AUTOCONF_VERSION}. | cut -d. -f1 | sed 's/[^0-9]//g'`" ac_minor="`echo ${AUTOCONF_VERSION}. | cut -d. -f2 | sed 's/[^0-9]//g'`" if [ $ac_major -lt 2 ] ; then macros_to_search="$ac2_59_macros $ac2_55_macros $ac2_54_macros" else if [ $ac_minor -lt 54 ] ; then macros_to_search="$ac2_59_macros $ac2_55_macros $ac2_54_macros" elif [ $ac_minor -lt 55 ] ; then macros_to_search="$ac2_59_macros $ac2_55_macros" elif [ $ac_minor -lt 59 ] ; then macros_to_search="$ac2_59_macros" fi fi configure_ac_macros=__none__ for feature in $macros_to_search ; do $VERBOSE_ECHO "Searching for $feature in $CONFIGURE" found="`grep \"^$feature.*\" $CONFIGURE`" if [ ! "x$found" = "x" ] ; then if [ "x$configure_ac_macros" = "x__none__" ] ; then configure_ac_macros="$feature" else configure_ac_macros="$feature $configure_ac_macros" fi fi done if [ ! "x$configure_ac_macros" = "x__none__" ] ; then $ECHO $ECHO "Warning: Unsupported macros were found in $CONFIGURE" $ECHO $ECHO "The `basename \"$CONFIGURE\"` file was scanned in order to determine if any" $ECHO "unsupported macros are used that exceed the minimum version" $ECHO "settings specified within this file. As such, the following macros" $ECHO "should be removed from configure.ac or the version numbers in this" $ECHO "file should be increased:" $ECHO $ECHO "$configure_ac_macros" $ECHO $ECHO $ECHO_N "Ignorantly continuing build preparation ... $ECHO_C" fi ################### # autoconf, retry # ################### $VERBOSE_ECHO $VERBOSE_ECHO "$AUTOCONF" autoconf_output="`$AUTOCONF 2>&1`" ret=$? $VERBOSE_ECHO "$autoconf_output" if [ ! $ret = 0 ] ; then # test if libtool is busted libtool_failure "$autoconf_output" # let the user know what went wrong cat < Wed, 12 Mar 2025 18:39:07 +0000 stimfit (0.16.6-1) unstable; urgency=medium * Install icons into appropriate locations * Drop build dependency on sip -- Christoph Schmidt-Hieber Sun, 09 Feb 2025 21:17:35 +0000 stimfit (0.16.5-1) unstable; urgency=low * Update to latest NumPy C API * Fix debian building and packaging (Closes: #1068032) -- Christoph Schmidt-Hieber Fri, 07 Feb 2025 18:39:37 +0000 stimfit (0.16.4-1.1) unstable; urgency=medium * Non-maintainer upload. * use external libbiosig instead of internal (configure --with-biosig instead of --with-biosiglite) -- Alois Schloegl Thu, 15 Aug 2024 12:56:35 +1300 stimfit (0.16.4-1) unstable; urgency=medium * Non-maintainer upload. * uses Debian's libbiosig package to build stimfit Improves reading ATF, ABF2, AXG, and HEKA format, and provides advantages of dynamic linking * several minor bug fixes -- Alois Schloegl Fri, 05 Apr 2024 00:15:00 +0200 stimfit (0.16.0-1.2) unstable; urgency=medium * Non-maintainer upload. * Update to wxwidgets3.2. (Closes: #1019791) -- Olly Betts Thu, 05 Jan 2023 10:56:35 +1300 stimfit (0.16.0-1.1) unstable; urgency=medium * Non-maintainer upload. * Build-depend on python3-dev instead of python3-all-dev (Closes: #948020) * Patch: Avoid a deprecation warning breaking autoconf with Python 3.10. -- Stefano Rivera Thu, 24 Mar 2022 15:29:58 -0400 stimfit (0.16.0-1) unstable; urgency=low * Upgrade to Python 3 (Closes: #938572) -- Christoph Schmidt-Hieber Tue, 26 Nov 2019 09:35:41 +0200 stimfit (0.15.8-1) unstable; urgency=low * Address wx-gtk2 / wxpython-gtk3 incompatibility issue on bionic (LP: #1778433) -- Christoph Schmidt-Hieber Fri, 29 Jun 2018 09:18:39 +0200 stimfit (0.15.6-1) unstable; urgency=low * Adress shared library renaming error during debian packaging. (Closes: #896407) -- Christoph Schmidt-Hieber Tue, 24 Apr 2018 23:05:28 +0200 stimfit (0.15.5-1) unstable; urgency=low * Adds native intan CLP & tdms file reading * Upgrade libbiosiglite to 1.9.1 -- Christoph Schmidt-Hieber Mon, 12 Feb 2018 16:13:09 +0100 stimfit (0.15.4-1) unstable; urgency=low * Fix building with gcc-6 on armhf (Closes: #847526) * Add channel scrolling * Upgrade libbiosiglite to 1.8.4 -- Christoph Schmidt-Hieber Sat, 10 Dec 2016 16:55:51 +0000 stimfit (0.15.3-1) unstable; urgency=low * Fix building with gcc-6 (Closes: #811904) * Improve latency cursor Python interface -- Christoph Schmidt-Hieber Thu, 14 Jul 2016 10:49:03 +0100 stimfit (0.15.2-1) unstable; urgency=low * Fix RNG in tests with >= C++11 (Closes: #811904) * Use builtin biosig library -- Christoph Schmidt-Hieber Fri, 01 Apr 2016 10:29:55 +0100 stimfit (0.14.11-1) unstable; urgency=low * Improve usability of stfio_plot.Timeseries * Debian build fixes bug #804592 -- Christoph Schmidt-Hieber Wed, 18 Nov 2015 09:52:53 +0000 stimfit (0.14.10-1) experimental; urgency=low * Improve batch file conversion usability * Fix Debian dependencies -- Christoph Schmidt-Hieber Mon, 04 May 2015 04:20:24 +0100 stimfit (0.14.9-1) experimental; urgency=low * Fix several bugs during abf2 (pClamp10) file reading * Fix several issues during event detection -- Christoph Schmidt-Hieber Sun, 05 Apr 2015 12:33:50 +0100 stimfit (0.14.5-2) experimental; urgency=low * Fix several bugs during event detection * Fix several bugs during file reading (abf, axograph and hdf5) * Alternatively use wx 2.8 instead of wx 3.0 for Debian packages -- Christoph Schmidt-Hieber Mon, 03 Mar 2015 19:29:58 +0000 stimfit (0.13.19-1) unstable; urgency=low * Update to use wxWidgets 3.0 (Closes: #757289) -- Christoph Schmidt-Hieber Sat, 30 Aug 2014 14:40:04 +0000 stimfit (0.13.18-1) unstable; urgency=low * Support hdf5 1.8.13 new packaging layout (Closes: #756699) * Support dpkg-buildflags with --enable-module * Improved information/error messages -- Christoph Schmidt-Hieber Fri, 01 Aug 2014 10:57:51 +0000 stimfit (0.13.15-1) unstable; urgency=low * Fix half duration limits bug * Use neo's StimfitIO implementation * Address some lintian warnings -- Christoph Schmidt-Hieber Sun, 16 Feb 2014 12:48:51 +0000 stimfit (0.13.13-1) unstable; urgency=low * Import/Export from/to python-neo * Fix potential buffer overflows * Fix some bugs in Python code * Use libhdf5-dev instead of libhdf5-serial-dev dependency (Closes: #735157) * Use dh-autoreconf to fix FTBFS on ppc64el (Closes: #735231) * Distinguish only between Windows and non-Windows builds (implicitly posix) (Closes: #728094) -- Christoph Schmidt-Hieber Sun, 09 Feb 2014 10:56:06 +0000 stimfit (0.13.6-1) unstable; urgency=low * Export stfio recordings to pandas * Improved support for accessing date and time of recordings -- Christoph Schmidt-Hieber Wed, 11 Dec 2013 21:42:13 +0000 stimfit (0.13.5-1) unstable; urgency=low * New upstream release - Don't write test results to disk - Fall back to gcc/Unix for unknown platforms/compilers in axodefn.h (Closes: #728094) * Improved batch analysis * Multi-channel concatenation * Less disruptive warnings and error messages -- Christoph Schmidt-Hieber Sat, 30 Nov 2013 18:23:23 +0000 stimfit (0.13.2-1) unstable; urgency=low * New upstream release - Disambiguate template type in boost's reset (Closes: #720825) * Faster plotting * Add support for inner and outer rise time computations * Add option 'align to half-amplitude' when computing averages * Fix some potential buffer overflows * Improve biosig integration * Improve deconvolution-based event detection * Improve fit initialization for some functions -- Christoph Schmidt-Hieber Tue, 17 Sep 2013 16:47:30 +0000 stimfit (0.12.5-1) UNRELEASED; urgency=low * More robust initialization for nonlinear regression * Faster convergence for most fits * Add support for latest abf2 file format (Clampex 10.4) * Fix potential buffer overflow when computing averages -- Christoph Schmidt-Hieber Mon, 08 Jul 2013 19:55:04 +0000 stimfit (0.12.1-1) experimental; urgency=low * Use biosig as additional file reading backend -- Christoph Schmidt-Hieber Tue, 02 Apr 2013 21:22:06 +0000 stimfit (0.11.9-1) UNRELEASED; urgency=low * Fix latency measurements in manual peak mode * GUI adjustments * Build for Debian proper -- Christoph Schmidt-Hieber Fri, 29 Mar 2013 09:20:13 +0000 stimfit (0.11.8-0lucid1) lucid; urgency=low * Make objects iterable in pystfio * Prettify fit dialog -- Christoph Schmidt-Hieber Sun, 17 Feb 2013 13:02:28 +0000 stimfit (0.11.7-0lucid1) lucid; urgency=low * Add missing library to stfio debian package -- Christoph Schmidt-Hieber Sat, 16 Feb 2013 20:20:24 +0000 stimfit (0.11.6-0lucid1) lucid; urgency=low * Corrected some bugs in cursor dialogs -- Christoph Schmidt-Hieber Sat, 16 Feb 2013 14:30:00 +0000 stimfit (0.11.4-0precise1) precise; urgency=low * Fixed monoexponential fit with delay * Release hdf5 resources after reading / writing a file -- Christoph Schmidt-Hieber Fri, 20 Apr 2012 17:18:43 +0000 stimfit (0.11.1-1oneiric1) oneiric; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:41:23 +0000 stimfit (0.11.1-1natty1) natty; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:40:08 +0000 stimfit (0.11.1-1maverick1) maverick; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:39:02 +0000 stimfit (0.11.1-1lucid1) lucid; urgency=low * Added stfio_plot.py to stimfit -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 16:33:22 +0000 stimfit (0.11.0-1oneiric1) oneiric; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 15:50:54 +0000 stimfit (0.11.0-1natty1) natty; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 15:48:41 +0000 stimfit (0.11.0-1maverick1) maverick; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 15:42:22 +0000 stimfit (0.11.0-1lucid1) lucid; urgency=low * libstfio factored out as separate, GUI-independent library -- Christoph Schmidt-Hieber Sat, 08 Oct 2011 14:49:00 +0000 stimfit (0.10.18-2) UNRELEASED; urgency=low * Acknowledging previous NMU * Adjusted dh_python2 call to - invoke it only whenever it is present - do not carry hardcoded python version in X-Python-Version but rather specify current default using -V cmdline option * Use of DEB_BUILD_OPTIONS - Condition running tests on not having 'nocheck' - Rely on parallel= option to specify number of parallel builds, instead of hardcoded -j4 * Use of dh_numpy (if present) to specify numpy ABI dependency * Added ${python:Depends} to stimfit itself -- Yaroslav Halchenko Sun, 04 Mar 2012 17:03:34 -0500 stimfit (0.10.18-1.1) unstable; urgency=low * Non-maintainer upload. * Use dh_python2 to set proper dependencies for python-stfio. Note: this only happens for Python 2.7, building for all versions needs maintainer work and isn't suitable for NMU. Closes: #631983 -- Jonathan Wiltshire Sun, 04 Mar 2012 13:33:02 +0000 stimfit (0.10.18-1) unstable; urgency=low * Updated copyright notice for numpy.i -- Christoph Schmidt-Hieber Sat, 10 Sep 2011 15:46:33 +0000 stimfit (0.10.17-1oneiric1) oneiric; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 23:02:16 +0000 stimfit (0.10.17-1natty1) natty; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:55:12 +0000 stimfit (0.10.17-1maverick1) maverick; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:53:32 +0000 stimfit (0.10.17-1lucid2) lucid; urgency=low * Added source package -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:47:50 +0000 stimfit (0.10.17-1lucid1) lucid; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 22:38:59 +0000 stimfit (0.10.17-1) UNRELEASED; urgency=low * Do not redirect Python stdio to separate Window (Closes: #639672) * From previous unreleased version: provide gtest source files (Closes: #631825) -- Christoph Schmidt-Hieber Tue, 30 Aug 2011 18:17:57 +0000 stimfit (0.10.16-1ubuntu3) natty; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 19:13:35 +0000 stimfit (0.10.16-1ubuntu2) maverick; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 19:10:52 +0000 stimfit (0.10.16-1ubuntu1) lucid; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 19:04:50 +0000 stimfit (0.10.16-1) UNRELEASED; urgency=low * Provide gtest source files (Closes: #631825) * File series conversion implemented by Jose Guzman -- Christoph Schmidt-Hieber Sun, 24 Jul 2011 16:59:56 +0000 stimfit (0.10.15-0ubuntu3) lucid; urgency=low * Igor file export -- Christoph Schmidt-Hieber Tue, 24 May 2011 23:42:50 +0000 stimfit (0.10.15-0ubuntu2) maverick; urgency=low * Igor file export -- Christoph Schmidt-Hieber Tue, 24 May 2011 22:36:01 +0000 stimfit (0.10.15-0ubuntu1) natty; urgency=low * Igor file export -- Christoph Schmidt-Hieber Tue, 24 May 2011 22:45:06 +0000 stimfit (0.10.14-0ubuntu1) lucid; urgency=low * Use unified menu on GTK to resolve problems with Unity and gnome-global-menu applet * Started support for viewing all channels -- Christoph Schmidt-Hieber Mon, 11 Apr 2011 14:56:55 +0000 stimfit (0.10.13-1ubuntu5) natty; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library * Reversioned because of source change -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 14:03:45 +0000 stimfit (0.10.13-1ubuntu4) maverick; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library * Reversioned because of source change -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 13:57:48 +0000 stimfit (0.10.13-1ubuntu3) natty; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 13:27:16 +0000 stimfit (0.10.13-1ubuntu2) maverick; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 13:21:56 +0000 stimfit (0.10.13-1ubuntu1) lucid; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 12:45:43 +0000 stimfit (0.10.13-1) unstable; urgency=low * Added scaling support to levmar * Fixed a bug in HEKA file reading library -- Christoph Schmidt-Hieber Sat, 02 Apr 2011 12:33:21 +0000 stimfit (0.10.12-3) unstable; urgency=low * Fixed time stamp for Debian. -- Christoph Schmidt-Hieber Sat, 26 Feb 2011 12:27:04 +0000 stimfit (0.10.12-2) unstable; urgency=low * Fixed version number for Debian. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 21:10:56 +0000 stimfit (0.10.12-1) UNRELEASED; urgency=low * Fixed gtest build on sid. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 21:10:56 +0000 stimfit (0.10.12-1ubuntu1) natty; urgency=low * Fixed gtest build on natty. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 15:36:31 +0000 stimfit (0.10.11-1ubuntu5) natty; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:55:59 +0000 stimfit (0.10.11-1ubuntu4) maverick; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:39:29 +0000 stimfit (0.10.11-1ubuntu3) natty; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:08:14 +0000 stimfit (0.10.11-1ubuntu2) maverick; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 14:06:39 +0000 stimfit (0.10.11-1ubuntu1) lucid; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Wed, 23 Feb 2011 13:53:47 +0000 stimfit (0.10.11-1) unstable; urgency=low * Resolved some dependency problems in Python module. -- Christoph Schmidt-Hieber Tue, 22 Feb 2011 20:12:18 +0000 stimfit (0.10.10-1ubuntu1) lucid; urgency=low * Failed upload required yet another reversioning... -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 18:11:03 +0000 stimfit (0.10.9-1ubuntu3) lucid; urgency=low * Failed upload required reversioning -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 17:54:56 +0000 stimfit (0.10.9-1ubuntu2) lucid; urgency=low * Moved Python files from dist-packages to private directory (/usr/lib/stimfit) to comply with debian packaging rules. * Minimal unit testing during build. -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 17:34:09 +0000 stimfit (0.10.9-1ubuntu1) maverick; urgency=low * Moved Python files from dist-packages to private directory (/usr/lib/stimfit) to comply with debian packaging rules. * Minimal unit testing during build. -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 17:31:57 +0000 stimfit (0.10.9-1) unstable; urgency=low * Moved Python files from dist-packages to private directory (/usr/lib/stimfit) to comply with debian packaging rules. * Minimal unit testing during build. * Initial Debian release (Closes: #612375) * Upload sponsored by Yaroslav Halchenko -- Christoph Schmidt-Hieber Thu, 08 Feb 2011 16:23:29 +0000 stimfit (0.10.8-0ubuntu2) lucid; urgency=low * Increased matplotlib compatibility * Started to replace printing and graphics export functions using matplotlib as the backend -- Christoph Schmidt-Hieber Thu, 05 Feb 2011 19:44:35 +0000 stimfit (0.10.8-0ubuntu1) maverick; urgency=low * Increased matplotlib compatibility * Started to replace printing and graphics export functions using matplotlib as the backend -- Christoph Schmidt-Hieber Thu, 05 Feb 2011 19:19:41 +0000 stimfit (0.10.7-0ubuntu2) lucid; urgency=low * Fixed "Apply scaling to all windows" -- Christoph Schmidt-Hieber Mon, 31 Jan 2011 11:00:55 +0000 stimfit (0.10.7-0ubuntu1) maverick; urgency=low * Fixed "Apply scaling to all windows" -- Christoph Schmidt-Hieber Thu, 27 Jan 2011 17:12:21 +0000 stimfit (0.10.6-0ubuntu2) lucid; urgency=low * Fixed a bug when accessing files from the Python shell. -- Christoph Schmidt-Hieber Thu, 27 Jan 2011 17:12:21 +0000 stimfit (0.10.6-0ubuntu1) maverick; urgency=low * Fixed a bug when accessing files from the Python shell. -- Christoph Schmidt-Hieber Thu, 27 Jan 2011 17:12:21 +0000 stimfit (0.10.5-0ubuntu5) lucid; urgency=low * Reversioned for lucid. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 16:32:52 +0000 stimfit (0.10.5-0ubuntu4) lucid; urgency=low * Initial release for lucid (10.04). -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 16:24:41 +0000 stimfit (0.10.5-0ubuntu4) maverick; urgency=low * Added build-arch to debian rules. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 15:53:17 +0000 stimfit (0.10.5-0ubuntu3) maverick; urgency=low * Added source to upload. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 15:04:35 +0000 stimfit (0.10.5-0ubuntu2) maverick; urgency=low * Uploaded to wrong ppa. -- Christoph Schmidt-Hieber Sun, 23 Jan 2011 15:04:35 +0000 stimfit (0.10.5-0ubuntu1) maverick; urgency=low * Initial release. -- Christoph Schmidt-Hieber Sat, 22 Jan 2011 20:06:14 +0000 stimfit-0.16.7/TODO0000664000175000017500000000260014750344764007453 This Jose's TODO list for Stimfit: Thu Jan 20 09:59:57 CET 2011 * Enable change threshold slope in Slope page of Cursor settings menu * Add python commands for the PSlope calculation (setting cursors, getting slope, setting Delta T mode, etc..) * Add a column with the Slope results in the Batch analysis Sun Jan 23 22:13:20 CET 2011 Wed May 11 09:23:14 CEST 2011 * Add Analysis toolbar to the Extensions menu * When pressing L, change latency measurements to manual Sun Jun 19 08:58:13 CEST 2011 Bugs reported by Stephanie * in stf.show_table_dictlist() the ordering of the dictionary list in the grid is random; the elements of the dictionary will not appear in the grid as they are written in the dictionary, nor appear alphabetically as in stf.shot_table. Besides that, the key of the dictionary doest not show in the column (it says A, B and so on). Wed Jul 13 16:55:13 CEST 2011 Add "Show reference" to Stimfit registry Thu Oct 27 09:37:41 CEST 2011 Set window Icon in Stimfit (see http://zetcode.com/tutorials/wxwidgetstutorial/firstprograms/) Sun Oct 30 07:52:17 CET 2011 GUI event loop support for IPython 0.11; The thread-based version to work interactively with wxPython is deprecated in IPython 0.11. See https://github.com/ipython/ipython/issues/645. There will be a new way to embed IPython (see http://ipython.org/ipython-doc/dev/interactive/reference.html#gui-event-loop-support stimfit-0.16.7/Makefile.am0000664000175000017500000003772414755262551011034 SUBDIRS = src ACLOCAL_AMFLAGS = ${ACLOCAL_AMFLAGS} -I m4 if !BUILD_MODULE bin_PROGRAMS = stimfit check_PROGRAMS = stimfittest TESTS = ${check_PROGRAMS} stimfit_SOURCES = ./src/stimfit/gui/main.cpp stimfittest_SOURCES = ./src/test/section.cpp ./src/test/channel.cpp ./src/test/recording.cpp ./src/test/fit.cpp ./src/test/measure.cpp \ ./src/test/gtest/src/gtest-all.cc ./src/test/gtest/src/gtest_main.cc noinst_HEADERS = \ ./src/libstfio/channel.h ./src/libstfio/section.h ./src/libstfio/recording.h ./src/libstfio/stfio.h \ ./src/libstfio/cfs/cfslib.h ./src/libstfio/cfs/cfs.h ./src/libstfio/cfs/machine.h \ ./src/libstfio/hdf5/hdf5lib.h \ ./src/libstfio/heka/hekalib.h \ ./src/libstfio/abf/abflib.h \ ./src/libstfio/abf/axon/AxAbfFio32/abffiles.h \ ./src/libstfio/abf/axon/AxAbfFio32/csynch.hpp \ ./src/libstfio/abf/axon/AxAbfFio32/filedesc.hpp \ ./src/libstfio/abf/axon/Common/FileReadCache.hpp \ ./src/libstfio/abf/axon/Common/FileIO.hpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfheadr.h \ ./src/libstfio/abf/axon/AxAbfFio32/oldheadr.h \ ./src/libstfio/abf/axon/AxAbfFio32/abfutil.h \ ./src/libstfio/abf/axon/AxAbfFio32/msbincvt.h \ ./src/libstfio/abf/axon/Common/unix.h \ ./src/libstfio/abf/axon/Common/axodefn.h \ ./src/libstfio/abf/axon/Common/axodebug.h \ ./src/libstfio/abf/axon/Common/wincpp.hpp \ ./src/libstfio/abf/axon/AxAbfFio32/AxAbffio32.h \ ./src/libstfio/abf/axon/AxAbfFio32/abfoldnx.h \ ./src/libstfio/abf/axon/Common/resource.h \ ./src/libstfio/abf/axon/AxAtfFio32/axatffio32.h \ ./src/libstfio/abf/axon/AxAtfFio32/atfutil.h \ ./src/libstfio/abf/axon/AxAtfFio32/atfintl.h \ ./src/libstfio/abf/axon/Common/colors.h \ ./src/libstfio/abf/axon/Common/adcdac.h \ ./src/libstfio/abf/axon/Common/ArrayPtr.hpp \ ./src/libstfio/abf/axon/Common/wincpp.hpp \ ./src/libstfio/abf/axon2/ProtocolReaderABF2.hpp \ ./src/libstfio/abf/axon2/SimpleStringCache.hpp \ ./src/libstfio/abf/axon2/ProtocolStructs.h \ ./src/libstfio/abf/axon2/abf2headr.h \ ./src/libstfio/atf/atflib.h \ ./src/libstfio/axg/axglib.h \ ./src/libstfio/axg/AxoGraph_ReadWrite.h \ ./src/libstfio/axg/fileUtils.h \ ./src/libstfio/axg/stringUtils.h \ ./src/libstfio/axg/byteswap.h \ ./src/libstfio/axg/longdef.h \ ./src/libstfio/biosig/biosiglib.h \ ./src/libstfio/igor/igorlib.h \ ./src/libstfio/igor/CrossPlatformFileIO.h \ ./src/libstfio/igor/IgorBin.h \ ./src/libstfio/intan/common.h \ ./src/libstfio/intan/intanlib.h \ ./src/libstfio/intan/streams.h \ ./src/libstfnum/stfnum.h ./src/libstfnum/fit.h ./src/libstfnum/spline.h \ ./src/libstfnum/measure.h \ ./src/libstfnum/levmar/lm.h ./src/libstfnum/levmar/levmar.h \ ./src/libstfnum/levmar/misc.h ./src/libstfnum/levmar/compiler.h \ ./src/libstfnum/funclib.h \ ./src/stimfit/stf.h \ ./src/stimfit/gui/app.h \ ./src/stimfit/gui/copygrid.h ./src/stimfit/gui/graph.h \ ./src/stimfit/gui/printout.h \ ./src/stimfit/gui/doc.h ./src/stimfit/gui/parentframe.h ./src/stimfit/gui/childframe.h ./src/stimfit/gui/view.h \ ./src/stimfit/gui/table.h ./src/stimfit/gui/zoom.h \ ./src/stimfit/gui/dlgs/convertdlg.h \ ./src/stimfit/gui/dlgs/cursorsdlg.h ./src/stimfit/gui/dlgs/eventdlg.h \ ./src/stimfit/gui/dlgs/fitseldlg.h ./src/stimfit/gui/dlgs/smalldlgs.h \ ./src/stimfit/gui/usrdlg/usrdlg.h \ ./src/test/gtest/include/gtest/gtest-death-test.h \ ./src/test/gtest/include/gtest/gtest-message.h \ ./src/test/gtest/include/gtest/gtest-param-test.h.pump \ ./src/test/gtest/include/gtest/gtest-printers.h \ ./src/test/gtest/include/gtest/gtest-spi.h \ ./src/test/gtest/include/gtest/gtest-typed-test.h \ ./src/test/gtest/include/gtest/gtest.h \ ./src/test/gtest/include/gtest/gtest-param-test.h \ ./src/test/gtest/include/gtest/gtest_pred_impl.h \ ./src/test/gtest/include/gtest/gtest_prod.h \ ./src/test/gtest/include/gtest/gtest-test-part.h \ ./src/test/gtest/include/gtest/internal/gtest-death-test-internal.h \ ./src/test/gtest/include/gtest/internal/gtest-linked_ptr.h \ ./src/test/gtest/include/gtest/internal/gtest-param-util.h \ ./src/test/gtest/include/gtest/internal/gtest-tuple.h \ ./src/test/gtest/include/gtest/internal/gtest-type-util.h.pump \ ./src/test/gtest/include/gtest/internal/gtest-filepath.h \ ./src/test/gtest/include/gtest/internal/gtest-param-util-generated.h \ ./src/test/gtest/include/gtest/internal/gtest-port.h \ ./src/test/gtest/include/gtest/internal/gtest-tuple.h.pump \ ./src/test/gtest/include/gtest/internal/gtest-internal.h \ ./src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump \ ./src/test/gtest/include/gtest/internal/gtest-string.h \ ./src/test/gtest/include/gtest/internal/gtest-type-util.h \ ./src/test/gtest/src/gtest-internal-inl.h EXTRA_DIST = ./src/stimfit/res/16-em-down.xpm EXTRA_DIST+= ./src/stimfit/res/16-em-open.xpm EXTRA_DIST+= ./src/stimfit/res/accept.xpm EXTRA_DIST+= ./src/stimfit/res/arrow_down.xpm EXTRA_DIST+= ./src/stimfit/res/arrow_left.xpm EXTRA_DIST+= ./src/stimfit/res/arrow_out.xpm EXTRA_DIST+= ./src/stimfit/res/arrow_right.xpm EXTRA_DIST+= ./src/stimfit/res/arrow_up.xpm EXTRA_DIST+= ./src/stimfit/res/camera.xpm EXTRA_DIST+= ./src/stimfit/res/camera_ps.xpm EXTRA_DIST+= ./src/stimfit/res/ch1.xpm EXTRA_DIST+= ./src/stimfit/res/ch2.xpm EXTRA_DIST+= ./src/stimfit/res/cursor.xpm EXTRA_DIST+= ./src/stimfit/res/event.xpm EXTRA_DIST+= ./src/stimfit/res/fit.xpm EXTRA_DIST+= ./src/stimfit/res/fit_lim.xpm EXTRA_DIST+= ./src/stimfit/res/latency_lim.xpm EXTRA_DIST+= ./src/stimfit/res/resultset_first.xpm EXTRA_DIST+= ./src/stimfit/res/resultset_last.xpm EXTRA_DIST+= ./src/stimfit/res/resultset_next.xpm EXTRA_DIST+= ./src/stimfit/res/resultset_previous.xpm EXTRA_DIST+= ./src/stimfit/res/slope.xpm EXTRA_DIST+= ./src/stimfit/res/stimfit.png EXTRA_DIST+= ./src/stimfit/res/stimfit_16.png EXTRA_DIST+= ./src/stimfit/res/stimfit_32.png EXTRA_DIST+= ./src/stimfit/res/stimfit_48.png EXTRA_DIST+= ./src/stimfit/res/stimfit_128.png EXTRA_DIST+= ./src/stimfit/res/stimfit_256.png EXTRA_DIST+= ./src/stimfit/res/stimfit_512.png EXTRA_DIST+= ./src/stimfit/res/sum_new.xpm EXTRA_DIST+= ./src/stimfit/res/sum_new_aligned.xpm EXTRA_DIST+= ./src/stimfit/res/table.xpm EXTRA_DIST+= ./src/stimfit/res/zoom.xpm EXTRA_DIST+= ./src/stimfit/res/zoom_in.xpm EXTRA_DIST+= ./src/stimfit/res/zoom_out.xpm EXTRA_DIST+= ./src/libstfnum/levmar/Axb_core.c EXTRA_DIST+= ./src/libstfnum/levmar/lmbc_core.c EXTRA_DIST+= ./src/libstfnum/levmar/lm_core.c EXTRA_DIST+= ./src/libstfnum/levmar/lmlec_core.c EXTRA_DIST+= ./src/libstfnum/levmar/misc_core.c EXTRA_DIST+= ./src/libstfnum/levmar/LICENSE EXTRA_DIST+= ./src/libstfnum/levmar/README.txt EXTRA_DIST+= ./doc/Doxyfile EXTRA_DIST+= ./m4/acsite.m4 EXTRA_DIST+= ./autogen.sh EXTRA_DIST+= ./Makefile.static EXTRA_DIST+= ./dist/macosx/scripts/conf_mac_release.sh EXTRA_DIST+= ./dist/macosx/scripts/change_deps_release.sh EXTRA_DIST+= ./dist/macosx/app.r EXTRA_DIST+= ./dist/macosx/stimfit.icns EXTRA_DIST+= ./src/pystfio/__init__.py # EXTRA_DIST+= ./src/pystfio/stfioswig_wrap.cxx # EXTRA_DIST+= ./src/pystfio/stfio.py EXTRA_DIST+= ./src/pystfio/pystfio.cxx EXTRA_DIST+= ./src/pystfio/pystfio.i EXTRA_DIST+= ./src/pystfio/stfio_plot.py EXTRA_DIST+= ./src/pystfio/stfio_neo.py EXTRA_DIST+= ./src/pystfio/unittest_stfio.py # EXTRA_DIST+= ./src/pystfio/test.h5 EXTRA_DIST+= ./src/pystfio/pystfio.h EXTRA_DIST+= ./dist/debian/changelog EXTRA_DIST+= ./dist/debian/compat EXTRA_DIST+= ./dist/debian/control EXTRA_DIST+= ./dist/debian/copyright EXTRA_DIST+= ./dist/debian/docs EXTRA_DIST+= ./dist/debian/mkdeb.sh EXTRA_DIST+= ./dist/debian/python3-stfio.files EXTRA_DIST+= ./dist/debian/python3-stfio.install EXTRA_DIST+= ./dist/debian/python3-stfio.lintian-overrides EXTRA_DIST+= ./dist/debian/rules EXTRA_DIST+= ./dist/debian/stimfit.1 EXTRA_DIST+= ./dist/debian/stimfit.desktop EXTRA_DIST+= ./dist/debian/stimfit.files EXTRA_DIST+= ./dist/debian/stimfit.install EXTRA_DIST+= ./src/test/gtest/CHANGES EXTRA_DIST+= ./src/test/gtest/CONTRIBUTORS EXTRA_DIST+= ./src/test/gtest/COPYING EXTRA_DIST+= ./src/test/gtest/README EXTRA_DIST+= ./src/test/gtest/src/gtest.cc EXTRA_DIST+= ./src/test/gtest/src/gtest-death-test.cc EXTRA_DIST+= ./src/test/gtest/src/gtest-filepath.cc EXTRA_DIST+= ./src/test/gtest/src/gtest-port.cc EXTRA_DIST+= ./src/test/gtest/src/gtest-printers.cc EXTRA_DIST+= ./src/test/gtest/src/gtest-test-part.cc EXTRA_DIST+= ./src/test/gtest/src/gtest-typed-test.cc if BUILD_PYTHON PYTHON_ADDINCLUDES = $(LIBPYTHON_INCLUDES) $(LIBWXPYTHON_INCLUDES) PYTHON_ADDLDFLAGS = $(LIBPYTHON_LDFLAGS) PYTHON_ADDLIBS = ./src/stimfit/py/libpystf.la else !BUILD_PYTHON PYTHON_ADDLDFLAGS = PYTHON_ADDLIBS = PYTHON_ADDINCLUDES = endif !BUILD_PYTHON INCLUDES = $(PYTHON_ADDINCLUDES) stimfit_CXXFLAGS = $(OPT_CXXFLAGS) $(WX_CXXFLAGS) stimfit_LDFLAGS = $(LIBLAPACK_LDFLAGS) $(PYTHON_ADDLDFLAGS) $(LIBSTF_LDFLAGS) $(LIBBIOSIG_LDFLAGS) stimfit_LDADD = $(WX_LIBS) -lfftw3 ./src/stimfit/libstimfit.la ./src/libstfio/libstfio.la ./src/libstfnum/libstfnum.la # $(PYTHON_ADDLIBS) stimfittest_CXXFLAGS = $(GT_CXXFLAGS) $(WX_CXXFLAGS) stimfittest_CPPFLAGS = ${CPPFLAGS} $(GT_CPPFLAGS) -DSTF_TEST -I$(top_srcdir)/src/test/gtest -I$(top_srcdir)/src/test/gtest/include stimfittest_LDFLAGS = $(LIBLAPACK_LDFLAGS) $(PYTHON_ADDLDFLAGS) $(GT_LDFLAGS) stimfittest_LDADD = $(WX_LIBS) $(PYTHON_ADDLIBS) $(GT_LIBS) -lfftw3 ./src/stimfit/libstimfit.la ./src/libstfio/libstfio.la ./src/libstfnum/libstfnum.la if WITH_BIOSIGLITE stimfit_LDADD += ./src/libbiosiglite/libbiosiglite.la stimfittest_LDADD += ./src/libbiosiglite/libbiosiglite.la endif if !ISDARWIN if BUILD_DEBIAN LTTARGET = /usr/lib/stimfit else LTTARGET = $(prefix)/lib/stimfit endif install-exec-hook: $(LIBTOOL) --finish $(prefix)/lib/stimfit chrpath -r $(LTTARGET) $(prefix)/bin/stimfit if BUILD_DEBIAN chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libpystf.so chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libstimfit.so chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libstfio.so chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libstfnum.so if WITH_BIOSIGLITE chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libbiosiglite.so endif endif install -d $(prefix)/share/applications install -m 644 $(top_srcdir)/dist/debian/stimfit.desktop $(prefix)/share/applications/ for size in 16 32 48 128 256 512; do \ install -d $(prefix)/share/icons/hicolor/$${size}x$${size}/apps; \ install -m 644 $(top_srcdir)/src/stimfit/res/stimfit_$${size}.png $(prefix)/share/icons/hicolor/$${size}x$${size}/apps/stimfit.png; \ done uninstall-hook: for size in 16 32 48 128 256 512; do \ rm -f $(prefix)/share/icons/hicolor/$${size}x$${size}/apps/stimfit.png; \ done rm -f $(prefix)/share/applications/stimfit.desktop else ISDARWIN LTTARGET=$(prefix)/lib/stimfit # wxMac resource fork/unbundled app install: stimfit mkdir -p ${DESTDIR}/stimfit.app/Contents/MacOS mkdir -p ${DESTDIR}/stimfit.app/Contents/Resources mkdir -p ${DESTDIR}/stimfit.app/Contents/Resources/English.lproj mkdir -p ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit mkdir -p ${DESTDIR}/stimfit.app/Contents/lib/stimfit cp -v ./src/stimfit/.libs/libstimfit.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib cp -v ./src/libstfio/.libs/libstfio.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfio.dylib cp -v ./src/libstfnum/.libs/libstfnum.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfnum.dylib if WITH_BIOSIGLITE cp -v ./src/libbiosiglite/.libs/libbiosiglite.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libbiosiglite.dylib endif cp $(top_srcdir)/dist/macosx/stimfit.plist.in ${DESTDIR}/stimfit.app/Contents/Info.plist echo "APPL????\c" > ${DESTDIR}/stimfit.app/Contents/PkgInfo rm -f ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) cp -p -f .libs/stimfit$(EXEEXT) ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) if BUILD_PYTHON cp -v ./src/stimfit/py/.libs/libpystf.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib ln -sf ../../lib/stimfit/libpystf.dylib ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/_stf.so cp -v $(top_srcdir)/src/stimfit/py/*.py ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/ cp -v $(top_srcdir)/src/pystfio/*.py ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/ ${PYTHON} -m compileall -l ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/ endif BUILD_PYTHON $(POSTLINK_COMMAND) ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) \ $(srcdir)/dist/macosx/app.r $(MACSETFILE) -a C ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) cp -f $(top_srcdir)/dist/macosx/stimfit.icns ${DESTDIR}/stimfit.app/Contents/Resources/stimfit.icns install_name_tool -change \ $(LTTARGET)/libstimfit.dylib \ @executable_path/../lib/stimfit/libstimfit.dylib \ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit install_name_tool -change \ $(LTTARGET)/libstfio.dylib \ @executable_path/../lib/stimfit/libstfio.dylib \ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit install_name_tool -change \ $(LTTARGET)/libstfnum.dylib \ @executable_path/../lib/stimfit/libstfnum.dylib \ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit install_name_tool -change \ $(LTTARGET)/libstimfit.dylib \ @executable_path/../lib/stimfit/libstimfit.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib install_name_tool -change \ $(LTTARGET)/libstfio.dylib \ @executable_path/../lib/stimfit/libstfio.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib install_name_tool -change \ $(LTTARGET)/libstfio.dylib \ @executable_path/../lib/stimfit/libstfio.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfio.dylib install_name_tool -change \ $(LTTARGET)/libstfnum.dylib \ @executable_path/../lib/stimfit/libstfnum.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib install_name_tool -change \ $(LTTARGET)/libstfnum.dylib \ @executable_path/../lib/stimfit/libstfnum.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfnum.dylib if WITH_BIOSIGLITE install_name_tool -change \ $(LTTARGET)/libbiosiglite.dylib \ @executable_path/../lib/stimfit/libbiosiglite.dylib \ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit install_name_tool -change \ $(LTTARGET)/libbiosiglite.dylib \ @executable_path/../lib/stimfit/libbiosiglite.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib install_name_tool -change \ $(LTTARGET)/libbiosiglite.dylib \ @executable_path/../lib/stimfit/libbiosiglite.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfnum.dylib endif if BUILD_PYTHON install_name_tool -change \ $(LTTARGET)/libstimfit.dylib \ @executable_path/../lib/stimfit/libstimfit.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib install_name_tool -change \ $(LTTARGET)/libstfio.dylib \ @executable_path/../lib/stimfit/libstfio.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib install_name_tool -change \ $(LTTARGET)/libstfnum.dylib \ @executable_path/../lib/stimfit/libstfnum.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib install_name_tool -change \ $(LTTARGET)/libpystf.dylib \ @executable_path/../lib/stimfit/libpystf.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib if WITH_BIOSIGLITE install_name_tool -change \ $(LTTARGET)/libbiosiglite.dylib \ @executable_path/../lib/stimfit/libbiosiglite.dylib \ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib endif endif BUILD_PYTHON endif ISDARWIN endif # !BUILD_MODULE stimfit-0.16.7/Makefile.in0000664000175000017500000030437514764352410011036 # Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 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@ 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@ @BUILD_MODULE_FALSE@bin_PROGRAMS = stimfit$(EXEEXT) @BUILD_MODULE_FALSE@check_PROGRAMS = stimfittest$(EXEEXT) @BUILD_MODULE_FALSE@TESTS = $(check_PROGRAMS) @BUILD_MODULE_FALSE@@WITH_BIOSIGLITE_TRUE@am__append_1 = ./src/libbiosiglite/libbiosiglite.la @BUILD_MODULE_FALSE@@WITH_BIOSIGLITE_TRUE@am__append_2 = ./src/libbiosiglite/libbiosiglite.la subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/acsite.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.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__noinst_HEADERS_DIST) \ $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = stfconf.h CONFIG_CLEAN_FILES = dist/macosx/stimfit.plist \ dist/macosx/macports/insert_checksums.sh \ dist/macosx/scripts/mkimage.sh \ dist/macosx/package.pmdoc/index.xml dist/debian/mkdeb.sh \ dist/debian/mkquick.sh setup.py \ dist/conda/py-stfio-debug/meta.yaml \ dist/conda/py-stfio/meta.yaml doc/Doxyfile doc/sphinx/conf.py \ Makefile.static CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__stimfit_SOURCES_DIST = ./src/stimfit/gui/main.cpp @BUILD_MODULE_FALSE@am_stimfit_OBJECTS = stimfit-main.$(OBJEXT) stimfit_OBJECTS = $(am_stimfit_OBJECTS) am__DEPENDENCIES_1 = @BUILD_MODULE_FALSE@stimfit_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @BUILD_MODULE_FALSE@ ./src/stimfit/libstimfit.la \ @BUILD_MODULE_FALSE@ ./src/libstfio/libstfio.la \ @BUILD_MODULE_FALSE@ ./src/libstfnum/libstfnum.la \ @BUILD_MODULE_FALSE@ $(am__append_1) 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 = stimfit_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(stimfit_CXXFLAGS) \ $(CXXFLAGS) $(stimfit_LDFLAGS) $(LDFLAGS) -o $@ am__stimfittest_SOURCES_DIST = ./src/test/section.cpp \ ./src/test/channel.cpp ./src/test/recording.cpp \ ./src/test/fit.cpp ./src/test/measure.cpp \ ./src/test/gtest/src/gtest-all.cc \ ./src/test/gtest/src/gtest_main.cc @BUILD_MODULE_FALSE@am_stimfittest_OBJECTS = \ @BUILD_MODULE_FALSE@ stimfittest-section.$(OBJEXT) \ @BUILD_MODULE_FALSE@ stimfittest-channel.$(OBJEXT) \ @BUILD_MODULE_FALSE@ stimfittest-recording.$(OBJEXT) \ @BUILD_MODULE_FALSE@ stimfittest-fit.$(OBJEXT) \ @BUILD_MODULE_FALSE@ stimfittest-measure.$(OBJEXT) \ @BUILD_MODULE_FALSE@ stimfittest-gtest-all.$(OBJEXT) \ @BUILD_MODULE_FALSE@ stimfittest-gtest_main.$(OBJEXT) stimfittest_OBJECTS = $(am_stimfittest_OBJECTS) @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@am__DEPENDENCIES_2 = ./src/stimfit/py/libpystf.la @BUILD_MODULE_FALSE@stimfittest_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @BUILD_MODULE_FALSE@ $(am__DEPENDENCIES_2) \ @BUILD_MODULE_FALSE@ $(am__DEPENDENCIES_1) \ @BUILD_MODULE_FALSE@ ./src/stimfit/libstimfit.la \ @BUILD_MODULE_FALSE@ ./src/libstfio/libstfio.la \ @BUILD_MODULE_FALSE@ ./src/libstfnum/libstfnum.la \ @BUILD_MODULE_FALSE@ $(am__append_2) stimfittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(stimfittest_CXXFLAGS) \ $(CXXFLAGS) $(stimfittest_LDFLAGS) $(LDFLAGS) -o $@ 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__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/stimfit-main.Po \ ./$(DEPDIR)/stimfittest-channel.Po \ ./$(DEPDIR)/stimfittest-fit.Po \ ./$(DEPDIR)/stimfittest-gtest-all.Po \ ./$(DEPDIR)/stimfittest-gtest_main.Po \ ./$(DEPDIR)/stimfittest-measure.Po \ ./$(DEPDIR)/stimfittest-recording.Po \ ./$(DEPDIR)/stimfittest-section.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 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 = $(stimfit_SOURCES) $(stimfittest_SOURCES) DIST_SOURCES = $(am__stimfit_SOURCES_DIST) \ $(am__stimfittest_SOURCES_DIST) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__noinst_HEADERS_DIST = ./src/libstfio/channel.h \ ./src/libstfio/section.h ./src/libstfio/recording.h \ ./src/libstfio/stfio.h ./src/libstfio/cfs/cfslib.h \ ./src/libstfio/cfs/cfs.h ./src/libstfio/cfs/machine.h \ ./src/libstfio/hdf5/hdf5lib.h ./src/libstfio/heka/hekalib.h \ ./src/libstfio/abf/abflib.h \ ./src/libstfio/abf/axon/AxAbfFio32/abffiles.h \ ./src/libstfio/abf/axon/AxAbfFio32/csynch.hpp \ ./src/libstfio/abf/axon/AxAbfFio32/filedesc.hpp \ ./src/libstfio/abf/axon/Common/FileReadCache.hpp \ ./src/libstfio/abf/axon/Common/FileIO.hpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfheadr.h \ ./src/libstfio/abf/axon/AxAbfFio32/oldheadr.h \ ./src/libstfio/abf/axon/AxAbfFio32/abfutil.h \ ./src/libstfio/abf/axon/AxAbfFio32/msbincvt.h \ ./src/libstfio/abf/axon/Common/unix.h \ ./src/libstfio/abf/axon/Common/axodefn.h \ ./src/libstfio/abf/axon/Common/axodebug.h \ ./src/libstfio/abf/axon/Common/wincpp.hpp \ ./src/libstfio/abf/axon/AxAbfFio32/AxAbffio32.h \ ./src/libstfio/abf/axon/AxAbfFio32/abfoldnx.h \ ./src/libstfio/abf/axon/Common/resource.h \ ./src/libstfio/abf/axon/AxAtfFio32/axatffio32.h \ ./src/libstfio/abf/axon/AxAtfFio32/atfutil.h \ ./src/libstfio/abf/axon/AxAtfFio32/atfintl.h \ ./src/libstfio/abf/axon/Common/colors.h \ ./src/libstfio/abf/axon/Common/adcdac.h \ ./src/libstfio/abf/axon/Common/ArrayPtr.hpp \ ./src/libstfio/abf/axon2/ProtocolReaderABF2.hpp \ ./src/libstfio/abf/axon2/SimpleStringCache.hpp \ ./src/libstfio/abf/axon2/ProtocolStructs.h \ ./src/libstfio/abf/axon2/abf2headr.h \ ./src/libstfio/atf/atflib.h ./src/libstfio/axg/axglib.h \ ./src/libstfio/axg/AxoGraph_ReadWrite.h \ ./src/libstfio/axg/fileUtils.h \ ./src/libstfio/axg/stringUtils.h ./src/libstfio/axg/byteswap.h \ ./src/libstfio/axg/longdef.h ./src/libstfio/biosig/biosiglib.h \ ./src/libstfio/igor/igorlib.h \ ./src/libstfio/igor/CrossPlatformFileIO.h \ ./src/libstfio/igor/IgorBin.h ./src/libstfio/intan/common.h \ ./src/libstfio/intan/intanlib.h ./src/libstfio/intan/streams.h \ ./src/libstfnum/stfnum.h ./src/libstfnum/fit.h \ ./src/libstfnum/spline.h ./src/libstfnum/measure.h \ ./src/libstfnum/levmar/lm.h ./src/libstfnum/levmar/levmar.h \ ./src/libstfnum/levmar/misc.h \ ./src/libstfnum/levmar/compiler.h ./src/libstfnum/funclib.h \ ./src/stimfit/stf.h ./src/stimfit/gui/app.h \ ./src/stimfit/gui/copygrid.h ./src/stimfit/gui/graph.h \ ./src/stimfit/gui/printout.h ./src/stimfit/gui/doc.h \ ./src/stimfit/gui/parentframe.h ./src/stimfit/gui/childframe.h \ ./src/stimfit/gui/view.h ./src/stimfit/gui/table.h \ ./src/stimfit/gui/zoom.h ./src/stimfit/gui/dlgs/convertdlg.h \ ./src/stimfit/gui/dlgs/cursorsdlg.h \ ./src/stimfit/gui/dlgs/eventdlg.h \ ./src/stimfit/gui/dlgs/fitseldlg.h \ ./src/stimfit/gui/dlgs/smalldlgs.h \ ./src/stimfit/gui/usrdlg/usrdlg.h \ ./src/test/gtest/include/gtest/gtest-death-test.h \ ./src/test/gtest/include/gtest/gtest-message.h \ ./src/test/gtest/include/gtest/gtest-param-test.h.pump \ ./src/test/gtest/include/gtest/gtest-printers.h \ ./src/test/gtest/include/gtest/gtest-spi.h \ ./src/test/gtest/include/gtest/gtest-typed-test.h \ ./src/test/gtest/include/gtest/gtest.h \ ./src/test/gtest/include/gtest/gtest-param-test.h \ ./src/test/gtest/include/gtest/gtest_pred_impl.h \ ./src/test/gtest/include/gtest/gtest_prod.h \ ./src/test/gtest/include/gtest/gtest-test-part.h \ ./src/test/gtest/include/gtest/internal/gtest-death-test-internal.h \ ./src/test/gtest/include/gtest/internal/gtest-linked_ptr.h \ ./src/test/gtest/include/gtest/internal/gtest-param-util.h \ ./src/test/gtest/include/gtest/internal/gtest-tuple.h \ ./src/test/gtest/include/gtest/internal/gtest-type-util.h.pump \ ./src/test/gtest/include/gtest/internal/gtest-filepath.h \ ./src/test/gtest/include/gtest/internal/gtest-param-util-generated.h \ ./src/test/gtest/include/gtest/internal/gtest-port.h \ ./src/test/gtest/include/gtest/internal/gtest-tuple.h.pump \ ./src/test/gtest/include/gtest/internal/gtest-internal.h \ ./src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump \ ./src/test/gtest/include/gtest/internal/gtest-string.h \ ./src/test/gtest/include/gtest/internal/gtest-type-util.h \ ./src/test/gtest/src/gtest-internal-inl.h HEADERS = $(noinst_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope check recheck distdir distdir-am dist dist-all \ distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ stfconf.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)` am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } 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__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.static.in \ $(srcdir)/setup.py.in $(srcdir)/stfconf.h.in \ $(top_srcdir)/dist/conda/py-stfio-debug/meta.yaml.in \ $(top_srcdir)/dist/conda/py-stfio/meta.yaml.in \ $(top_srcdir)/dist/debian/mkdeb.sh.in \ $(top_srcdir)/dist/debian/mkquick.sh.in \ $(top_srcdir)/dist/macosx/macports/insert_checksums.sh.in \ $(top_srcdir)/dist/macosx/package.pmdoc/index.xml.in \ $(top_srcdir)/dist/macosx/scripts/mkimage.sh.in \ $(top_srcdir)/dist/macosx/stimfit.plist.in \ $(top_srcdir)/doc/Doxyfile.in \ $(top_srcdir)/doc/sphinx/conf.py.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README TODO compile config.guess config.sub \ depcomp install-sh ltmain.sh missing test-driver 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) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi 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@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ GT_CPPFLAGS = @GT_CPPFLAGS@ GT_CXXFLAGS = @GT_CXXFLAGS@ GT_LDFLAGS = @GT_LDFLAGS@ GT_LIBS = @GT_LIBS@ HDF5_CFLAGS = @HDF5_CFLAGS@ HDF5_LIBS = @HDF5_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBIOSIG_LDFLAGS = @LIBBIOSIG_LDFLAGS@ LIBHDF5_LDFLAGS = @LIBHDF5_LDFLAGS@ LIBLAPACK_LDFLAGS = @LIBLAPACK_LDFLAGS@ LIBNUMPY_INCLUDES = @LIBNUMPY_INCLUDES@ LIBOBJS = @LIBOBJS@ LIBPYTHON_INCLUDES = @LIBPYTHON_INCLUDES@ LIBPYTHON_LDFLAGS = @LIBPYTHON_LDFLAGS@ LIBS = @LIBS@ LIBSTF_LDFLAGS = @LIBSTF_LDFLAGS@ LIBTOOL = @LIBTOOL@ LIBWXPYTHON_INCLUDES = @LIBWXPYTHON_INCLUDES@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MACSETFILE = @MACSETFILE@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPT_CXXFLAGS = @OPT_CXXFLAGS@ 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@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POSTLINK_COMMAND = @POSTLINK_COMMAND@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_DIST_PKG = @PYTHON_DIST_PKG@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ PYTHON_NUMPY_INCLUDE = @PYTHON_NUMPY_INCLUDE@ PYTHON_PRE_DIST_PKG = @PYTHON_PRE_DIST_PKG@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ PYTHON_WXPYTHON_INCLUDE = @PYTHON_WXPYTHON_INCLUDE@ PY_AC_VERSION = @PY_AC_VERSION@ RANLIB = @RANLIB@ REZ = @REZ@ SED = @SED@ SETFILE = @SETFILE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STFIO_PYTHON_LIBNAME = @STFIO_PYTHON_LIBNAME@ STF_PYTHON_LIBNAME = @STF_PYTHON_LIBNAME@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ VERSION = @VERSION@ WX_CPPFLAGS = @WX_CPPFLAGS@ WX_CXXFLAGS = @WX_CXXFLAGS@ WX_LIBS = @WX_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ 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@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ 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@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src ACLOCAL_AMFLAGS = ${ACLOCAL_AMFLAGS} -I m4 @BUILD_MODULE_FALSE@stimfit_SOURCES = ./src/stimfit/gui/main.cpp @BUILD_MODULE_FALSE@stimfittest_SOURCES = ./src/test/section.cpp ./src/test/channel.cpp ./src/test/recording.cpp ./src/test/fit.cpp ./src/test/measure.cpp \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-all.cc ./src/test/gtest/src/gtest_main.cc @BUILD_MODULE_FALSE@noinst_HEADERS = \ @BUILD_MODULE_FALSE@ ./src/libstfio/channel.h ./src/libstfio/section.h ./src/libstfio/recording.h ./src/libstfio/stfio.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/cfs/cfslib.h ./src/libstfio/cfs/cfs.h ./src/libstfio/cfs/machine.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/hdf5/hdf5lib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/heka/hekalib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/abflib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/abffiles.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/csynch.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/filedesc.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/FileReadCache.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/FileIO.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/abfheadr.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/oldheadr.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/abfutil.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/msbincvt.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/unix.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/axodefn.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/axodebug.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/wincpp.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/AxAbffio32.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAbfFio32/abfoldnx.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/resource.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAtfFio32/axatffio32.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAtfFio32/atfutil.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/AxAtfFio32/atfintl.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/colors.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/adcdac.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/ArrayPtr.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon/Common/wincpp.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon2/ProtocolReaderABF2.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon2/SimpleStringCache.hpp \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon2/ProtocolStructs.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/abf/axon2/abf2headr.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/atf/atflib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/axg/axglib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/axg/AxoGraph_ReadWrite.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/axg/fileUtils.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/axg/stringUtils.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/axg/byteswap.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/axg/longdef.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/biosig/biosiglib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/igor/igorlib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/igor/CrossPlatformFileIO.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/igor/IgorBin.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/intan/common.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/intan/intanlib.h \ @BUILD_MODULE_FALSE@ ./src/libstfio/intan/streams.h \ @BUILD_MODULE_FALSE@ ./src/libstfnum/stfnum.h ./src/libstfnum/fit.h ./src/libstfnum/spline.h \ @BUILD_MODULE_FALSE@ ./src/libstfnum/measure.h \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/lm.h ./src/libstfnum/levmar/levmar.h \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/misc.h ./src/libstfnum/levmar/compiler.h \ @BUILD_MODULE_FALSE@ ./src/libstfnum/funclib.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/stf.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/app.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/copygrid.h ./src/stimfit/gui/graph.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/printout.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/doc.h ./src/stimfit/gui/parentframe.h ./src/stimfit/gui/childframe.h ./src/stimfit/gui/view.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/table.h ./src/stimfit/gui/zoom.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/dlgs/convertdlg.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/dlgs/cursorsdlg.h ./src/stimfit/gui/dlgs/eventdlg.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/dlgs/fitseldlg.h ./src/stimfit/gui/dlgs/smalldlgs.h \ @BUILD_MODULE_FALSE@ ./src/stimfit/gui/usrdlg/usrdlg.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-death-test.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-message.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-param-test.h.pump \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-printers.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-spi.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-typed-test.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-param-test.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest_pred_impl.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest_prod.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/gtest-test-part.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-death-test-internal.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-linked_ptr.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-param-util.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-tuple.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-type-util.h.pump \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-filepath.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-param-util-generated.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-port.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-tuple.h.pump \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-internal.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-string.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/include/gtest/internal/gtest-type-util.h \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-internal-inl.h # EXTRA_DIST+= ./src/pystfio/stfioswig_wrap.cxx # EXTRA_DIST+= ./src/pystfio/stfio.py # EXTRA_DIST+= ./src/pystfio/test.h5 @BUILD_MODULE_FALSE@EXTRA_DIST = ./src/stimfit/res/16-em-down.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/16-em-open.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/accept.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/arrow_down.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/arrow_left.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/arrow_out.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/arrow_right.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/arrow_up.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/camera.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/camera_ps.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/ch1.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/ch2.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/cursor.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/event.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/fit.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/fit_lim.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/latency_lim.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/resultset_first.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/resultset_last.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/resultset_next.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/resultset_previous.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/slope.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/stimfit.png \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/stimfit_16.png \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/stimfit_32.png \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/stimfit_48.png \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/stimfit_128.png \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/stimfit_256.png \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/stimfit_512.png \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/sum_new.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/sum_new_aligned.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/table.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/zoom.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/zoom_in.xpm \ @BUILD_MODULE_FALSE@ ./src/stimfit/res/zoom_out.xpm \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/Axb_core.c \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/lmbc_core.c \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/lm_core.c \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/lmlec_core.c \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/misc_core.c \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/LICENSE \ @BUILD_MODULE_FALSE@ ./src/libstfnum/levmar/README.txt \ @BUILD_MODULE_FALSE@ ./doc/Doxyfile ./m4/acsite.m4 ./autogen.sh \ @BUILD_MODULE_FALSE@ ./Makefile.static \ @BUILD_MODULE_FALSE@ ./dist/macosx/scripts/conf_mac_release.sh \ @BUILD_MODULE_FALSE@ ./dist/macosx/scripts/change_deps_release.sh \ @BUILD_MODULE_FALSE@ ./dist/macosx/app.r \ @BUILD_MODULE_FALSE@ ./dist/macosx/stimfit.icns \ @BUILD_MODULE_FALSE@ ./src/pystfio/__init__.py \ @BUILD_MODULE_FALSE@ ./src/pystfio/pystfio.cxx \ @BUILD_MODULE_FALSE@ ./src/pystfio/pystfio.i \ @BUILD_MODULE_FALSE@ ./src/pystfio/stfio_plot.py \ @BUILD_MODULE_FALSE@ ./src/pystfio/stfio_neo.py \ @BUILD_MODULE_FALSE@ ./src/pystfio/unittest_stfio.py \ @BUILD_MODULE_FALSE@ ./src/pystfio/pystfio.h \ @BUILD_MODULE_FALSE@ ./dist/debian/changelog \ @BUILD_MODULE_FALSE@ ./dist/debian/compat ./dist/debian/control \ @BUILD_MODULE_FALSE@ ./dist/debian/copyright ./dist/debian/docs \ @BUILD_MODULE_FALSE@ ./dist/debian/mkdeb.sh \ @BUILD_MODULE_FALSE@ ./dist/debian/python3-stfio.files \ @BUILD_MODULE_FALSE@ ./dist/debian/python3-stfio.install \ @BUILD_MODULE_FALSE@ ./dist/debian/python3-stfio.lintian-overrides \ @BUILD_MODULE_FALSE@ ./dist/debian/rules \ @BUILD_MODULE_FALSE@ ./dist/debian/stimfit.1 \ @BUILD_MODULE_FALSE@ ./dist/debian/stimfit.desktop \ @BUILD_MODULE_FALSE@ ./dist/debian/stimfit.files \ @BUILD_MODULE_FALSE@ ./dist/debian/stimfit.install \ @BUILD_MODULE_FALSE@ ./src/test/gtest/CHANGES \ @BUILD_MODULE_FALSE@ ./src/test/gtest/CONTRIBUTORS \ @BUILD_MODULE_FALSE@ ./src/test/gtest/COPYING \ @BUILD_MODULE_FALSE@ ./src/test/gtest/README \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest.cc \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-death-test.cc \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-filepath.cc \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-port.cc \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-printers.cc \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-test-part.cc \ @BUILD_MODULE_FALSE@ ./src/test/gtest/src/gtest-typed-test.cc @BUILD_MODULE_FALSE@@BUILD_PYTHON_FALSE@PYTHON_ADDINCLUDES = @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@PYTHON_ADDINCLUDES = $(LIBPYTHON_INCLUDES) $(LIBWXPYTHON_INCLUDES) @BUILD_MODULE_FALSE@@BUILD_PYTHON_FALSE@PYTHON_ADDLDFLAGS = @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@PYTHON_ADDLDFLAGS = $(LIBPYTHON_LDFLAGS) @BUILD_MODULE_FALSE@@BUILD_PYTHON_FALSE@PYTHON_ADDLIBS = @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@PYTHON_ADDLIBS = ./src/stimfit/py/libpystf.la @BUILD_MODULE_FALSE@INCLUDES = $(PYTHON_ADDINCLUDES) @BUILD_MODULE_FALSE@stimfit_CXXFLAGS = $(OPT_CXXFLAGS) $(WX_CXXFLAGS) @BUILD_MODULE_FALSE@stimfit_LDFLAGS = $(LIBLAPACK_LDFLAGS) $(PYTHON_ADDLDFLAGS) $(LIBSTF_LDFLAGS) $(LIBBIOSIG_LDFLAGS) @BUILD_MODULE_FALSE@stimfit_LDADD = $(WX_LIBS) -lfftw3 \ @BUILD_MODULE_FALSE@ ./src/stimfit/libstimfit.la \ @BUILD_MODULE_FALSE@ ./src/libstfio/libstfio.la \ @BUILD_MODULE_FALSE@ ./src/libstfnum/libstfnum.la \ @BUILD_MODULE_FALSE@ $(am__append_1) @BUILD_MODULE_FALSE@stimfittest_CXXFLAGS = $(GT_CXXFLAGS) $(WX_CXXFLAGS) @BUILD_MODULE_FALSE@stimfittest_CPPFLAGS = ${CPPFLAGS} $(GT_CPPFLAGS) -DSTF_TEST -I$(top_srcdir)/src/test/gtest -I$(top_srcdir)/src/test/gtest/include @BUILD_MODULE_FALSE@stimfittest_LDFLAGS = $(LIBLAPACK_LDFLAGS) $(PYTHON_ADDLDFLAGS) $(GT_LDFLAGS) @BUILD_MODULE_FALSE@stimfittest_LDADD = $(WX_LIBS) $(PYTHON_ADDLIBS) \ @BUILD_MODULE_FALSE@ $(GT_LIBS) -lfftw3 \ @BUILD_MODULE_FALSE@ ./src/stimfit/libstimfit.la \ @BUILD_MODULE_FALSE@ ./src/libstfio/libstfio.la \ @BUILD_MODULE_FALSE@ ./src/libstfnum/libstfnum.la \ @BUILD_MODULE_FALSE@ $(am__append_2) @BUILD_DEBIAN_FALSE@@BUILD_MODULE_FALSE@@ISDARWIN_FALSE@LTTARGET = $(prefix)/lib/stimfit @BUILD_DEBIAN_TRUE@@BUILD_MODULE_FALSE@@ISDARWIN_FALSE@LTTARGET = /usr/lib/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@LTTARGET = $(prefix)/lib/stimfit all: stfconf.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .cc .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu 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__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): stfconf.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/stfconf.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status stfconf.h $(srcdir)/stfconf.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f stfconf.h stamp-h1 dist/macosx/stimfit.plist: $(top_builddir)/config.status $(top_srcdir)/dist/macosx/stimfit.plist.in cd $(top_builddir) && $(SHELL) ./config.status $@ dist/macosx/macports/insert_checksums.sh: $(top_builddir)/config.status $(top_srcdir)/dist/macosx/macports/insert_checksums.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ dist/macosx/scripts/mkimage.sh: $(top_builddir)/config.status $(top_srcdir)/dist/macosx/scripts/mkimage.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ dist/macosx/package.pmdoc/index.xml: $(top_builddir)/config.status $(top_srcdir)/dist/macosx/package.pmdoc/index.xml.in cd $(top_builddir) && $(SHELL) ./config.status $@ dist/debian/mkdeb.sh: $(top_builddir)/config.status $(top_srcdir)/dist/debian/mkdeb.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ dist/debian/mkquick.sh: $(top_builddir)/config.status $(top_srcdir)/dist/debian/mkquick.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ setup.py: $(top_builddir)/config.status $(srcdir)/setup.py.in cd $(top_builddir) && $(SHELL) ./config.status $@ dist/conda/py-stfio-debug/meta.yaml: $(top_builddir)/config.status $(top_srcdir)/dist/conda/py-stfio-debug/meta.yaml.in cd $(top_builddir) && $(SHELL) ./config.status $@ dist/conda/py-stfio/meta.yaml: $(top_builddir)/config.status $(top_srcdir)/dist/conda/py-stfio/meta.yaml.in cd $(top_builddir) && $(SHELL) ./config.status $@ doc/Doxyfile: $(top_builddir)/config.status $(top_srcdir)/doc/Doxyfile.in cd $(top_builddir) && $(SHELL) ./config.status $@ doc/sphinx/conf.py: $(top_builddir)/config.status $(top_srcdir)/doc/sphinx/conf.py.in cd $(top_builddir) && $(SHELL) ./config.status $@ Makefile.static: $(top_builddir)/config.status $(srcdir)/Makefile.static.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list stimfit$(EXEEXT): $(stimfit_OBJECTS) $(stimfit_DEPENDENCIES) $(EXTRA_stimfit_DEPENDENCIES) @rm -f stimfit$(EXEEXT) $(AM_V_CXXLD)$(stimfit_LINK) $(stimfit_OBJECTS) $(stimfit_LDADD) $(LIBS) stimfittest$(EXEEXT): $(stimfittest_OBJECTS) $(stimfittest_DEPENDENCIES) $(EXTRA_stimfittest_DEPENDENCIES) @rm -f stimfittest$(EXEEXT) $(AM_V_CXXLD)$(stimfittest_LINK) $(stimfittest_OBJECTS) $(stimfittest_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfit-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfittest-channel.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfittest-fit.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfittest-gtest-all.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfittest-gtest_main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfittest-measure.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfittest-recording.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stimfittest-section.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .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 $@ $< stimfit-main.o: ./src/stimfit/gui/main.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stimfit_CXXFLAGS) $(CXXFLAGS) -MT stimfit-main.o -MD -MP -MF $(DEPDIR)/stimfit-main.Tpo -c -o stimfit-main.o `test -f './src/stimfit/gui/main.cpp' || echo '$(srcdir)/'`./src/stimfit/gui/main.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfit-main.Tpo $(DEPDIR)/stimfit-main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/stimfit/gui/main.cpp' object='stimfit-main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stimfit_CXXFLAGS) $(CXXFLAGS) -c -o stimfit-main.o `test -f './src/stimfit/gui/main.cpp' || echo '$(srcdir)/'`./src/stimfit/gui/main.cpp stimfit-main.obj: ./src/stimfit/gui/main.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stimfit_CXXFLAGS) $(CXXFLAGS) -MT stimfit-main.obj -MD -MP -MF $(DEPDIR)/stimfit-main.Tpo -c -o stimfit-main.obj `if test -f './src/stimfit/gui/main.cpp'; then $(CYGPATH_W) './src/stimfit/gui/main.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/stimfit/gui/main.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfit-main.Tpo $(DEPDIR)/stimfit-main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/stimfit/gui/main.cpp' object='stimfit-main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stimfit_CXXFLAGS) $(CXXFLAGS) -c -o stimfit-main.obj `if test -f './src/stimfit/gui/main.cpp'; then $(CYGPATH_W) './src/stimfit/gui/main.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/stimfit/gui/main.cpp'; fi` stimfittest-section.o: ./src/test/section.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-section.o -MD -MP -MF $(DEPDIR)/stimfittest-section.Tpo -c -o stimfittest-section.o `test -f './src/test/section.cpp' || echo '$(srcdir)/'`./src/test/section.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-section.Tpo $(DEPDIR)/stimfittest-section.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/section.cpp' object='stimfittest-section.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-section.o `test -f './src/test/section.cpp' || echo '$(srcdir)/'`./src/test/section.cpp stimfittest-section.obj: ./src/test/section.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-section.obj -MD -MP -MF $(DEPDIR)/stimfittest-section.Tpo -c -o stimfittest-section.obj `if test -f './src/test/section.cpp'; then $(CYGPATH_W) './src/test/section.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/section.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-section.Tpo $(DEPDIR)/stimfittest-section.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/section.cpp' object='stimfittest-section.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-section.obj `if test -f './src/test/section.cpp'; then $(CYGPATH_W) './src/test/section.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/section.cpp'; fi` stimfittest-channel.o: ./src/test/channel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-channel.o -MD -MP -MF $(DEPDIR)/stimfittest-channel.Tpo -c -o stimfittest-channel.o `test -f './src/test/channel.cpp' || echo '$(srcdir)/'`./src/test/channel.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-channel.Tpo $(DEPDIR)/stimfittest-channel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/channel.cpp' object='stimfittest-channel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-channel.o `test -f './src/test/channel.cpp' || echo '$(srcdir)/'`./src/test/channel.cpp stimfittest-channel.obj: ./src/test/channel.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-channel.obj -MD -MP -MF $(DEPDIR)/stimfittest-channel.Tpo -c -o stimfittest-channel.obj `if test -f './src/test/channel.cpp'; then $(CYGPATH_W) './src/test/channel.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/channel.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-channel.Tpo $(DEPDIR)/stimfittest-channel.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/channel.cpp' object='stimfittest-channel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-channel.obj `if test -f './src/test/channel.cpp'; then $(CYGPATH_W) './src/test/channel.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/channel.cpp'; fi` stimfittest-recording.o: ./src/test/recording.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-recording.o -MD -MP -MF $(DEPDIR)/stimfittest-recording.Tpo -c -o stimfittest-recording.o `test -f './src/test/recording.cpp' || echo '$(srcdir)/'`./src/test/recording.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-recording.Tpo $(DEPDIR)/stimfittest-recording.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/recording.cpp' object='stimfittest-recording.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-recording.o `test -f './src/test/recording.cpp' || echo '$(srcdir)/'`./src/test/recording.cpp stimfittest-recording.obj: ./src/test/recording.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-recording.obj -MD -MP -MF $(DEPDIR)/stimfittest-recording.Tpo -c -o stimfittest-recording.obj `if test -f './src/test/recording.cpp'; then $(CYGPATH_W) './src/test/recording.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/recording.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-recording.Tpo $(DEPDIR)/stimfittest-recording.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/recording.cpp' object='stimfittest-recording.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-recording.obj `if test -f './src/test/recording.cpp'; then $(CYGPATH_W) './src/test/recording.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/recording.cpp'; fi` stimfittest-fit.o: ./src/test/fit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-fit.o -MD -MP -MF $(DEPDIR)/stimfittest-fit.Tpo -c -o stimfittest-fit.o `test -f './src/test/fit.cpp' || echo '$(srcdir)/'`./src/test/fit.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-fit.Tpo $(DEPDIR)/stimfittest-fit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/fit.cpp' object='stimfittest-fit.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-fit.o `test -f './src/test/fit.cpp' || echo '$(srcdir)/'`./src/test/fit.cpp stimfittest-fit.obj: ./src/test/fit.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-fit.obj -MD -MP -MF $(DEPDIR)/stimfittest-fit.Tpo -c -o stimfittest-fit.obj `if test -f './src/test/fit.cpp'; then $(CYGPATH_W) './src/test/fit.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/fit.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-fit.Tpo $(DEPDIR)/stimfittest-fit.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/fit.cpp' object='stimfittest-fit.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-fit.obj `if test -f './src/test/fit.cpp'; then $(CYGPATH_W) './src/test/fit.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/fit.cpp'; fi` stimfittest-measure.o: ./src/test/measure.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-measure.o -MD -MP -MF $(DEPDIR)/stimfittest-measure.Tpo -c -o stimfittest-measure.o `test -f './src/test/measure.cpp' || echo '$(srcdir)/'`./src/test/measure.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-measure.Tpo $(DEPDIR)/stimfittest-measure.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/measure.cpp' object='stimfittest-measure.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-measure.o `test -f './src/test/measure.cpp' || echo '$(srcdir)/'`./src/test/measure.cpp stimfittest-measure.obj: ./src/test/measure.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-measure.obj -MD -MP -MF $(DEPDIR)/stimfittest-measure.Tpo -c -o stimfittest-measure.obj `if test -f './src/test/measure.cpp'; then $(CYGPATH_W) './src/test/measure.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/measure.cpp'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-measure.Tpo $(DEPDIR)/stimfittest-measure.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/measure.cpp' object='stimfittest-measure.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-measure.obj `if test -f './src/test/measure.cpp'; then $(CYGPATH_W) './src/test/measure.cpp'; else $(CYGPATH_W) '$(srcdir)/./src/test/measure.cpp'; fi` stimfittest-gtest-all.o: ./src/test/gtest/src/gtest-all.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-gtest-all.o -MD -MP -MF $(DEPDIR)/stimfittest-gtest-all.Tpo -c -o stimfittest-gtest-all.o `test -f './src/test/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`./src/test/gtest/src/gtest-all.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-gtest-all.Tpo $(DEPDIR)/stimfittest-gtest-all.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/gtest/src/gtest-all.cc' object='stimfittest-gtest-all.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-gtest-all.o `test -f './src/test/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`./src/test/gtest/src/gtest-all.cc stimfittest-gtest-all.obj: ./src/test/gtest/src/gtest-all.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-gtest-all.obj -MD -MP -MF $(DEPDIR)/stimfittest-gtest-all.Tpo -c -o stimfittest-gtest-all.obj `if test -f './src/test/gtest/src/gtest-all.cc'; then $(CYGPATH_W) './src/test/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/./src/test/gtest/src/gtest-all.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-gtest-all.Tpo $(DEPDIR)/stimfittest-gtest-all.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/gtest/src/gtest-all.cc' object='stimfittest-gtest-all.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-gtest-all.obj `if test -f './src/test/gtest/src/gtest-all.cc'; then $(CYGPATH_W) './src/test/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/./src/test/gtest/src/gtest-all.cc'; fi` stimfittest-gtest_main.o: ./src/test/gtest/src/gtest_main.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-gtest_main.o -MD -MP -MF $(DEPDIR)/stimfittest-gtest_main.Tpo -c -o stimfittest-gtest_main.o `test -f './src/test/gtest/src/gtest_main.cc' || echo '$(srcdir)/'`./src/test/gtest/src/gtest_main.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-gtest_main.Tpo $(DEPDIR)/stimfittest-gtest_main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/gtest/src/gtest_main.cc' object='stimfittest-gtest_main.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-gtest_main.o `test -f './src/test/gtest/src/gtest_main.cc' || echo '$(srcdir)/'`./src/test/gtest/src/gtest_main.cc stimfittest-gtest_main.obj: ./src/test/gtest/src/gtest_main.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -MT stimfittest-gtest_main.obj -MD -MP -MF $(DEPDIR)/stimfittest-gtest_main.Tpo -c -o stimfittest-gtest_main.obj `if test -f './src/test/gtest/src/gtest_main.cc'; then $(CYGPATH_W) './src/test/gtest/src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/./src/test/gtest/src/gtest_main.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stimfittest-gtest_main.Tpo $(DEPDIR)/stimfittest-gtest_main.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='./src/test/gtest/src/gtest_main.cc' object='stimfittest-gtest_main.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stimfittest_CPPFLAGS) $(CPPFLAGS) $(stimfittest_CXXFLAGS) $(CXXFLAGS) -c -o stimfittest-gtest_main.obj `if test -f './src/test/gtest/src/gtest_main.cc'; then $(CYGPATH_W) './src/test/gtest/src/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/./src/test/gtest/src/gtest_main.cc'; fi` .cpp.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 $@ $< .cpp.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) '$<'` .cpp.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 # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(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-recursive 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-recursive 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 # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? stimfittest.log: stimfittest$(EXEEXT) @p='stimfittest$(EXEEXT)'; \ b='stimfittest'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(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 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || 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-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(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 ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ 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) $(AM_DISTCHECK_DVI_TARGET) \ && $(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 $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile $(PROGRAMS) $(HEADERS) stfconf.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done @BUILD_MODULE_TRUE@install: install-recursive @ISDARWIN_FALSE@install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive 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: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) 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." @BUILD_MODULE_TRUE@install-exec-hook: @ISDARWIN_TRUE@install-exec-hook: @BUILD_MODULE_TRUE@uninstall-hook: @ISDARWIN_TRUE@uninstall-hook: clean: clean-recursive clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f ./$(DEPDIR)/stimfit-main.Po -rm -f ./$(DEPDIR)/stimfittest-channel.Po -rm -f ./$(DEPDIR)/stimfittest-fit.Po -rm -f ./$(DEPDIR)/stimfittest-gtest-all.Po -rm -f ./$(DEPDIR)/stimfittest-gtest_main.Po -rm -f ./$(DEPDIR)/stimfittest-measure.Po -rm -f ./$(DEPDIR)/stimfittest-recording.Po -rm -f ./$(DEPDIR)/stimfittest-section.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f ./$(DEPDIR)/stimfit-main.Po -rm -f ./$(DEPDIR)/stimfittest-channel.Po -rm -f ./$(DEPDIR)/stimfittest-fit.Po -rm -f ./$(DEPDIR)/stimfittest-gtest-all.Po -rm -f ./$(DEPDIR)/stimfittest-gtest_main.Po -rm -f ./$(DEPDIR)/stimfittest-measure.Po -rm -f ./$(DEPDIR)/stimfittest-recording.Po -rm -f ./$(DEPDIR)/stimfittest-section.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: $(am__recursive_targets) all check-am install-am \ install-exec-am install-strip uninstall-am .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--depfiles am--refresh check check-TESTS check-am clean \ clean-binPROGRAMS clean-checkPROGRAMS clean-cscope \ clean-generic clean-libtool cscope cscopelist-am ctags \ ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \ dist-shar dist-tarZ dist-xz dist-zip dist-zstd 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-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-exec-hook install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am recheck tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-hook .PRECIOUS: Makefile @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@install-exec-hook: @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ $(LIBTOOL) --finish $(prefix)/lib/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ chrpath -r $(LTTARGET) $(prefix)/bin/stimfit @BUILD_DEBIAN_TRUE@@BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libpystf.so @BUILD_DEBIAN_TRUE@@BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libstimfit.so @BUILD_DEBIAN_TRUE@@BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libstfio.so @BUILD_DEBIAN_TRUE@@BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libstfnum.so @BUILD_DEBIAN_TRUE@@BUILD_MODULE_FALSE@@ISDARWIN_FALSE@@WITH_BIOSIGLITE_TRUE@ chrpath -r $(LTTARGET) $(prefix)/lib/stimfit/libbiosiglite.so @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ install -d $(prefix)/share/applications @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ install -m 644 $(top_srcdir)/dist/debian/stimfit.desktop $(prefix)/share/applications/ @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ for size in 16 32 48 128 256 512; do \ @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ install -d $(prefix)/share/icons/hicolor/$${size}x$${size}/apps; \ @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ install -m 644 $(top_srcdir)/src/stimfit/res/stimfit_$${size}.png $(prefix)/share/icons/hicolor/$${size}x$${size}/apps/stimfit.png; \ @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ done @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@uninstall-hook: @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ for size in 16 32 48 128 256 512; do \ @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ rm -f $(prefix)/share/icons/hicolor/$${size}x$${size}/apps/stimfit.png; \ @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ done @BUILD_MODULE_FALSE@@ISDARWIN_FALSE@ rm -f $(prefix)/share/applications/stimfit.desktop # wxMac resource fork/unbundled app @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@install: stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ mkdir -p ${DESTDIR}/stimfit.app/Contents/MacOS @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ mkdir -p ${DESTDIR}/stimfit.app/Contents/Resources @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ mkdir -p ${DESTDIR}/stimfit.app/Contents/Resources/English.lproj @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ mkdir -p ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ mkdir -p ${DESTDIR}/stimfit.app/Contents/lib/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ cp -v ./src/stimfit/.libs/libstimfit.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ cp -v ./src/libstfio/.libs/libstfio.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfio.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ cp -v ./src/libstfnum/.libs/libstfnum.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfnum.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ cp -v ./src/libbiosiglite/.libs/libbiosiglite.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libbiosiglite.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ cp $(top_srcdir)/dist/macosx/stimfit.plist.in ${DESTDIR}/stimfit.app/Contents/Info.plist @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ echo "APPL????\c" > ${DESTDIR}/stimfit.app/Contents/PkgInfo @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ rm -f ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ cp -p -f .libs/stimfit$(EXEEXT) ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ cp -v ./src/stimfit/py/.libs/libpystf.dylib ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ ln -sf ../../lib/stimfit/libpystf.dylib ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/_stf.so @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ cp -v $(top_srcdir)/src/stimfit/py/*.py ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ cp -v $(top_srcdir)/src/pystfio/*.py ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ ${PYTHON} -m compileall -l ${DESTDIR}/stimfit.app/Contents/Frameworks/stimfit/ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(POSTLINK_COMMAND) ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(srcdir)/dist/macosx/app.r @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(MACSETFILE) -a C ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit$(EXEEXT) @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ cp -f $(top_srcdir)/dist/macosx/stimfit.icns ${DESTDIR}/stimfit.app/Contents/Resources/stimfit.icns @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstimfit.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstimfit.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfio.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfio.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfnum.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfnum.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstimfit.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstimfit.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfio.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfio.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfio.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfio.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfio.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfnum.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfnum.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfnum.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfnum.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfnum.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ $(LTTARGET)/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ @executable_path/../lib/stimfit/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ ${DESTDIR}/stimfit.app/Contents/MacOS/stimfit @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ $(LTTARGET)/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ @executable_path/../lib/stimfit/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstimfit.dylib @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ $(LTTARGET)/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ @executable_path/../lib/stimfit/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libstfnum.dylib @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ $(LTTARGET)/libstimfit.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstimfit.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfio.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfio.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ $(LTTARGET)/libstfnum.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libstfnum.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ $(LTTARGET)/libpystf.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ @executable_path/../lib/stimfit/libpystf.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ install_name_tool -change \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ $(LTTARGET)/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ @executable_path/../lib/stimfit/libbiosiglite.dylib \ @BUILD_MODULE_FALSE@@BUILD_PYTHON_TRUE@@ISDARWIN_TRUE@@WITH_BIOSIGLITE_TRUE@ ${DESTDIR}/stimfit.app/Contents/lib/stimfit/libpystf.dylib # 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: stimfit-0.16.7/config.sub0000755000175000017500000010511614764352410010742 #! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x$basic_os != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os in linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ | linux-musl* | linux-relibc* | linux-uclibc* ) ;; uclinux-uclibc* ) ;; -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 exit 1 ;; kfreebsd*-gnu* | kopensolaris*-gnu*) ;; vxworks-simlinux | vxworks-simwindows | vxworks-spe) ;; nto-qnx*) ;; os2-emx) ;; *-eabi* | *-gnueabi*) ;; -*) # Blank kernel with real OS is always fine. ;; *-*) echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: stimfit-0.16.7/INSTALL0000644000175000017500000003662614764352410010021 Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same timestamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. stimfit-0.16.7/depcomp0000755000175000017500000005602014764352410010333 #! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: stimfit-0.16.7/ltmain.sh0000755000175000017500000121237514764352406010616 #! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2019-02-19.15 # libtool (GNU libtool) 2.4.7 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # 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 this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.7 Debian-2.4.7-7build1" package_revision=2.4.7 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2004-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! 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 # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # These NLS vars are set unconditionally (bootstrap issue #24). Unset those # in case the environment reset is needed later and the $save_* variant is not # defined (see the code above). LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! 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 # func_unset VAR # -------------- # Portably unset VAR. # In some shells, an 'unset VAR' statement leaves a non-zero return # status if VAR is already unset, which might be problematic if the # statement is used at the end of a function (thus poisoning its return # value) or when 'set -e' is active (causing even a spurious abort of # the script in this case). func_unset () { { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } } # Make sure CDPATH doesn't cause `cd` commands to output the target dir. func_unset CDPATH # Make sure ${,E,F}GREP behave sanely. func_unset GREP_OPTIONS ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" # require_check_ifs_backslash # --------------------------- # Check if we can use backslash as IFS='\' separator, and set # $check_ifs_backshlash_broken to ':' or 'false'. require_check_ifs_backslash=func_require_check_ifs_backslash func_require_check_ifs_backslash () { _G_save_IFS=$IFS IFS='\' _G_check_ifs_backshlash='a\\b' for _G_i in $_G_check_ifs_backshlash do case $_G_i in a) check_ifs_backshlash_broken=false ;; '') break ;; *) check_ifs_backshlash_broken=: break ;; esac done IFS=$_G_save_IFS require_check_ifs_backslash=: } ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. if test -z "$_G_HAVE_PLUSEQ_OP" && \ __PLUSEQ_TEST="a" && \ __PLUSEQ_TEST+=" b" 2>/dev/null && \ test "a b" = "$__PLUSEQ_TEST"; then _G_HAVE_PLUSEQ_OP=yes fi if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd func_quote_arg pretty "$2" eval "$1=\$$1\\ \$func_quote_arg_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # 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" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_portable EVAL ARG # ---------------------------- # Internal function to portably implement func_quote_arg. Note that we still # keep attention to performance here so we as much as possible try to avoid # calling sed binary (so far O(N) complexity as long as func_append is O(1)). func_quote_portable () { $debug_cmd $require_check_ifs_backslash func_quote_portable_result=$2 # one-time-loop (easy break) while true do if $1; then func_quote_portable_result=`$ECHO "$2" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` break fi # Quote for eval. case $func_quote_portable_result in *[\\\`\"\$]*) # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string # contains the shell wildcard characters. case $check_ifs_backshlash_broken$func_quote_portable_result in :*|*[\[\*\?]*) func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ | $SED "$sed_quote_subst"` break ;; esac func_quote_portable_old_IFS=$IFS for _G_char in '\' '`' '"' '$' do # STATE($1) PREV($2) SEPARATOR($3) set start "" "" func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy IFS=$_G_char for _G_part in $func_quote_portable_result do case $1 in quote) func_append func_quote_portable_result "$3$2" set quote "$_G_part" "\\$_G_char" ;; start) set first "" "" func_quote_portable_result= ;; first) set quote "$_G_part" "" ;; esac done done IFS=$func_quote_portable_old_IFS ;; *) ;; esac break done func_quote_portable_unquoted_result=$func_quote_portable_result case $func_quote_portable_result in # double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # many bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_portable_result=\"$func_quote_portable_result\" ;; esac } # func_quotefast_eval ARG # ----------------------- # Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', # but optimized for speed. Result is stored in $func_quotefast_eval. if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then printf -v _GL_test_printf_tilde %q '~' if test '\~' = "$_GL_test_printf_tilde"; then func_quotefast_eval () { printf -v func_quotefast_eval_result %q "$1" } else # Broken older Bash implementations. Make those faster too if possible. func_quotefast_eval () { case $1 in '~'*) func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result ;; *) printf -v func_quotefast_eval_result %q "$1" ;; esac } fi else func_quotefast_eval () { func_quote_portable false "$1" func_quotefast_eval_result=$func_quote_portable_result } fi # func_quote_arg MODEs ARG # ------------------------ # Quote one ARG to be evaled later. MODEs argument may contain zero or more # specifiers listed below separated by ',' character. This function returns two # values: # i) func_quote_arg_result # double-quoted (when needed), suitable for a subsequent eval # ii) func_quote_arg_unquoted_result # has all characters that are still active within double # quotes backslashified. Available only if 'unquoted' is specified. # # Available modes: # ---------------- # 'eval' (default) # - escape shell special characters # 'expand' # - the same as 'eval'; but do not quote variable references # 'pretty' # - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might # be used later in func_quote to get output like: 'echo "a b"' instead # of 'echo a\ b'. This is slower than default on some shells. # 'unquoted' # - produce also $func_quote_arg_unquoted_result which does not contain # wrapping double-quotes. # # Examples for 'func_quote_arg pretty,unquoted string': # # string | *_result | *_unquoted_result # ------------+-----------------------+------------------- # " | \" | \" # a b | "a b" | a b # "a b" | "\"a b\"" | \"a b\" # * | "*" | * # z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" # # Examples for 'func_quote_arg pretty,unquoted,expand string': # # string | *_result | *_unquoted_result # --------------+---------------------+-------------------- # z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" func_quote_arg () { _G_quote_expand=false case ,$1, in *,expand,*) _G_quote_expand=: ;; esac case ,$1, in *,pretty,*|*,expand,*|*,unquoted,*) func_quote_portable $_G_quote_expand "$2" func_quote_arg_result=$func_quote_portable_result func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result ;; *) # Faster quote-for-eval for some shells. func_quotefast_eval "$2" func_quote_arg_result=$func_quotefast_eval_result ;; esac } # func_quote MODEs ARGs... # ------------------------ # Quote all ARGs to be evaled later and join them into single command. See # func_quote_arg's description for more info. func_quote () { $debug_cmd _G_func_quote_mode=$1 ; shift func_quote_result= while test 0 -lt $#; do func_quote_arg "$_G_func_quote_mode" "$1" if test -n "$func_quote_result"; then func_append func_quote_result " $func_quote_arg_result" else func_append func_quote_result "$func_quote_arg_result" fi shift done } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # 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). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_arg pretty,expand "$_G_cmd" eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_arg expand,pretty "$_G_cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Copyright (C) 2010-2019, 2021 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 2 or later # . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. # Please report bugs or propose patches to: # # Set a version string for this script. scriptversion=2019-02-19.15; # UTC ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # in the main code. A hook is just a list of function names that can be # run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of hook functions to be called by # FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_propagate_result FUNC_NAME_A FUNC_NAME_B # --------------------------------------------- # If the *_result variable of FUNC_NAME_A _is set_, assign its value to # *_result variable of FUNC_NAME_B. func_propagate_result () { $debug_cmd func_propagate_result_result=: if eval "test \"\${${1}_result+set}\" = set" then eval "${2}_result=\$${1}_result" else func_propagate_result_result=false fi } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd _G_rc_run_hooks=false case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do func_unset "${_G_hook}_result" eval $_G_hook '${1+"$@"}' func_propagate_result $_G_hook func_run_hooks if $func_propagate_result_result; then eval set dummy "$func_run_hooks_result"; shift fi done } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list from your hook function. You may remove # or edit any options that you action, and then pass back the remaining # unprocessed options in '_result', escaped # suitably for 'eval'. # # The '_result' variable is automatically unset # before your hook gets called; for best performance, only set the # *_result variable when necessary (i.e. don't call the 'func_quote' # function unnecessarily because it can be an expensive operation on some # machines). # # Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # No change in '$@' (ignored completely by this hook). Leave # # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # args_changed=false # # # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: # args_changed=: # ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # args_changed=: # ;; # *) # Make sure the first unrecognised option "$_G_opt" # # is added back to "$@" in case we need it later, # # if $args_changed was set to 'true'. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # # # Only call 'func_quote' here if we processed at least one argument. # if $args_changed; then # func_quote eval ${1+"$@"} # my_silent_option_result=$func_quote_result # fi # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # } # func_add_hook func_validate_options my_option_validation # # You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options_finish [ARG]... # ---------------------------- # Finishing the option parse loop (call 'func_options' hooks ATM). func_options_finish () { $debug_cmd func_run_hooks func_options ${1+"$@"} func_propagate_result func_run_hooks func_options_finish } # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd _G_options_quoted=false for my_func in options_prep parse_options validate_options options_finish do func_unset func_${my_func}_result func_unset func_run_hooks_result eval func_$my_func '${1+"$@"}' func_propagate_result func_$my_func func_options if $func_propagate_result_result; then eval set dummy "$func_options_result"; shift _G_options_quoted=: fi done $_G_options_quoted || { # As we (func_options) are top-level options-parser function and # nobody quoted "$@" for us yet, we need to do it explicitly for # caller. func_quote eval ${1+"$@"} func_options_result=$func_quote_result } } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propagate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} func_propagate_result func_run_hooks func_options_prep } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} func_propagate_result func_run_hooks func_parse_options if $func_propagate_result_result; then eval set dummy "$func_parse_options_result"; shift # Even though we may have changed "$@", we passed the "$@" array # down into the hook and it quoted it for us (because we are in # this if-branch). No need to quote it again. _G_parse_options_requote=false fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break # We expect that one of the options parsed in this function matches # and thus we remove _G_opt from "$@" and need to re-quote. _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" >&2 $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) if test $# = 0 && func_missing_arg $_G_opt; then _G_parse_options_requote=: break fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false break ;; esac if $_G_match_parse_options; then _G_parse_options_requote=: fi done if $_G_parse_options_requote; then # save modified positional parameters for caller func_quote eval ${1+"$@"} func_parse_options_result=$func_quote_result fi } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables # after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} if test "x$func_split_equals_lhs" = "x$1"; then func_split_equals_rhs= fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. # The version message is extracted from the calling file's header # comments, with leading '# ' stripped: # 1. First display the progname and version # 2. Followed by the header comment line matching /^# Written by / # 3. Then a blank line followed by the first following line matching # /^# Copyright / # 4. Immediately followed by any lines between the previous matches, # except lines preceding the intervening completely blank line. # For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /^# Written by /!b s|^# ||; p; n :fwd2blnk /./ { n b fwd2blnk } p; n :holdwrnt s|^# || s|^# *$|| /^Copyright /!{ /./H n b holdwrnt } s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| G s|\(\n\)\n*|\1|g p; q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.7' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.7-7build1 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= _G_rc_lt_options_prep=: _G_rc_lt_options_prep=: # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; *) _G_rc_lt_options_prep=false ;; esac if $_G_rc_lt_options_prep; then # Pass back the list of options. func_quote eval ${1+"$@"} libtool_options_prep_result=$func_quote_result fi } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd _G_rc_lt_parse_options=false # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"} ; shift _G_match_lt_parse_options=false break ;; esac $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done if $_G_rc_lt_parse_options; then # save modified positional parameters for caller func_quote eval ${1+"$@"} libtool_parse_options_result=$func_quote_result fi } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote eval ${1+"$@"} libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_arg pretty "$libobj" test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_arg pretty "$srcfile" qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wa,FLAG -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_arg pretty "$nonopt" install_prog="$func_quote_arg_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_arg pretty "$arg" func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_arg pretty "$arg" func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then func_quote_arg pretty "$arg2" fi func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_arg pretty "$install_override_mode" func_append install_shared_prog " -m $func_quote_arg_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_arg expand,pretty "$relink_command" eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs 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 BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # 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 relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" func_quote_arg pretty "$ECHO" qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_arg pretty,unquoted "$arg" qarg=$func_quote_arg_unquoted_result func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xassembler) func_append compiler_flags " -Xassembler $qarg" prev= func_append compile_command " -Xassembler $qarg" func_append finalize_command " -Xassembler $qarg" continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. -pthread) case $host in *solaris2*) ;; *) case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac ;; esac continue ;; -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_arg pretty "$flag" func_append arg " $func_quote_arg_result" func_append compiler_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_arg pretty "$flag" func_append arg " $wl$func_quote_arg_result" func_append compiler_flags " $wl$func_quote_arg_result" func_append linker_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xassembler) prev=xassembler continue ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer # -fuse-ld=* Linker select flags for GCC # -static-* direct GCC to link specific libraries statically # -fcilkplus Cilk Plus language extension features for C/C++ # -Wa,* Pass flags directly to the assembler -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus|-Wa,*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_arg pretty "$arg" arg=$func_quote_arg_result fi ;; # Some other compiler flag. -* | +*) func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_arg pretty "$arg" arg=$func_quote_arg_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf | midnightbsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_arg expand,pretty "$cmd" eval "func_echo $func_quote_arg_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_arg pretty "$var_value" relink_command="$var=$func_quote_arg_result; export $var; $relink_command" fi done func_quote eval cd "`pwd`" func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)" relink_command=$func_quote_arg_unquoted_result fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_arg pretty,unquoted "$var_value" relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command" fi done # Quote the link command for shipping. func_quote eval cd "`pwd`" relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" func_quote_arg pretty,unquoted "$relink_command" relink_command=$func_quote_arg_unquoted_result if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: stimfit-0.16.7/compile0000755000175000017500000001635014764352410010336 #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: stimfit-0.16.7/Makefile.static0000664000175000017500000002103014764352426011706 ######################################################################## # Makefile for static compilation Stimfit # no automake, or libtool, are needed. # # No global installation (sudo make install) is needed, but # stimfit can be started immediately after compilation. # # This is most useful for debugging, when several instances of stimfit # should be available. # # Usage: # cd ~/src/stimfit/ # change into stimfit's root directory # ./autogen.sh # ./configure --with-biosig --disable-python --with-pslope # make -f Makefile.static # build stimfit(-lite) i.e. w/o python support # make -f Makefile.static install # install stimfit into bindir # # WXCONF=/usr/bin/wx-config make -f Makefile.static # # build built with non-default WX # # PREFIX=/usr/local make -f Makefile.static # # ./stimfit # start stimfit # # win32 built # CROSS=i686-pc-mingw32- make -f Makefile.static # WXCONF=i686-pc-mingw32-wx-config make -f Makefile.static # win64 built # CROSS=x86_64-static-mingw32- make -f Makefile.static # WXCONF=x86_64-static-mingw32-wx-config make -f Makefile.static # # The use of WXCONF is deprecated, and might be removed in future # Limitations: # - PYTHON shell, matplotlib (print) are not supported # # Copyright (C) 2012,2013,2014,2015,2021,2025 Alois Schloegl # This is part of the stimfit project http://stimfit.org # ######################################################################## ifeq (,$(WXCONF)) # default wx-config WXCONF = $(CROSS)wx-config else ifneq (,$(findstring mingw,$(WXCONF))) # for backwords compatibility to older MXE scripts CROSS = $(subst wx-config,,$(WXCONF)) endif endif DEFINES += -DWITH_BIOSIG DEFINES += -DWITH_PSLOPE #DEFINES += -DTEST_MINIMAL #DEFINES += -DPYTHON -DWITH_PYTHON WXVERSION = $(basename $(shell $(WXCONF) --version)) PY_VERSION := $(shell py3versions -i | sed 's/python//g') ############################################################## ### SOURCES ############################################################## vpath %.cpp ./src/stimfit:./src/stimfit/gui:./src/stimfit/gui/dlgs:./src/stimfit/gui/usrdlg:./src/libstfnum:./src/libstfio/:./src/libstfio/cfs/:./src/libstfio/atf/:./src/libstfio/abf/:./src/libstfio/abf/axon2:./src/libstfio/abf/axon/Common:./src/libstfio/abf/axon/AxAbfFio32:./src/libstfio/abf/axon/AxAtfFio32/:./src/libstfio/biosig/:./src/libstfio/hdf5/:./src/libstfio/heka/:./src/libstfio/igor:./src/libstfio/ascii/:./src/libstfio/axg/ vpath %.c ./src/libstfnum/levmar/:./src/libstfio/igor/:./src/libstfio/cfs/ vpath %.cpp ./src/libstfnum/:./src/libstfnum/levmar/:./src/stimfit/gui/:./src/stimfit/gui/dlgs/:./src/libstfio/:./src/libstfio/biosig/:./src/libstfio/igor/:./src/libstfio/cfs/ SOURCES = ./src/stimfit/stf.cpp \ ./src/libstfnum/stfnum.cpp \ ./src/libstfnum/funclib.cpp \ ./src/libstfnum/measure.cpp \ ./src/libstfnum/fit.cpp \ ./src/libstfnum/levmar/lm.c \ ./src/libstfnum/levmar/Axb.c \ ./src/libstfnum/levmar/misc.c \ ./src/libstfnum/levmar/lmbc.c \ ./src/libstfnum/levmar/lmlec.c \ ./src/stimfit/gui/doc.cpp \ ./src/stimfit/gui/zoom.cpp \ ./src/stimfit/gui/childframe.cpp \ ./src/stimfit/gui/app.cpp \ ./src/stimfit/gui/parentframe.cpp \ ./src/stimfit/gui/dlgs/convertdlg.cpp \ ./src/stimfit/gui/dlgs/cursorsdlg.cpp \ ./src/stimfit/gui/dlgs/eventdlg.cpp \ ./src/stimfit/gui/dlgs/smalldlgs.cpp \ ./src/stimfit/gui/dlgs/fitseldlg.cpp \ ./src/stimfit/gui/copygrid.cpp \ ./src/stimfit/gui/usrdlg/usrdlg.cpp \ ./src/stimfit/gui/graph.cpp \ ./src/stimfit/gui/unopt.cpp \ ./src/stimfit/gui/view.cpp \ ./src/stimfit/gui/table.cpp \ ./src/stimfit/gui/printout.cpp \ ./src/stimfit/gui/main.cpp \ ./src/libstfio/igor/igorlib.cpp \ ./src/libstfio/cfs/cfslib.cpp \ ./src/libstfio/section.cpp \ ./src/libstfio/recording.cpp \ ./src/libstfio/hdf5/hdf5lib.cpp \ ./src/libstfio/intan/intanlib.cpp \ ./src/libstfio/intan/common.cpp \ ./src/libstfio/intan/streams.cpp \ ./src/libstfio/channel.cpp \ ./src/libstfio/stfio.cpp \ ./src/libstfio/igor/WriteWave.c \ ./src/libstfio/igor/CrossPlatformFileIO.c \ ./src/libstfio/biosig/biosiglib.cpp \ ./src/libstfio/cfs/cfs.c SOURCES_OPTIONAL = \ ./src/libstfio/heka/hekalib.cpp \ SOURCES_ABF = ./src/libstfio/atf/atflib.cpp \ ./src/libstfio/abf/abflib.cpp \ ./src/libstfio/abf/axon2/ProtocolReaderABF2.cpp \ ./src/libstfio/abf/axon2/abf2headr.cpp \ ./src/libstfio/abf/axon2/SimpleStringCache.cpp \ ./src/libstfio/abf/axon/Common/FileReadCache.cpp \ ./src/libstfio/abf/axon/Common/unix.cpp \ ./src/libstfio/abf/axon/Common/FileIO.cpp \ ./src/libstfio/abf/axon/AxAtfFio32/axatffio32.cpp \ ./src/libstfio/abf/axon/AxAtfFio32/fileio2.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abferror.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfheadr.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/filedesc.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/msbincvt.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfutil.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abffiles.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/Oldheadr.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/abfhwave.cpp \ ./src/libstfio/abf/axon/AxAbfFio32/csynch.cpp EXCLUDED = ./src/libstfio/ascii/asciilib.cpp \ ./src/libstfio/abf/axon/AxAtfFio32/fileio2.cpp \ ./src/libstfnum/levmar/lmbc_core.c \ ./src/libstfnum/levmar/lmlec_core.c \ ./src/libstfnum/levmar/misc_core.c \ ./src/libstfnum/levmar/lm_core.c \ ./src/libstfnum/levmar/Axb_core.c \ ./src/stimfit/gui/dclatex.cpp \ TESTSRC = ./src/test/section.cpp \ ./src/test/recording.cpp \ ./src/test/measure.cpp \ ./src/test/channel.cpp \ ./src/test/gtest/src/gtest.cc \ ./src/test/gtest/src/gtest-port.cc \ ./src/test/gtest/src/gtest-test-part.cc \ ./src/test/gtest/src/gtest-typed-test.cc \ ./src/test/gtest/src/gtest.cc \ ./src/test/gtest/src/gtest-printers.cc \ ./src/test/gtest/src/gtest-death-test.cc \ ./src/test/gtest/src/gtest-all.cc \ ./src/test/gtest/src/gtest_main.cc \ ./src/test/gtest/src/gtest-filepath.cc SOURCES_AXG = ./src/libstfio/axg/axglib.cpp \ ./src/libstfio/axg/AxoGraph_ReadWrite.cpp \ ./src/libstfio/axg/fileUtils.cpp \ ./src/libstfio/axg/stringUtils.cpp \ ./src/libstfio/axg/byteswap.cpp \ # needed because of exportATF SOURCES += $(SOURCES_ABF) SOURCES += $(SOURCES_AXG) ifeq (,$(findstring mingw, $(WXCONF))) TARGET = stimfit OBJEXT = o else ### MINGW ### TARGET = stimfit.exe OBJEXT = obj endif ifeq (,$(findstring TEST_MINIMAL, $(DEFINES))) SOURCES += $(SOURCES_OPTIONAL) endif ifneq (,$(findstring WITH_PYTHON, $(DEFINES))) SOURCES += $(SOURCES_PYSTFIO) CFLAGS += $(shell python$(PY_VERSION)-config --cflags) DEFINES += -I$(shell python$(PY_VERSION)-config --prefix)/lib/pymodules/python$(PY_VERSION)/numpy/core/include LDFLAGS += $(shell python$(PY_VERSION)-config --ldflags) LIBS += $(shell python$(PY_VERSION)-config --libs) endif CC ?= $(shell $(WXCONF) --cc) CXX ?= $(shell $(WXCONF) --cxx) LD = $(shell $(WXCONF) --ld) CFLAGS += $(DEFINES) $(shell $(WXCONF) --cflags) -fstack-protector -O2 -I./ CPPFLAGS += $(DEFINES) $(shell $(WXCONF) --cppflags) -std=c++17 -fstack-protector -O2 -I./ LIBS += $(shell $(WXCONF) --libs net,adv,aui,core,base) SWIG = /usr/bin/swig -c++ SWIG_PYTHON_OPT = -python prefix ?= $(PREFIX) exec_prefix = ${prefix} datarootdir = ${prefix}/share datadir = ${datarootdir} libdir = ${exec_prefix}/lib includedir = ${prefix}/include bindir = ${exec_prefix}/bin mandir = ${datarootdir}/man PKGCONF ?= $(CROSS)pkg-config HDF5_CFLAGS = -I/usr/include/hdf5/serial CPPFLAGS += $(HDF5_CFLAGS) LIBHDF5_LDFLAGS = -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5 -lhdf5_hl LIBS += $(LIBHDF5_LDFLAGS) LIBLAPACK_LDFLAGS = -llapack -lblas LIBS += $(LIBLAPACK_LDFLAGS) CXXFLAGS += $(CFLAGS) $(CPPFLAGS) ## BIOSIG related stuff ## LIBS += $(shell $(PKGCONF) --libs libbiosig) LIBS += -lfftw3 ifeq (mingw,$(findstring mingw, $(WXCONF))) LIBS += -lgfortran -lquadmath endif PYTHON_DEST_DIR = ${prefix}${PYTHON_TARGET_DIR} ############################################################## ### BUILT ############################################################## OBJECTS = $(addsuffix .$(OBJEXT), $(basename $(SOURCES))) $(TARGET): $(OBJECTS) $(LD) "$@" $(OBJECTS) $(LDFLAGS) $(LIBS) %.c: %.h %.cpp: %.h %.$(OBJEXT): %.c $(CC) -o "$@" $(CFLAGS) -c "$<" %.$(OBJEXT): %.cc $(CC) -o "$@" $(CFLAGS) -c "$<" %.$(OBJEXT): %.cpp $(CXX) -o "$@" $(CPPFLAGS) -c "$<" %.$(OBJEXT): %.cxx $(CXX) -o "$@" $(CXXFLAGS) -c "$<" clean: find src -name "*.$(OBJEXT)" -exec rm {} \; rm -f stimfit install: $(TARGET) install $(TARGET) $(bindir) uninstall: rm $(bindir)/stimfit stimfit-0.16.7/test-driver0000755000175000017500000001141714764352410011155 #! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <"$log_file" "$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: stimfit-0.16.7/aclocal.m40000664000175000017500000015367114764352407010640 # generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 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.71],, [m4_warning([this file was generated for autoconf 2.71. 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'.])]) # pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurrence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------ dnl dnl Prepare a "--with-" configure option using the lowercase dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and dnl PKG_CHECK_MODULES in a single macro. AC_DEFUN([PKG_WITH_MODULES], [ m4_pushdef([with_arg], m4_tolower([$1])) m4_pushdef([description], [m4_default([$5], [build with ]with_arg[ support])]) m4_pushdef([def_arg], [m4_default([$6], [auto])]) m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) m4_case(def_arg, [yes],[m4_pushdef([with_without], [--without-]with_arg)], [m4_pushdef([with_without],[--with-]with_arg)]) AC_ARG_WITH(with_arg, AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, [AS_TR_SH([with_]with_arg)=def_arg]) AS_CASE([$AS_TR_SH([with_]with_arg)], [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], [auto],[PKG_CHECK_MODULES([$1],[$2], [m4_n([def_action_if_found]) $3], [m4_n([def_action_if_not_found]) $4])]) m4_popdef([with_arg]) m4_popdef([description]) m4_popdef([def_arg]) ])dnl PKG_WITH_MODULES dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ----------------------------------------------- dnl dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES dnl check._[VARIABLE-PREFIX] is exported as make variable. AC_DEFUN([PKG_HAVE_WITH_MODULES], [ PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) AM_CONDITIONAL([HAVE_][$1], [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) ])dnl PKG_HAVE_WITH_MODULES dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------------------ dnl dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make dnl and preprocessor variable. AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], [ PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ])dnl PKG_HAVE_DEFINE_WITH_MODULES # Copyright (C) 2002-2021 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.16' 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.16.5], [], [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.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2021 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-2021 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-2021 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-2021 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. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _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. # This creates each '.Po' and '.Plo' makefile fragment that we'll 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" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2021 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 m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])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_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([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 ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) 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-2021 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])]) # Copyright (C) 2003-2021 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. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [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 AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2021 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 whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2021 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 MISSING="\${SHELL} '$am_aux_dir/missing'" 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-2021 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-2021 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-2021 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-2021 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-2021 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-2021 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-2021 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-2021 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([m4/acsite.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) stimfit-0.16.7/NEWS0000664000175000017500000000000014750344764007452